Class: Sepa::DanskeResponse
- Defined in:
- lib/sepa/banks/danske/danske_response.rb
Overview
Handles Danske Bank specific Response functionality. Mainly decryption and certificate specific stuff.
Constant Summary collapse
- CERTIFICATE_COMMANDS =
[:get_bank_certificate, :create_certificate, :renew_certificate].freeze
Constants included from ErrorMessages
ErrorMessages::CONTENT_ERROR_MESSAGE, ErrorMessages::CUSTOMER_ID_ERROR_MESSAGE, ErrorMessages::DECRYPTION_ERROR_MESSAGE, ErrorMessages::ENCRYPTION_CERT_ERROR_MESSAGE, ErrorMessages::ENCRYPTION_CERT_REQUEST_ERROR_MESSAGE, ErrorMessages::ENCRYPTION_PRIVATE_KEY_ERROR_MESSAGE, ErrorMessages::ENVIRONMENT_ERROR_MESSAGE, ErrorMessages::FILE_REFERENCE_ERROR_MESSAGE, ErrorMessages::FILE_TYPE_ERROR_MESSAGE, ErrorMessages::HASH_ERROR_MESSAGE, ErrorMessages::NOT_OK_RESPONSE_CODE_ERROR_MESSAGE, ErrorMessages::PIN_ERROR_MESSAGE, ErrorMessages::SIGNATURE_ERROR_MESSAGE, ErrorMessages::SIGNING_CERT_REQUEST_ERROR_MESSAGE, ErrorMessages::STATUS_ERROR_MESSAGE, ErrorMessages::TARGET_ID_ERROR_MESSAGE
Instance Attribute Summary
Attributes inherited from Response
#command, #environment, #error, #soap
Instance Method Summary collapse
- #application_response ⇒ String
-
#bank_encryption_certificate ⇒ OpenSSL::X509::Certificate?
Returns the bank's encryption certificate which is used to encrypt messages sent to the bank.
-
#bank_root_certificate ⇒ OpenSSL::X509::Certificate?
Returns the bank's root certificate which is the certificate that is used to sign bank's other certificates.
-
#bank_signing_certificate ⇒ OpenSSL::X509::Certificate?
Returns the bank's signing certificate which is used by the bank to sign the responses.
-
#ca_certificate ⇒ OpenSSL::X509::Certificate?
Returns the CA certificate that has been used to sign own signing and encryption certificates.
-
#can_be_decrypted_with_given_key ⇒ Object
private
Validates that the encrypted key in the response can be decrypted with the private key given to the response in the parameters.
-
#certificate ⇒ OpenSSL::X509::Certificate
Extract certificate that has been used to sign the response.
-
#certificate_is_trusted? ⇒ true, false
Checks whether certificate embedded in the response has been signed with the bank's root certificate.
-
#decrypt_application_response ⇒ String
private
Decrypts the application response in the response.
-
#decrypt_embedded_key ⇒ String?
private
Decrypts (assymetrically) the symmetric encryption key embedded in the response with the private key given to the response in the parameters.
-
#encrypted_application_response ⇒ Nokogiri::XML?
private
Extracts the encrypted application response from the response and returns it as a nokogiri document.
-
#find_node_by_uri(uri) ⇒ Nokogiri::XML::Node
private
Finds a node by its reference URI from Danske Bank's certificate responses.
-
#own_encryption_certificate ⇒ OpenSSL::X509::Certificate?
Returns own encryption certificate which has been signed by the bank.
-
#own_signing_certificate ⇒ OpenSSL::X509::Certificate?
Returns own signing certificate which has been signed by the bank.
- #response_code ⇒ Object
- #response_text ⇒ Object
-
#valid_get_bank_certificate_response ⇒ Object
private
Validates get bank certificate response.
Methods inherited from Response
#client_errors, #content, #doc, #document_must_validate_against_schema, #error_doc, #extract_application_response, #file_references, #find_digest_values, #find_nodes_to_verify, #hashes_match?, #initialize, #response_code_is_ok?, #signature_is_valid?, #to_s, #validate_hashes, #validate_response_code, #verify_certificate, #verify_signature
Methods included from Utilities
#calculate_digest, #canonicalize_exclusively, #canonicalized_node, #cert_request_valid?, #check_validity_against_schema, #csr_to_binary, #decode, #encode, #extract_cert, #format_cert, #format_cert_request, #hmac, #iso_time, #load_body_template, #process_cert_value, #rsa_key, #set_node_id, #validate_signature, #verify_certificate_against_root_certificate, #x509_certificate, #xml_doc
Constructor Details
This class inherits a constructor from Sepa::Response
Instance Method Details
#application_response ⇒ String
12 13 14 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 12 def application_response @application_response ||= decrypt_application_response end |
#bank_encryption_certificate ⇒ OpenSSL::X509::Certificate?
Returns the bank's encryption certificate which is used to encrypt messages sent to the bank.
The certificate is only present in :get_bank_certificate
responess.
21 22 23 24 25 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 21 def bank_encryption_certificate return unless @command == :get_bank_certificate @bank_encryption_certificate ||= extract_cert(doc, 'BankEncryptionCert', DANSKE_PKI) end |
#bank_root_certificate ⇒ OpenSSL::X509::Certificate?
Returns the bank's root certificate which is the certificate that is used to sign bank's other
certificates. Only present in :get_bank_certificate
responses.
43 44 45 46 47 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 43 def bank_root_certificate return unless @command == :get_bank_certificate @bank_root_certificate ||= extract_cert(doc, 'BankRootCert', DANSKE_PKI) end |
#bank_signing_certificate ⇒ OpenSSL::X509::Certificate?
Returns the bank's signing certificate which is used by the bank to sign the responses. The
certificate is only present in :get_bank_certificate
responses
32 33 34 35 36 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 32 def bank_signing_certificate return unless @command == :get_bank_certificate @bank_signing_certificate ||= extract_cert(doc, 'BankSigningCert', DANSKE_PKI) end |
#ca_certificate ⇒ OpenSSL::X509::Certificate?
Returns the CA certificate that has been used to sign own signing and encryption certificates.
Only present in :create_certificate
& :renew_certificate
responses
76 77 78 79 80 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 76 def ca_certificate return unless [:create_certificate, :renew_certificate].include?(@command) @ca_certificate ||= extract_cert(doc, 'CACert', DANSKE_PKI) end |
#can_be_decrypted_with_given_key ⇒ Object (private)
Validates that the encrypted key in the response can be decrypted with the private key given to the response in the parameters. Response is invalid if this cannot be done.
189 190 191 192 193 194 195 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 189 def can_be_decrypted_with_given_key return if CERTIFICATE_COMMANDS.include? @command return unless encrypted_application_response.css('CipherValue', 'xmlns' => XMLENC)[0] return if errors.add(:encryption_private_key, DECRYPTION_ERROR_MESSAGE) end |
#certificate ⇒ OpenSSL::X509::Certificate
Extract certificate that has been used to sign the response. This overrides
Response#certificate method with specific functionality for :get_bank_certificate
,
:create_certificate
& :renew_certificate
commands. Otherwise just calls Response#certificate
88 89 90 91 92 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 88 def certificate return super unless CERTIFICATE_COMMANDS.include? @command @certificate ||= extract_cert(doc, 'X509Certificate', DSIG) end |
#certificate_is_trusted? ⇒ true, false
Checks whether certificate embedded in the response has been signed with the bank's root
certificate. Always returns true when Response#command is :get_bank_certificate
, because the
certificate is not present with that command.
114 115 116 117 118 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 114 def certificate_is_trusted? return true if @command == :get_bank_certificate verify_certificate_against_root_certificate(certificate, DANSKE_ROOT_CERTIFICATE) end |
#decrypt_application_response ⇒ String (private)
Decrypts the application response in the response. Starts by calling #decrypt_embedded_key method to get the key used in encrypting the application response. After this the encrypted data is retrieved from the document and base64 decoded. After this the iv (initialization vector) is extracted from the encrypted data and a decipher with the 'DES-EDE3-CBC' algorithm is initialized (This is used by banks as encryption algorithm) and its key and iv set accordingly and mode changes to decrypt. After this the data is decrypted and returned as string.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 147 def decrypt_application_response key = encypted_data = encrypted_application_response .css('CipherValue', 'xmlns' => XMLENC)[1] .content encypted_data = decode encypted_data iv = encypted_data[0, 8] encypted_data = encypted_data[8, encypted_data.length] decipher = OpenSSL::Cipher.new('DES-EDE3-CBC') decipher.decrypt decipher.key = key decipher.iv = iv decipher.update(encypted_data) + decipher.final end |
#decrypt_embedded_key ⇒ String? (private)
Decrypts (assymetrically) the symmetric encryption key embedded in the response with the private key given to the response in the parameters. The key is later used to decrypt the application response.
203 204 205 206 207 208 209 210 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 203 def enc_key = encrypted_application_response.css('CipherValue', 'xmlns' => XMLENC)[0].content enc_key = decode enc_key @encryption_private_key.private_decrypt(enc_key) rescue OpenSSL::PKey::RSAError nil end |
#encrypted_application_response ⇒ Nokogiri::XML? (private)
Extracts the encrypted application response from the response and returns it as a nokogiri document
180 181 182 183 184 185 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 180 def encrypted_application_response @encrypted_application_response ||= begin encrypted_application_response = extract_application_response(BXD) xml_doc(encrypted_application_response) end end |
#find_node_by_uri(uri) ⇒ Nokogiri::XML::Node (private)
Finds a node by its reference URI from Danske Bank's certificate responses. If Response#command is
other than :get_bank_certificate
, :create_certificate
or :renew_certificate
returns super. This method is
needed because Danske Bank uses a different way to reference nodes in their certificate
responses.
130 131 132 133 134 135 136 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 130 def find_node_by_uri(uri) return super unless CERTIFICATE_COMMANDS.include? @command doc_without_signature = doc.dup doc_without_signature.at('xmlns|Signature', xmlns: DSIG).remove doc_without_signature.at("[xml|id='#{uri}']") end |
#own_encryption_certificate ⇒ OpenSSL::X509::Certificate?
Returns own encryption certificate which has been signed by the bank. Only present in
:create_certificate
& :renew_certificate
responses
54 55 56 57 58 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 54 def own_encryption_certificate return unless [:create_certificate, :renew_certificate].include?(@command) @own_encryption_certificate ||= extract_cert(doc, 'EncryptionCert', DANSKE_PKI) end |
#own_signing_certificate ⇒ OpenSSL::X509::Certificate?
Returns own signing certificate which has been signed by the bank. Is used to sign requests
sent to the bank. Is only present in :create_certificate
& :renew_certificate
responses.
65 66 67 68 69 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 65 def own_signing_certificate return unless [:create_certificate, :renew_certificate].include?(@command) @own_signing_certificate ||= extract_cert(doc, 'SigningCert', DANSKE_PKI) end |
#response_code ⇒ Object
95 96 97 98 99 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 95 def response_code return super unless CERTIFICATE_COMMANDS.include? @command super(namespace: DANSKE_PKI, node_name: 'ReturnCode') || super(namespace: DANSKE_PKIF, node_name: 'ReturnCode') end |
#response_text ⇒ Object
102 103 104 105 106 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 102 def response_text return super unless CERTIFICATE_COMMANDS.include? @command super(namespace: DANSKE_PKI, node_name: 'ReturnText') || super(namespace: DANSKE_PKIF, node_name: 'ReturnText') end |
#valid_get_bank_certificate_response ⇒ Object (private)
Validates get bank certificate response. Response is valid if service fault is not returned from the bank.
168 169 170 171 172 173 |
# File 'lib/sepa/banks/danske/danske_response.rb', line 168 def valid_get_bank_certificate_response return unless @command == :get_bank_certificate return unless doc.at('xmlns|PKIFactoryServiceFault', xmlns: DANSKE_PKIF) errors.add(:base, "Did not get a proper response when trying to get bank's certificates") end |