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,43 +1,40 @@
1
1
  module Sepa
2
2
  class SoapBuilder
3
- # SoapBuilder checks and validates incoming params and creates the SOAP structure
4
- def initialize(params)
5
-
6
- check_params(params)
7
- # Generate a request ID for the request
8
- params[:request_id] = generate_request_id
9
-
10
- # Check if the bank&command need keys/certificates/csr's
11
- @params = initialize_certificates_and_csr(params)
12
-
13
- check_if_bank_allows_command(@params)
3
+ include Utilities
14
4
 
15
- @ar = ApplicationRequest.new(@params).get_as_base64
5
+ attr_reader :ar
16
6
 
17
- @bank = @params.fetch(:bank)
18
- find_correct_bank_extension(@bank)
19
-
20
- @template_path = File.expand_path('../xml_templates/soap/', __FILE__)
7
+ # SoapBuilder creates the SOAP structure.
8
+ def initialize(params)
9
+ @bank = params[:bank]
10
+ @private_key = params[:private_key]
11
+ @cert = params[:cert]
12
+ @command = params[:command]
13
+ @customer_id = params[:customer_id]
14
+ @environment = params[:environment]
15
+ @status = params[:status]
16
+ @target_id = params[:target_id]
17
+ @language = params[:language]
18
+ @file_type = params[:file_type]
19
+ @content = params[:content]
20
+ @file_reference = params[:file_reference]
21
+ @enc_cert = params[:enc_cert]
22
+ @header_template = load_header_template
23
+ @template = load_body_template SOAP_TEMPLATE_PATH
24
+ @ar = ApplicationRequest.new(params)
25
+
26
+ find_correct_bank_extension
21
27
  end
22
28
 
23
29
  def to_xml
24
30
  # Returns a complete SOAP message in xml format
25
- find_correct_build(@params).to_xml
26
- end
27
-
28
- def get_ar_as_base64
29
- @ar
31
+ find_correct_build.to_xml
30
32
  end
31
33
 
32
34
  private
33
35
 
34
- def generate_request_id
35
- reqid = SecureRandom.random_number(1000).to_s<<SecureRandom.random_number(1000).to_s
36
- reqid
37
- end
38
-
39
- def find_correct_bank_extension(bank)
40
- case bank
36
+ def find_correct_bank_extension
37
+ case @bank
41
38
  when :danske
42
39
  self.extend(DanskeSoapRequest)
43
40
  when :nordea
@@ -45,351 +42,64 @@ module Sepa
45
42
  end
46
43
  end
47
44
 
48
- # Generic building steps
49
45
  def calculate_digest(doc, node)
50
46
  sha1 = OpenSSL::Digest::SHA1.new
51
-
52
47
  node = doc.at_css(node)
53
48
 
54
49
  canon_node = node.canonicalize(
55
- mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
56
- inclusive_namespaces=nil,with_comments=false
50
+ mode = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
51
+ inclusive_namespaces = nil, with_comments = false
57
52
  )
58
53
 
59
54
  Base64.encode64(sha1.digest(canon_node)).gsub(/\s+/, "")
60
55
  end
61
56
 
62
- def calculate_signature(doc, node, private_key)
57
+ def calculate_signature(doc, node)
63
58
  sha1 = OpenSSL::Digest::SHA1.new
64
-
65
59
  node = doc.at_css(node)
66
60
 
67
61
  canon_signed_info_node = node.canonicalize(
68
- mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,inclusive_namespaces=nil,
69
- with_comments=false
62
+ mode = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
63
+ inclusive_namespaces = nil, with_comments = false
70
64
  )
71
65
 
72
- signature = private_key.sign(sha1, canon_signed_info_node)
73
-
66
+ signature = @private_key.sign(sha1, canon_signed_info_node)
74
67
  Base64.encode64(signature).gsub(/\s+/, "")
75
68
  end
76
69
 
77
- def load_body_template(command)
78
- case command
79
- when :download_file_list
80
- path = "#{@template_path}/download_file_list.xml"
81
- when :get_user_info
82
- path = "#{@template_path}/get_user_info.xml"
83
- when :upload_file
84
- path = "#{@template_path}/upload_file.xml"
85
- when :download_file
86
- path = "#{@template_path}/download_file.xml"
87
- when :get_certificate
88
- path = "#{@template_path}/get_certificate.xml"
89
- when :get_bank_certificate
90
- path = "#{@template_path}/danske_get_bank_certificate.xml"
91
- end
92
-
93
- body_template = File.open(path)
94
- body = Nokogiri::XML(body_template)
95
- body_template.close
96
-
97
- body
70
+ def load_header_template
71
+ path = File.open("#{SOAP_TEMPLATE_PATH}/header.xml")
72
+ Nokogiri::XML(path)
98
73
  end
99
74
 
100
75
  def set_node(doc, node, value)
101
76
  doc.at_css(node).content = value
102
77
  end
103
78
 
104
- def add_body_to_header(header, body)
105
- body = body.at_css('env|Body')
106
- header.root.add_child(body)
107
- header
108
- end
109
-
110
- def extract_public_key(cert)
111
- pkey = cert.public_key
112
- pkey = OpenSSL::PKey::RSA.new(pkey)
113
-
114
- pkey
115
- end
116
-
117
- def format_cert(cert)
118
- cert = cert.to_s
119
- cert = cert.split('-----BEGIN CERTIFICATE-----')[1]
120
- cert = cert.split('-----END CERTIFICATE-----')[0]
121
- cert.gsub!(/\s+/, "")
122
- end
123
-
124
- def load_header_template(template_path)
125
- header_template = File.open("#{template_path}/header.xml")
126
- header = Nokogiri::XML(header_template)
127
- header_template.close
128
- header
129
- end
130
-
131
- def process_header(header, body, private_key, cert)
132
- set_node(header, 'wsu|Created', Time.now.iso8601)
133
-
134
- set_node(header, 'wsu|Expires', (Time.now + 3600).iso8601)
135
-
136
- timestamp_digest = calculate_digest(header,'wsu|Timestamp')
137
- set_node(header,'dsig|Reference[URI="#dsfg8sdg87dsf678g6dsg6ds7fg"]' \
138
- ' dsig|DigestValue', timestamp_digest)
139
-
140
- body_digest = calculate_digest(body, 'env|Body')
141
- set_node(header,'dsig|Reference[URI="#sdf6sa7d86f87s6df786sd87f6s8fsd'\
142
- 'a"] dsig|DigestValue', body_digest)
143
-
144
- signature = calculate_signature(header, 'dsig|SignedInfo', private_key)
145
- set_node(header, 'dsig|SignatureValue', signature)
146
-
147
- formatted_cert = format_cert(cert)
148
- set_node(header, 'wsse|BinarySecurityToken', formatted_cert)
79
+ def add_body_to_header
80
+ body = @template.at_css('env|Body')
81
+ @header_template.root.add_child(body)
82
+ @header_template
149
83
  end
150
84
 
151
- # Tries to validate the parameters or their presence.
152
- def check_params(params)
153
- # Universally for all
154
- check_params_hash(params)
155
- check_certificate_and_key_requirements(params)
156
- check_bank(params[:bank])
157
- check_env(params[:environment])
158
- check_customer_id(params[:customer_id])
85
+ def process_header
86
+ set_node(@header_template, 'wsu|Created', iso_time)
87
+ set_node(@header_template, 'wsu|Expires', (Time.now.utc + 300).iso8601)
159
88
 
160
- # Generic commands
161
- generic_commands = [:download_file,:download_file_list,:get_user_info]
89
+ timestamp_digest = calculate_digest(@header_template, 'wsu|Timestamp')
90
+ dsig = 'dsig|Reference[URI="#dsfg8sdg87dsf678g6dsg6ds7fg"] dsig|DigestValue'
91
+ set_node(@header_template, dsig, timestamp_digest)
162
92
 
163
- # Depending on command
164
- case params[:command]
165
- when :get_certificate
166
- check_pin(params[:pin])
167
- check_service(params[:service])
168
- when *generic_commands
169
- if params[:bank] == :nordea
170
- check_lang(params[:language])
171
- check_status(params[:status])
172
- check_target_id(params[:target_id])
173
- check_file_type(params[:file_type])
174
- end
175
- when :upload_file
176
- check_lang(params[:language])
177
- check_target_id(params[:target_id])
178
- check_file_type(params[:file_type])
179
- check_content(params[:content])
180
- when :get_bank_certificate
181
- if params[:bank] == :danske
182
- # Nothing here
183
- end
184
- else
185
- fail ArgumentError, "Command not supported."
186
- end
187
- end
93
+ body_digest = calculate_digest(@template, 'env|Body')
94
+ dsig = 'dsig|Reference[URI="#sdf6sa7d86f87s6df786sd87f6s8fsda"] dsig|DigestValue'
95
+ set_node(@header_template, dsig, body_digest)
188
96
 
189
- def check_csr(csr)
190
- unless csr
191
- fail ArgumentError, "You didn't provide a certificate signing request"
192
- end
193
- end
194
-
195
- def check_params_hash(params)
196
- unless params.respond_to?(:each_pair)
197
- fail ArgumentError, "You didn't provide a proper hash"
198
- end
199
- end
97
+ signature = calculate_signature(@header_template, 'dsig|SignedInfo')
98
+ set_node(@header_template, 'dsig|SignatureValue', signature)
200
99
 
201
- def check_bank(bank)
202
- unless [:nordea, :danske].include?(bank)
203
- fail ArgumentError, "You didn't provide a proper bank. " \
204
- "Acceptable values are nordea OR danske."
205
- end
206
- end
207
-
208
- def check_request_id(request_id)
209
- if request_id.to_i == 0
210
- fail ArgumentError, "Request ID must be a number and not 0"
211
- end
212
- end
213
-
214
- def check_keygen_type(keygen)
215
- unless keygen
216
- fail ArgumentError, "You didn't provide any Key Generator Type"
217
- end
218
- end
219
-
220
- def check_encryption_pkcs10(enc_cert)
221
- unless enc_cert
222
- fail ArgumentError, "You didn't provide Encrypting certificate PKCS10"
223
- end
224
- end
225
-
226
- def check_signing_pkcs10(sig_cert)
227
- unless sig_cert
228
- fail ArgumentError, "You didn't provide Signing certificate PKCS10"
229
- end
100
+ formatted_cert = format_cert(@cert)
101
+ set_node(@header_template, 'wsse|BinarySecurityToken', formatted_cert)
230
102
  end
231
103
 
232
- def check_pin(pin)
233
- unless pin
234
- fail ArgumentError, "You didn't provide a secret PIN"
235
- end
236
- end
237
-
238
- def check_private_key(private_key)
239
- unless private_key.respond_to?(:sign)
240
- fail ArgumentError, "You didn't provide a proper private key. The " \
241
- "key has to be in OpenSSL::PKey::RSA - format."
242
- end
243
- end
244
-
245
- def check_cert(cert)
246
- unless cert.respond_to?(:check_private_key)
247
- fail ArgumentError, "You didn't provide a proper certificate. The " \
248
- "certificate has to be in OpenSSL::X509::Certificate - format."
249
- end
250
- end
251
-
252
- def check_customer_id(customer_id)
253
- unless customer_id && customer_id.respond_to?(:to_s) &&
254
- customer_id.length <= 16
255
- fail ArgumentError, "You didn't provide a proper customer id"
256
- end
257
- end
258
-
259
- def check_env(env)
260
- unless ['PRODUCTION', 'TEST', 'customertest'].include?(env)
261
- fail ArgumentError, "You didn't provide a proper environment. " \
262
- "Acceptable values are PRODUCTION or TEST or customertest."
263
- end
264
- end
265
-
266
- def check_status(status)
267
- unless ['NEW', 'DOWNLOADED', 'ALL'].include?(status)
268
- fail ArgumentError, "You didn't provide a proper status. " \
269
- "Acceptable values are NEW, DOWNLOADED or ALL."
270
- end
271
- end
272
-
273
- def check_target_id(target_id)
274
- unless target_id && target_id.respond_to?(:to_s) &&
275
- target_id.length <= 80
276
- fail ArgumentError, "You didn't provide a proper target id"
277
- end
278
- end
279
-
280
- def check_lang(lang)
281
- unless ['FI', 'SE', 'EN'].include?(lang)
282
- fail ArgumentError, "You didn't provide a proper language. " \
283
- "Acceptable values are FI, SE or EN."
284
- end
285
- end
286
-
287
- def check_file_type(file_type)
288
- unless file_type && file_type.respond_to?(:to_s) &&
289
- file_type.length <= 20
290
- fail ArgumentError, "You didn't provide a proper file type. Check " \
291
- "Your bank's documentation for available file types."
292
- end
293
- end
294
-
295
- def check_content(content)
296
- unless content
297
- fail ArgumentError, "You didn't provide any content."
298
- end
299
- end
300
-
301
- def check_service(service)
302
- unless ['service', 'ISSUER', 'MATU'].include?(service)
303
- fail ArgumentError, "You didn't provide a proper service."
304
- end
305
- end
306
-
307
- def check_hmac(hmac)
308
- unless hmac
309
- fail ArgumentError, "You didn't provide any HMAC."
310
- end
311
- end
312
-
313
- def check_if_bank_allows_command(params)
314
- bank = params.fetch(:bank)
315
- command = params.fetch(:command)
316
- case bank
317
- when :nordea
318
- allowed_commands = [:get_certificate,:get_user_info,
319
- :download_file_list,:download_file,:upload_file]
320
- unless allowed_commands.include?(command)
321
- fail ArgumentError, "You didn't provide a matching bank and service."
322
- end
323
- when :danske
324
- allowed_commands = [:get_bank_certificate]
325
- unless allowed_commands.include?(command)
326
- fail ArgumentError, "You didn't provide a matching bank and service."
327
- end
328
- end
329
- end
330
-
331
- def check_certificate_and_key_requirements(params)
332
- command = params[:command]
333
- require_private_and_cert = [:get_user_info,:download_file_list,
334
- :download_file,:upload_file]
335
- require_nothing = [:get_bank_certificate]
336
- require_pkcs = [:get_certificate]
337
-
338
- case command
339
- when *require_private_and_cert
340
- if params[:cert_path] == nil && params[:cert_plain] == nil
341
- fail ArgumentError, "You must provide a path to the certificate " \
342
- "or certificate in plain text"
343
- end
344
- if params[:private_key_path] == nil && params[:private_key_plain] == nil
345
- fail ArgumentError, "You must provide a path to your private key " \
346
- "or private key in plain text"
347
- end
348
- when *require_nothing
349
- when *require_pkcs
350
- if params[:csr_path] == nil && params[:csr_plain] == nil
351
- fail ArgumentError, "You must provide a path to the CSR or CSR in plain text"
352
- end
353
- end
354
- end
355
-
356
- def initialize_certificates_and_csr(params)
357
- begin
358
- command = params[:command]
359
- require_private_and_cert = [:get_user_info,:download_file_list,
360
- :download_file,:upload_file]
361
- require_nothing = [:get_bank_certificate]
362
- require_pkcs = [:get_certificate]
363
-
364
- case command
365
- when *require_private_and_cert
366
- if params[:cert_path] != nil
367
- params[:cert] = OpenSSL::X509::Certificate.new(File.read(params.fetch(:cert_path)))
368
- elsif params[:cert_plain] != nil
369
- params[:cert] = OpenSSL::X509::Certificate.new(params.fetch(:cert_plain))
370
- end
371
- if params[:private_key_path] != nil
372
- params[:private_key] = OpenSSL::PKey::RSA.new(File.read(params.fetch(:private_key_path)))
373
- elsif params[:private_key_plain] != nil
374
- params[:private_key] = OpenSSL::PKey::RSA.new(params.fetch(:private_key_plain))
375
- end
376
- check_private_key(params[:private_key])
377
- check_cert(params[:cert])
378
- when *require_nothing
379
- when *require_pkcs
380
- if params[:csr_path] != nil
381
- params[:csr] = OpenSSL::X509::Request.new(File.read(params.fetch(:csr_path)))
382
- elsif params[:csr_plain] != nil
383
- params[:csr] = OpenSSL::X509::Request.new(params.fetch(:csr_plain))
384
- end
385
- check_csr(params[:csr])
386
- else
387
- fail ArgumentError, "No matching cases for initialize_certificates_and_csr"
388
- end
389
- params
390
- rescue Exception => e
391
- fail ArgumentError, "Parameter failed to initialize, check private key and cert path/plain"
392
- end
393
- end
394
104
  end
395
105
  end
@@ -0,0 +1,132 @@
1
+ module Sepa
2
+ module Utilities
3
+
4
+ def calculate_digest(node)
5
+ sha1 = OpenSSL::Digest::SHA1.new
6
+
7
+ canon_node = node.canonicalize(
8
+ mode = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
9
+ inclusive_namespaces = nil, with_comments = false
10
+ )
11
+
12
+ Base64.encode64(sha1.digest(canon_node)).gsub(/\s+/, "")
13
+ end
14
+
15
+ # Takes a certificate, adds begin and end
16
+ # certificate texts and splits it into multiple lines so that OpenSSL
17
+ # can read it.
18
+ def process_cert_value(cert_value)
19
+ cert = "-----BEGIN CERTIFICATE-----\n"
20
+ cert += cert_value.to_s.gsub(/\s+/, "").scan(/.{1,64}/).join("\n")
21
+ cert += "\n"
22
+ cert + "-----END CERTIFICATE-----"
23
+ end
24
+
25
+ def format_cert(cert)
26
+ cert = cert.to_s
27
+ cert = cert.split('-----BEGIN CERTIFICATE-----')[1]
28
+ cert = cert.split('-----END CERTIFICATE-----')[0]
29
+ cert.gsub!(/\s+/, "")
30
+ end
31
+
32
+ def format_cert_request(cert_request)
33
+ cert_request = cert_request.split('-----BEGIN CERTIFICATE REQUEST-----')[1]
34
+ cert_request = cert_request.split('-----END CERTIFICATE REQUEST-----')[0]
35
+ cert_request.gsub!(/\s+/, "")
36
+ end
37
+
38
+ def check_validity_against_schema(doc, schema)
39
+ Dir.chdir(SCHEMA_PATH) do
40
+ xsd = Nokogiri::XML::Schema(IO.read(schema))
41
+ unless doc.respond_to?(:canonicalize) && xsd.valid?(doc)
42
+ errors.add(:base, 'The document did not validate against the schema file')
43
+ end
44
+ end
45
+ end
46
+
47
+ # Extracts a certificate from a document and return it as an OpenSSL X509 certificate
48
+ # Return nil is the node cannot be found
49
+ def extract_cert(doc, node, namespace)
50
+ return nil unless doc.respond_to? :at
51
+
52
+ cert_raw = doc.at("xmlns|#{node}", 'xmlns' => namespace)
53
+
54
+ return nil if cert_raw.nil?
55
+
56
+ cert_raw = cert_raw.content.gsub(/\s+/, "")
57
+
58
+ cert = process_cert_value(cert_raw)
59
+
60
+ begin
61
+ OpenSSL::X509::Certificate.new(cert)
62
+ rescue => e
63
+ fail OpenSSL::X509::CertificateError,
64
+ "The certificate could not be processed. It's most likely corrupted. OpenSSL had this to say: #{e}."
65
+ end
66
+ end
67
+
68
+ def cert_request_valid?(cert_request)
69
+ begin
70
+ OpenSSL::X509::Request.new cert_request
71
+ rescue
72
+ return false
73
+ end
74
+
75
+ true
76
+ end
77
+
78
+ def load_body_template(template)
79
+ path = "#{template}/"
80
+
81
+ case @command
82
+ when :download_file_list
83
+ path << "download_file_list.xml"
84
+ when :get_user_info
85
+ path << "get_user_info.xml"
86
+ when :upload_file
87
+ path << "upload_file.xml"
88
+ when :download_file
89
+ path << "download_file.xml"
90
+ when :get_certificate
91
+ path << "get_certificate.xml"
92
+ when :get_bank_certificate
93
+ path << "danske_get_bank_certificate.xml"
94
+ when :create_certificate
95
+ path << "create_certificate.xml"
96
+ else
97
+ fail ArgumentError
98
+ end
99
+
100
+ Nokogiri::XML(File.open(path))
101
+ end
102
+
103
+ # Checks that the certificate in the application response is signed with the
104
+ # private key of the public key of the certificate as parameter.
105
+ def cert_is_trusted(root_cert)
106
+ if root_cert.subject == certificate.issuer
107
+ # Return true or false
108
+ certificate.verify(root_cert.public_key)
109
+ else
110
+ fail SecurityError, "false"
111
+ end
112
+ end
113
+
114
+ def iso_time
115
+ @iso_time ||= Time.now.utc.iso8601
116
+ end
117
+
118
+ def hmac(pin, csr)
119
+ Base64.encode64(OpenSSL::HMAC.digest('sha1', pin, csr)).chop
120
+ end
121
+
122
+ def csr_to_binary(csr)
123
+ OpenSSL::X509::Request.new(csr).to_der
124
+ end
125
+
126
+ def canonicalized_node(doc, namespace, node)
127
+ content_node = doc.at("xmlns|#{node}", xmlns: namespace)
128
+ content_node.canonicalize if content_node
129
+ end
130
+
131
+ end
132
+ end
data/lib/sepa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sepa
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end