sepafm 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -30
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +15 -0
  5. data/Gemfile +1 -1
  6. data/LICENSE +16 -4
  7. data/README.md +180 -319
  8. data/Rakefile +7 -2
  9. data/lib/sepa/application_request.rb +100 -131
  10. data/lib/sepa/application_response.rb +28 -84
  11. data/lib/sepa/attribute_checks.rb +169 -0
  12. data/lib/sepa/banks/danske/danske_response.rb +19 -0
  13. data/lib/sepa/banks/danske/soap_danske.rb +132 -0
  14. data/lib/sepa/banks/nordea/nordea_response.rb +20 -0
  15. data/lib/sepa/banks/nordea/soap_nordea.rb +51 -0
  16. data/lib/sepa/client.rb +72 -60
  17. data/lib/sepa/error_messages.rb +15 -0
  18. data/lib/sepa/response.rb +88 -85
  19. data/lib/sepa/soap_builder.rb +51 -341
  20. data/lib/sepa/utilities.rb +132 -0
  21. data/lib/sepa/version.rb +1 -1
  22. data/lib/sepa/xml_schemas/PKIFactory.xsd +334 -0
  23. data/lib/sepa/xml_schemas/xml_id.xsd +9 -0
  24. data/lib/sepa/xml_templates/application_request/create_certificate.xml +15 -10
  25. data/lib/sepa/xml_templates/application_request/danske_get_bank_certificate.xml +13 -9
  26. data/lib/sepa/xml_templates/application_request/download_file.xml +32 -30
  27. data/lib/sepa/xml_templates/application_request/download_file_list.xml +29 -27
  28. data/lib/sepa/xml_templates/application_request/encrypted_request.xml +22 -0
  29. data/lib/sepa/xml_templates/application_request/get_certificate.xml +9 -8
  30. data/lib/sepa/xml_templates/application_request/get_user_info.xml +26 -24
  31. data/lib/sepa/xml_templates/application_request/upload_file.xml +29 -27
  32. data/lib/sepa/xml_templates/soap/create_certificate.xml +17 -15
  33. data/lib/sepa/xml_templates/soap/danske_get_bank_certificate.xml +15 -13
  34. data/lib/sepa/xml_templates/soap/download_file.xml +19 -15
  35. data/lib/sepa/xml_templates/soap/download_file_list.xml +19 -15
  36. data/lib/sepa/xml_templates/soap/get_certificate.xml +2 -1
  37. data/lib/sepa/xml_templates/soap/get_user_info.xml +19 -15
  38. data/lib/sepa/xml_templates/soap/header.xml +48 -37
  39. data/lib/sepa/xml_templates/soap/upload_file.xml +19 -15
  40. data/lib/sepafm.rb +20 -18
  41. data/{sepa.gemspec → sepafm.gemspec} +10 -9
  42. data/test/sepa/banks/danske/danske_cert_response_test.rb +52 -0
  43. data/test/sepa/banks/danske/danske_cert_soap_builder_test.rb +100 -0
  44. data/test/sepa/banks/danske/danske_generic_soap_builder_test.rb +278 -0
  45. data/test/sepa/banks/danske/danske_get_bank_cert_test.rb +111 -0
  46. data/{lib/sepa/danske_testing/keys/danske_encryption.crt → test/sepa/banks/danske/keys/bank_encryption_cert.pem} +0 -0
  47. data/test/sepa/{danske_test_keys/danskeroot.pem → banks/danske/keys/bank_root_cert.pem} +1 -1
  48. data/test/sepa/banks/danske/keys/bank_signing_cert.pem +24 -0
  49. data/test/sepa/banks/danske/keys/danske_encryption.crt +24 -0
  50. data/test/sepa/banks/danske/keys/enc_private_key.pem +27 -0
  51. data/test/sepa/{danske_test_keys → banks/danske/keys}/encryption_pkcs.csr +0 -0
  52. data/test/sepa/banks/danske/keys/own_enc_cert.pem +21 -0
  53. data/test/sepa/banks/danske/keys/own_signing_cert.pem +22 -0
  54. data/test/sepa/{danske_test_keys → banks/danske/keys}/signing_key.pem +0 -0
  55. data/test/sepa/{danske_test_keys → banks/danske/keys}/signing_pkcs.csr +0 -0
  56. data/test/sepa/banks/danske/keys/signing_private_key.pem +27 -0
  57. data/test/sepa/banks/danske/responses/create_cert.xml +38 -0
  58. data/test/sepa/banks/danske/responses/get_bank_cert.xml +37 -0
  59. data/{lib/sepa/nordea_testing → test/sepa/banks/nordea}/keys/nordea.crt +0 -4
  60. data/test/sepa/{nordea_test_keys → banks/nordea/keys}/nordea.key +0 -3
  61. data/test/sepa/{nordea_test_keys → banks/nordea/keys}/root_cert.cer +0 -0
  62. data/test/sepa/{nordea_test_keys → banks/nordea/keys}/testcert.csr +0 -0
  63. data/test/sepa/banks/nordea/nordea_application_request_test.rb +252 -0
  64. data/test/sepa/{application_response_test.rb → banks/nordea/nordea_application_response_test.rb} +40 -46
  65. data/test/sepa/banks/nordea/nordea_cert_application_request_test.rb +72 -0
  66. data/test/sepa/banks/nordea/nordea_cert_request_soap_builder_test.rb +65 -0
  67. data/test/sepa/banks/nordea/nordea_generic_soap_builder_test.rb +280 -0
  68. data/test/sepa/banks/nordea/nordea_response_test.rb +116 -0
  69. data/test/sepa/banks/nordea/responses/df_ktl.xml +45 -0
  70. data/test/sepa/{test_files/test_responses/df.xml → banks/nordea/responses/df_tito.xml} +1 -1
  71. data/test/sepa/{test_files/test_responses → banks/nordea/responses}/dfl.xml +0 -0
  72. data/test/sepa/banks/nordea/responses/gbc.xml +15 -0
  73. data/test/sepa/banks/nordea/responses/gc.xml +49 -0
  74. data/test/sepa/{test_files/test_responses → banks/nordea/responses}/gui.xml +0 -0
  75. data/test/sepa/{test_files/test_responses → banks/nordea/responses}/uf.xml +0 -0
  76. data/test/sepa/client_test.rb +156 -302
  77. data/test/sepa/fixtures.rb +214 -0
  78. data/test/sepa/sepa_test.rb +3 -13
  79. data/test/sepa/test_files/{invalid.wsdl → invalid_wsdl.wsdl} +0 -0
  80. data/test/test_helper.rb +29 -3
  81. metadata +140 -116
  82. data/lib/danske_get_bank_certificate_test.rb +0 -15
  83. data/lib/sepa/custom_exceptions.rb +0 -2
  84. data/lib/sepa/filedescriptor.rb +0 -7
  85. data/lib/sepa/filetypeservice.rb +0 -6
  86. data/lib/sepa/nordea_testing/keys/CSR.csr +0 -0
  87. data/lib/sepa/nordea_testing/keys/nordea.key +0 -19
  88. data/lib/sepa/nordea_testing/response/content_053.xml +0 -998
  89. data/lib/sepa/nordea_testing/response/content_054.xml +0 -1
  90. data/lib/sepa/nordea_testing/response/download_file_response.xml +0 -14
  91. data/lib/sepa/nordea_testing/response/download_filelist_response.xml +0 -14
  92. data/lib/sepa/nordea_testing/response/get_user_info_response.xml +0 -14
  93. data/lib/sepa/nordea_testing/response/upload_file_response.xml +0 -14
  94. data/lib/sepa/payload.rb +0 -109
  95. data/lib/sepa/payment.rb +0 -97
  96. data/lib/sepa/sender_verifier.rb +0 -15
  97. data/lib/sepa/signature.rb +0 -7
  98. data/lib/sepa/soap_danske.rb +0 -47
  99. data/lib/sepa/soap_nordea.rb +0 -68
  100. data/lib/sepa/transaction.rb +0 -178
  101. data/lib/sepa/userfiletype.rb +0 -16
  102. data/lib/sepa/xml_parser.rb +0 -291
  103. data/lib/sepa_client_testing_mika.rb +0 -32
  104. data/lib/sepa_client_testing_tiere.rb +0 -257
  105. data/test/sepa/application_request_test.rb +0 -423
  106. data/test/sepa/cert_application_request_test.rb +0 -99
  107. data/test/sepa/nordea_cert_request_soap_builder_test.rb +0 -112
  108. data/test/sepa/nordea_generic_soap_builder_test.rb +0 -427
  109. data/test/sepa/nordea_test_keys/nordea.crt +0 -27
  110. data/test/sepa/payload_test.rb +0 -297
  111. data/test/sepa/payment_test.rb +0 -198
  112. data/test/sepa/response_test.rb +0 -269
  113. data/test/sepa/transaction_test.rb +0 -362
  114. data/test/sepa/user_file_type_test.rb +0 -21
  115. data/test/sepa/xml_parser_test.rb +0 -73
@@ -1,182 +1,151 @@
1
1
  module Sepa
2
2
  class ApplicationRequest
3
- def initialize(params)
4
- # Used by most, both Nordea and Danske
5
- @command = check_command(params.fetch(:command))
6
- @customer_id = params.fetch(:customer_id)
7
- @environment = params.fetch(:environment)
8
- @target_id = params[:target_id]
9
- @status = params[:status]
10
- @file_type = params[:file_type]
11
- @content = params[:content]
12
- @file_reference = params[:file_reference]
13
-
14
- @private_key, @cert, @pin, @service, @csr, @hmac,
15
- @bank_root_cert_serial,@request_id = ''
16
-
17
- # Set values for the previously defined attributes
18
- initialize_required_fields_per_request(params)
3
+ include Utilities
4
+
5
+ def initialize(params = {})
6
+ # Set all params as instance variables
7
+ params.each do |key, value|
8
+ instance_variable_set("@#{key}", value)
9
+ end
10
+
11
+ @ar = load_body_template AR_TEMPLATE_PATH
19
12
  end
20
13
 
21
- def get_as_base64
22
- load_template(@command)
14
+ def to_xml
15
+ set_common_nodes
23
16
  set_nodes_contents
24
- # No signature for Certificate Requests
25
- if @command != :get_certificate && @command != :get_bank_certificate
26
- process_signature
27
- end
17
+ process_signature
18
+ @ar.to_xml
19
+ end
28
20
 
29
- Base64.encode64(@ar.to_xml)
21
+ def to_base64
22
+ Base64.encode64(to_xml)
30
23
  end
31
24
 
32
- private
25
+ def to_nokogiri
26
+ Nokogiri::XML to_xml
27
+ end
33
28
 
34
- def initialize_required_fields_per_request(params)
35
- generic_commands = [:get_user_info, :upload_file, :download_file,
36
- :download_file_list]
29
+ private
37
30
 
38
- case @command
39
- when *generic_commands
40
- @private_key = params.fetch(:private_key)
41
- @cert = params.fetch(:cert)
42
- when :get_certificate
43
- @service = params[:service]
44
- @pin = params[:pin]
45
- @csr = params[:csr]
46
- @hmac = create_hmac_seal(@pin,@csr)
47
- when :get_bank_certificate
48
- @pin = params[:pin]
49
- @request_id = params[:request_id]
50
- @bank_root_cert_serial = params[:bank_root_cert_serial]
51
- end
31
+ def set_node(node, value)
32
+ @ar.at_css(node).content = value
52
33
  end
53
34
 
54
- def check_command(command)
55
- valid_commands = [:get_certificate, :download_file_list, :download_file,
56
- :get_user_info, :upload_file, :download_file,
57
- :get_bank_certificate]
58
- unless valid_commands.include?(command)
59
- fail ArgumentError, "You didn't provide a proper command. " \
60
- "Acceptable values are #{valid_commands.inspect}"
61
- else
62
- command
63
- end
35
+ def set_node_b(node, value)
36
+ set_node node, Base64.encode64(value)
64
37
  end
65
- # Loads the application request template according to the command
66
- def load_template(command)
67
- template_dir = File.expand_path('../xml_templates/application_request',
68
- __FILE__)
69
38
 
70
- case command
39
+ def pretty_command
40
+ @command.to_s.split(/[\W_]/).map {|c| c.capitalize}.join
41
+ end
71
42
 
43
+ def set_nodes_contents
44
+ case @command
45
+ when :create_certificate
46
+ set_create_certificate_nodes
72
47
  when :get_certificate
73
- path = "#{template_dir}/get_certificate.xml"
48
+ set_get_certificate_nodes
74
49
  when :download_file_list
75
- path = "#{template_dir}/download_file_list.xml"
76
- when :get_user_info
77
- path = "#{template_dir}/get_user_info.xml"
78
- when :upload_file
79
- path = "#{template_dir}/upload_file.xml"
50
+ set_download_file_list_nodes
80
51
  when :download_file
81
- path = "#{template_dir}/download_file.xml"
52
+ set_download_file_nodes
53
+ when :upload_file
54
+ set_upload_file_nodes
82
55
  when :get_bank_certificate
83
- path = "#{template_dir}/danske_get_bank_certificate.xml"
56
+ set_get_bank_certificate_nodes
84
57
  end
58
+ end
85
59
 
86
- @ar = Nokogiri::XML(File.open(path))
60
+ def set_download_file_nodes
61
+ set_download_file_list_nodes
62
+ set_node("FileReference", @file_reference)
87
63
  end
88
64
 
65
+ def set_get_bank_certificate_nodes
66
+ set_node("elem|BankRootCertificateSerialNo", @bank_root_cert_serial)
67
+ set_node("elem|Timestamp", iso_time)
68
+ set_node("elem|RequestId", @request_id)
69
+ end
89
70
 
90
- def set_node(node, value)
91
- @ar.at_css(node).content = value
71
+ def set_upload_file_nodes
72
+ set_node_b("Content", @content)
73
+ set_node("FileType", @file_type)
74
+ set_node("TargetId", @target_id)
92
75
  end
93
76
 
94
- # Set the nodes' contents according to the command
95
- def set_nodes_contents
96
- if @command != :get_bank_certificate
97
- set_node("CustomerId", @customer_id)
98
- set_node("Timestamp", Time.now.iso8601)
99
- set_node("Environment", @environment)
100
- set_node("SoftwareId", "Sepa Transfer Library version #{VERSION}")
101
- set_node("Command",
102
- @command.to_s.split(/[\W_]/).map {|c| c.capitalize}.join)
103
- end
77
+ def set_download_file_list_nodes
78
+ set_node("Status", @status)
79
+ set_node("TargetId", @target_id)
80
+ set_node("FileType", @file_type)
81
+ end
104
82
 
105
- case @command
83
+ def set_get_certificate_nodes
84
+ set_node("Service", @service)
85
+ set_node("Content", format_cert_request(@csr))
86
+ set_node("HMAC", hmac(@pin, csr_to_binary(@csr)))
87
+ end
106
88
 
107
- when :get_certificate
108
- set_node("Service", @service)
109
- set_node("Content", Base64.encode64(@csr.to_der))
110
- set_node("HMAC", Base64.encode64(@hmac).chop)
111
- when :download_file_list
112
- set_node("Status", @status)
113
- set_node("TargetId", @target_id)
114
- set_node("FileType", @file_type)
115
- when :download_file
116
- set_node("Status", @status)
117
- set_node("TargetId", @target_id)
118
- set_node("FileType", @file_type)
119
- set_node("FileReference", @file_reference)
120
- when :upload_file
121
- set_node("Content", Base64.encode64(@content))
122
- set_node("FileType", @file_type)
123
- set_node("TargetId", @target_id)
124
- when :get_bank_certificate
125
- set_node("elem|BankRootCertificateSerialNo", @bank_root_cert_serial)
126
- set_node("elem|Timestamp", Time.now.iso8601)
127
- set_node("elem|RequestId", @request_id)
128
- end
89
+ def set_create_certificate_nodes
90
+ set_node("tns|CustomerId", @customer_id)
91
+ set_node("tns|KeyGeneratorType", @key_generator_type)
92
+ set_node("tns|EncryptionCertPKCS10", format_cert_request(@encryption_cert_pkcs10))
93
+ set_node("tns|SigningCertPKCS10", format_cert_request(@signing_cert_pkcs10))
94
+ set_node("tns|Timestamp", iso_time)
95
+ set_node("tns|RequestId", @request_id)
96
+ set_node("tns|Environment", @environment)
97
+ set_node("tns|PIN", @pin)
129
98
  end
130
99
 
131
- def create_hmac_seal(pin, csr)
132
- hmacseal = OpenSSL::HMAC.digest('sha1',pin,csr.to_der)
133
- hmacseal
100
+ def set_common_nodes
101
+ return if @command == :get_bank_certificate
102
+ return if @command == :create_certificate
103
+
104
+ set_node("CustomerId", @customer_id)
105
+ set_node("Timestamp", iso_time)
106
+ set_node("Environment", @environment)
107
+ set_node("SoftwareId", "Sepa Transfer Library version #{VERSION}")
108
+ set_node("Command", pretty_command)
134
109
  end
135
110
 
136
- def remove_node(doc, node, xmlns)
137
- doc.at_css("xmlns|#{node}", 'xmlns' => xmlns).remove
111
+ def remove_node(node, xmlns)
112
+ @ar.at_css("xmlns|#{node}", 'xmlns' => xmlns).remove
138
113
  end
139
114
 
140
- def add_node_to_root(doc, node)
141
- doc.root.add_child(node)
115
+ def add_node_to_root(node)
116
+ @ar.root.add_child(node)
142
117
  end
143
118
 
144
- def calculate_digest(doc)
119
+ def calculate_digest
145
120
  sha1 = OpenSSL::Digest::SHA1.new
146
- Base64.encode64(sha1.digest(doc.canonicalize))
121
+ Base64.encode64(sha1.digest(@ar.canonicalize))
147
122
  end
148
123
 
149
124
  def add_value_to_signature(node, value)
150
- node = @ar.at_css("dsig|#{node}",
151
- 'dsig' => 'http://www.w3.org/2000/09/xmldsig#')
152
- node.content = value
125
+ sig = @ar.at_css("dsig|#{node}", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#')
126
+ sig.content = value
153
127
  end
154
128
 
155
- def calculate_signature(private_key)
129
+ def calculate_signature
156
130
  sha1 = OpenSSL::Digest::SHA1.new
157
- node = @ar.at_css("dsig|SignedInfo",
158
- 'dsig' => 'http://www.w3.org/2000/09/xmldsig#')
159
- signature = private_key.sign(sha1, node.canonicalize)
131
+ node = @ar.at_css("dsig|SignedInfo", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#')
132
+ signature = @private_key.sign(sha1, node.canonicalize)
160
133
  Base64.encode64(signature)
161
134
  end
162
135
 
163
- def format_cert(cert)
164
- cert = cert.to_s
165
- cert = cert.split('-----BEGIN CERTIFICATE-----')[1]
166
- cert = cert.split('-----END CERTIFICATE-----')[0]
167
- cert.gsub!(/\s+/, "")
168
- end
169
-
170
136
  def process_signature
171
- signature_node = remove_node(@ar,
172
- 'Signature',
173
- 'http://www.w3.org/2000/09/xmldsig#')
174
- digest = calculate_digest(@ar)
175
- add_node_to_root(@ar, signature_node)
137
+ # No signature for Certificate Requests
138
+ return if @command == :get_certificate
139
+ return if @command == :get_bank_certificate
140
+ return if @command == :create_certificate
141
+
142
+ signature_node = remove_node('Signature', 'http://www.w3.org/2000/09/xmldsig#')
143
+ digest = calculate_digest
144
+ add_node_to_root(signature_node)
176
145
  add_value_to_signature('DigestValue', digest)
177
- signature = calculate_signature(@private_key)
178
- add_value_to_signature('SignatureValue', signature)
179
- add_value_to_signature('X509Certificate',format_cert(@cert))
146
+ add_value_to_signature('SignatureValue', calculate_signature)
147
+ add_value_to_signature('X509Certificate', format_cert(@cert))
180
148
  end
149
+
181
150
  end
182
151
  end
@@ -1,123 +1,67 @@
1
1
  module Sepa
2
2
  class ApplicationResponse
3
- def initialize(ar)
4
- @ar = ar
5
-
6
- if !@ar.respond_to?(:canonicalize)
7
- fail ArgumentError,
8
- "The application response you provided is not a valid Nokogiri::XML" \
9
- " file."
10
- elsif !valid_against_ar_schema?(@ar)
11
- fail ArgumentError,
12
- "The application response you provided doesn't validate against" \
13
- " application response schema."
14
- end
3
+ include ActiveModel::Validations
4
+ include Utilities
5
+
6
+ attr_accessor :ar, :certificate
7
+
8
+ validate :response_must_validate_against_schema
9
+ validate :validate_document_format
10
+
11
+ def initialize(app_resp)
12
+ self.ar = app_resp
13
+ self.certificate = extract_cert(ar, 'X509Certificate', 'http://www.w3.org/2000/09/xmldsig#')
15
14
  end
16
15
 
17
- # Checks that the hash value reported in the signature matches the actual
18
- # one.
16
+ # Checks that the hash value reported in the signature matches the actual one.
19
17
  def hashes_match?
20
- ar = @ar.clone
18
+ are = ar.clone
21
19
 
22
- digest_value = ar.at_css(
20
+ digest_value = are.at_css(
23
21
  'xmlns|DigestValue',
24
22
  'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
25
23
  ).content.strip
26
24
 
27
- ar.at_css(
25
+ are.at_css(
28
26
  "xmlns|Signature",
29
27
  'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
30
28
  ).remove
31
29
 
32
- actual_digest = calculate_digest(ar)
30
+ actual_digest = calculate_digest(are)
33
31
 
34
- if digest_value == actual_digest
35
- true
36
- else
37
- false
38
- end
39
- end
32
+ return true if digest_value == actual_digest
40
33
 
41
- # Extracts the X509 certificate from the application response.
42
- def certificate
43
- cert_value = @ar.at_css(
44
- 'xmlns|X509Certificate',
45
- 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
46
- ).content.gsub(/\s+/, "")
47
-
48
- cert = process_cert_value(cert_value)
49
-
50
- begin
51
- OpenSSL::X509::Certificate.new(cert)
52
- rescue => e
53
- fail OpenSSL::X509::CertificateError,
54
- "The certificate embedded in the application response could not be " \
55
- "processed. It's most likely corrupted. " \
56
- "OpenSSL had this to say: #{e}."
57
- end
34
+ false
58
35
  end
59
36
 
60
- # Checks that the signature is signed with the private key of the
61
- # certificate's public key.
37
+ # Checks that the signature is signed with the private key of the certificate's public key.
62
38
  def signature_is_valid?
63
- node = @ar.at_css('xmlns|SignedInfo',
64
- 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#')
39
+ node = ar.at_css('xmlns|SignedInfo', 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#')
65
40
 
66
41
  node = node.canonicalize
67
42
 
68
- signature = @ar.at_css(
43
+ signature = ar.at_css(
69
44
  'xmlns|SignatureValue',
70
45
  'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
71
46
  ).content
72
47
 
73
48
  signature = Base64.decode64(signature)
74
49
 
50
+ # Return true or false
75
51
  certificate.public_key.verify(OpenSSL::Digest::SHA1.new, signature, node)
76
52
  end
77
53
 
78
- # Checks that the certificate in the application response is signed with the
79
- # private key of the public key of the certificate as parameter.
80
- def cert_is_trusted?(root_cert)
81
- if root_cert.subject == certificate.issuer
82
- certificate.verify(root_cert.public_key)
83
- else
84
- fail SecurityError,
85
- "The issuer of the certificate doesn't match the subject of the " \
86
- "root certificate."
87
- end
88
- end
89
-
90
54
  private
91
55
 
92
- def calculate_digest(node)
93
- sha1 = OpenSSL::Digest::SHA1.new
94
-
95
- canon_node = node.canonicalize(
96
- mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
97
- inclusive_namespaces=nil,with_comments=false
98
- )
99
-
100
- Base64.encode64(sha1.digest(canon_node)).gsub(/\s+/, "")
101
- end
102
-
103
- def valid_against_ar_schema?(doc)
104
- schemas_path = File.expand_path('../../../lib/sepa/xml_schemas',
105
- __FILE__)
106
-
107
- Dir.chdir(schemas_path) do
108
- xsd = Nokogiri::XML::Schema(IO.read('application_response.xsd'))
109
- xsd.valid?(doc)
56
+ def validate_document_format
57
+ unless ar.respond_to?(:canonicalize)
58
+ errors.add(:base, 'Document must be a Nokogiri XML file')
110
59
  end
111
60
  end
112
61
 
113
- # Takes the certificate from the application response, adds begin and end
114
- # certificate texts and splits it into multiple lines so that OpenSSL
115
- # can read it.
116
- def process_cert_value(cert_value)
117
- cert = "-----BEGIN CERTIFICATE-----\n"
118
- cert += cert_value.to_s.gsub(/\s+/, "").scan(/.{1,64}/).join("\n")
119
- cert += "\n"
120
- cert += "-----END CERTIFICATE-----"
62
+ def response_must_validate_against_schema
63
+ check_validity_against_schema(ar, 'application_response.xsd')
121
64
  end
65
+
122
66
  end
123
67
  end
@@ -0,0 +1,169 @@
1
+ module Sepa
2
+ module AttributeChecks
3
+ include ErrorMessages
4
+
5
+ def allowed_commands
6
+ case bank
7
+ when :nordea
8
+ [:get_certificate, :get_user_info, :download_file_list, :download_file, :upload_file]
9
+ when :danske
10
+ [:get_bank_certificate, :get_user_info, :download_file_list, :download_file,
11
+ :upload_file, :create_certificate]
12
+ else
13
+ []
14
+ end
15
+ end
16
+
17
+ def check_command
18
+ errors.add(:command, "Invalid command") unless allowed_commands.include? command
19
+ end
20
+
21
+ def check_keys
22
+ return if [:get_certificate, :get_bank_certificate, :create_certificate].include? command
23
+
24
+ begin
25
+ OpenSSL::PKey::RSA.new private_key
26
+ rescue
27
+ errors.add(:private_key, "Invalid private key")
28
+ end
29
+
30
+ begin
31
+ OpenSSL::X509::Certificate.new cert
32
+ rescue
33
+ errors.add(:cert, "Invalid certificate")
34
+ end
35
+ end
36
+
37
+ def check_signing_cert
38
+ return unless command == :create_certificate
39
+
40
+ unless cert_request_valid?(signing_cert_pkcs10)
41
+ errors.add(:signing_cert_pkcs10, SIGNING_CERT_REQUEST_ERROR_MESSAGE)
42
+ end
43
+ end
44
+
45
+ def check_encryption_cert_request
46
+ return unless command == :create_certificate
47
+
48
+ unless cert_request_valid?(encryption_cert_pkcs10)
49
+ errors.add(:encryption_cert_pkcs10, ENCRYPTION_CERT_REQUEST_ERROR_MESSAGE)
50
+ end
51
+ end
52
+
53
+ def wsdl
54
+ case bank
55
+ when :nordea
56
+ if command == :get_certificate
57
+ file = "wsdl_nordea_cert.xml"
58
+ else
59
+ file = "wsdl_nordea.xml"
60
+ end
61
+ when :danske
62
+ if [:get_bank_certificate, :create_certificate].include? command
63
+ file = "wsdl_danske_cert.xml"
64
+ else
65
+ file = "wsdl_danske.xml"
66
+ end
67
+ else
68
+ return nil
69
+ end
70
+
71
+ "#{WSDL_PATH}/#{file}"
72
+ end
73
+
74
+ def check_wsdl
75
+ return unless wsdl.present?
76
+
77
+ xsd = Nokogiri::XML::Schema(File.read(SCHEMA_FILE))
78
+ wsdl_file = File.read(wsdl)
79
+ xml = Nokogiri::XML(wsdl_file)
80
+
81
+ unless xsd.valid?(xml)
82
+ errors.add(:wsdl, "Invalid wsdl file")
83
+ end
84
+ end
85
+
86
+ def check_file_type
87
+ return unless [:upload_file, :download_file_list, :download_file].include? command
88
+
89
+ if file_type.nil? || file_type.size > 35
90
+ errors.add(:file_type, FILE_TYPE_ERROR_MESSAGE)
91
+ end
92
+ end
93
+
94
+ def check_target_id
95
+ return if [:get_certificate, :create_certificate, :get_bank_certificate].include? command
96
+
97
+ check_presence_and_length(:target_id, 80, TARGET_ID_ERROR_MESSAGE)
98
+ end
99
+
100
+ def check_presence_and_length(attribute, length, error_message)
101
+ if send(attribute).nil? || send(attribute).size > length
102
+ errors.add(attribute, error_message)
103
+ end
104
+ end
105
+
106
+ def check_content
107
+ return unless command == :upload_file
108
+
109
+ errors.add(:content, CONTENT_ERROR_MESSAGE) if content.nil?
110
+ end
111
+
112
+ def check_pin
113
+ return unless command == :create_certificate
114
+
115
+ check_presence_and_length(:pin, 10, PIN_ERROR_MESSAGE)
116
+ end
117
+
118
+ def check_bank_root_cert_serial
119
+ return unless command == :get_bank_certificate
120
+
121
+ unless bank_root_cert_serial && bank_root_cert_serial.length.between?(1, 64)
122
+ errors.add(:bank_root_cert_serial, "Invalid bank root certificate serial")
123
+ end
124
+ end
125
+
126
+ def check_environment
127
+ return if command == :get_bank_certificate
128
+
129
+ environments = ['PRODUCTION', 'TEST', 'customertest']
130
+
131
+ unless environments.include? environment
132
+ errors.add(:environment, ENVIRONMENT_ERROR_MESSAGE)
133
+ end
134
+ end
135
+
136
+ def check_customer_id
137
+ return if command == :get_bank_certificate
138
+
139
+ unless customer_id && customer_id.length.between?(1, 16)
140
+ errors.add(:customer_id, CUSTOMER_ID_ERROR_MESSAGE)
141
+ end
142
+ end
143
+
144
+ def check_enc_cert
145
+ return unless command == :create_certificate
146
+
147
+ errors.add(:enc_cert, ENCRYPTION_CERT_ERROR_MESSAGE) unless enc_cert
148
+ end
149
+
150
+ def check_status
151
+ return unless [:download_file_list, :download_file].include? command
152
+
153
+ statuses = ['NEW', 'DOWNLOADED', 'ALL']
154
+
155
+ unless status && statuses.include?(status)
156
+ errors.add :status, STATUS_ERROR_MESSAGE
157
+ end
158
+ end
159
+
160
+ def check_file_reference
161
+ return unless command == :download_file
162
+
163
+ unless file_reference && file_reference.length <= 32
164
+ errors.add :file_reference, FILE_REFERENCE_ERROR_MESSAGE
165
+ end
166
+ end
167
+
168
+ end
169
+ end
@@ -0,0 +1,19 @@
1
+ module Sepa
2
+ class DanskeResponse < Response
3
+ attr_reader :bank_encryption_cert, :bank_signing_cert, :bank_root_cert, :own_encryption_cert,
4
+ :own_signing_cert, :ca_certificate
5
+
6
+ # Namespace used in danske bank certificate responses and requests
7
+ TNS = 'http://danskebank.dk/PKI/PKIFactoryService/elements'
8
+
9
+ def initialize(response, command: nil)
10
+ super
11
+ @bank_encryption_cert = extract_cert(soap, 'BankEncryptionCert', TNS)
12
+ @bank_signing_cert = extract_cert(soap, 'BankSigningCert', TNS)
13
+ @bank_root_cert = extract_cert(soap, 'BankRootCert', TNS)
14
+ @own_encryption_cert = extract_cert(soap, 'EncryptionCert', TNS)
15
+ @own_signing_cert = extract_cert(soap, 'SigningCert', TNS)
16
+ @ca_certificate = extract_cert(soap, 'CACert', TNS)
17
+ end
18
+ end
19
+ end