sepafm 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sepa/application_request.rb +29 -13
  3. data/lib/sepa/attribute_checks.rb +29 -29
  4. data/lib/sepa/banks/danske/danske_response.rb +49 -10
  5. data/lib/sepa/banks/danske/soap_danske.rb +7 -6
  6. data/lib/sepa/banks/nordea/nordea_response.rb +2 -4
  7. data/lib/sepa/client.rb +31 -11
  8. data/lib/sepa/error_messages.rb +2 -1
  9. data/lib/sepa/response.rb +18 -3
  10. data/lib/sepa/soap_builder.rb +52 -21
  11. data/lib/sepa/utilities.rb +4 -0
  12. data/lib/sepa/version.rb +1 -1
  13. data/lib/sepa/wsdl/wsdl_danske.xml +1 -1
  14. data/lib/sepa/xml_templates/application_request/download_file.xml +0 -1
  15. data/lib/sepa/xml_templates/application_request/download_file_list.xml +0 -1
  16. data/lib/sepa/xml_templates/application_request/upload_file.xml +0 -1
  17. data/lib/sepa/xml_templates/soap/download_file_list.xml +1 -1
  18. data/lib/sepa/xml_templates/soap/header.xml +6 -5
  19. data/lib/sepafm.rb +1 -0
  20. data/readme.md +3 -5
  21. data/sepafm.gemspec +5 -5
  22. data/test/sepa/banks/danske/danske_cert_response_test.rb +6 -6
  23. data/test/sepa/banks/danske/danske_cert_soap_builder_test.rb +16 -17
  24. data/test/sepa/banks/danske/danske_certificate_application_request_test.rb +16 -0
  25. data/test/sepa/banks/danske/danske_generic_soap_builder_test.rb +39 -43
  26. data/test/sepa/banks/nordea/nordea_application_request_test.rb +38 -18
  27. data/test/sepa/banks/nordea/nordea_cert_application_request_test.rb +12 -11
  28. data/test/sepa/banks/nordea/nordea_cert_request_soap_builder_test.rb +10 -10
  29. data/test/sepa/banks/nordea/nordea_generic_soap_builder_test.rb +14 -18
  30. data/test/sepa/banks/nordea/nordea_response_test.rb +1 -1
  31. data/test/sepa/client_test.rb +38 -25
  32. data/test/sepa/fixtures.rb +52 -22
  33. data/test/sepa/sepa_test.rb +1 -1
  34. metadata +27 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ab8c54ea976ca82082e9fd8a3c3e9d25dcfe5fc
4
- data.tar.gz: 29dfa7aaae9a52035d94f1e887aab8eefe92fa37
3
+ metadata.gz: ef6bfed9365908016a49c134f04b31270f2cd7c0
4
+ data.tar.gz: fad409e18066c845c6cc8c267d1d6f328c365f6a
5
5
  SHA512:
6
- metadata.gz: 6230983ca55fba1b930de177d0531f9a6af9c3b78b1ea7a25563707126da2f5cf2753d83bf8458f2cc4b72b08f54aaaf801c07bc1c7f042d810aafbefab0ff31
7
- data.tar.gz: 07db9e69500dadf3665ba74b5a32002dfeb2abec313f342176e28698883d856fa138d50587c8e9586fcf43e6be401a73b1c305abb10de81a7f85cd67c9c77d3f
6
+ metadata.gz: 0caa72426efa99e3baf93ad1cbdeb08ae742a99001de93068d48a8405a406eb3fb07eeb5ae69aa3b582f1af7c6a53f2a1153eca7d1c5b4b68c0798a217a4c082
7
+ data.tar.gz: 05e7942b179477e1742190c6160bf6270b8770fe1ee3e78ac5be7926d2d39464dc87b3b0ea570cb03d60653d19f4cd2b2593c31001f6be94de00f9ab7e14acf0
@@ -58,12 +58,17 @@ module Sepa
58
58
  end
59
59
 
60
60
  def set_download_file_nodes
61
- set_download_file_list_nodes
61
+ add_target_id_after 'FileReferences'
62
+ set_node("Status", @status)
63
+ set_node("FileType", @file_type)
62
64
  set_node("FileReference", @file_reference)
63
65
  end
64
66
 
65
67
  def set_get_bank_certificate_nodes
66
- set_node("elem|BankRootCertificateSerialNo", @bank_root_cert_serial)
68
+ raise 'OnlyWorksWithDanske' if @bank != :danske
69
+
70
+ # Root Cert Serial Hardcoded to Danske
71
+ set_node("elem|BankRootCertificateSerialNo", '1111110002')
67
72
  set_node("elem|Timestamp", iso_time)
68
73
  set_node("elem|RequestId", @request_id)
69
74
  end
@@ -71,29 +76,32 @@ module Sepa
71
76
  def set_upload_file_nodes
72
77
  set_node_b("Content", @content)
73
78
  set_node("FileType", @file_type)
74
- set_node("TargetId", @target_id)
79
+ add_target_id_after 'Environment'
75
80
  end
76
81
 
77
82
  def set_download_file_list_nodes
83
+ add_target_id_after 'Environment'
78
84
  set_node("Status", @status)
79
- set_node("TargetId", @target_id)
80
85
  set_node("FileType", @file_type)
81
86
  end
82
87
 
83
88
  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)))
89
+ set_node("Service", '')
90
+ set_node("Content", format_cert_request(@signing_csr))
91
+ set_node("HMAC", hmac(@pin, csr_to_binary(@signing_csr)))
87
92
  end
88
93
 
89
94
  def set_create_certificate_nodes
90
95
  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))
96
+ set_node("tns|KeyGeneratorType", 'software')
97
+ set_node("tns|EncryptionCertPKCS10", format_cert_request(@encryption_csr))
98
+ set_node("tns|SigningCertPKCS10", format_cert_request(@signing_csr))
94
99
  set_node("tns|Timestamp", iso_time)
95
100
  set_node("tns|RequestId", @request_id)
101
+
102
+ @environment = 'customertest' if @environment == :test
96
103
  set_node("tns|Environment", @environment)
104
+
97
105
  set_node("tns|PIN", @pin)
98
106
  end
99
107
 
@@ -101,9 +109,9 @@ module Sepa
101
109
  return if @command == :get_bank_certificate
102
110
  return if @command == :create_certificate
103
111
 
112
+ set_node('Environment', @environment.to_s.upcase)
104
113
  set_node("CustomerId", @customer_id)
105
114
  set_node("Timestamp", iso_time)
106
- set_node("Environment", @environment)
107
115
  set_node("SoftwareId", "Sepa Transfer Library version #{VERSION}")
108
116
  set_node("Command", pretty_command)
109
117
  end
@@ -131,7 +139,7 @@ module Sepa
131
139
  sha1 = OpenSSL::Digest::SHA1.new
132
140
  dsig = 'http://www.w3.org/2000/09/xmldsig#'
133
141
  node = @application_request.at_css("dsig|SignedInfo", 'dsig' => dsig)
134
- signature = @private_key.sign(sha1, node.canonicalize)
142
+ signature = @signing_private_key.sign(sha1, node.canonicalize)
135
143
  encode signature
136
144
  end
137
145
 
@@ -146,7 +154,15 @@ module Sepa
146
154
  add_node_to_root(signature_node)
147
155
  add_value_to_signature('DigestValue', digest)
148
156
  add_value_to_signature('SignatureValue', calculate_signature)
149
- add_value_to_signature('X509Certificate', format_cert(@cert))
157
+ add_value_to_signature('X509Certificate', format_cert(@signing_certificate))
158
+ end
159
+
160
+ def add_target_id_after(node)
161
+ return unless @bank == :nordea
162
+
163
+ target_id = Nokogiri::XML::Node.new 'TargetId', @application_request
164
+ target_id.content = @target_id
165
+ @application_request.at(node).add_next_sibling target_id
150
166
  end
151
167
 
152
168
  end
@@ -7,7 +7,7 @@ module Sepa
7
7
  when :nordea
8
8
  [:get_certificate, :get_user_info, :download_file_list, :download_file, :upload_file]
9
9
  when :danske
10
- [:get_bank_certificate, :get_user_info, :download_file_list, :download_file,
10
+ [:get_bank_certificate, :download_file_list, :download_file,
11
11
  :upload_file, :create_certificate]
12
12
  else
13
13
  []
@@ -22,31 +22,31 @@ module Sepa
22
22
  return if [:get_certificate, :get_bank_certificate, :create_certificate].include? command
23
23
 
24
24
  begin
25
- OpenSSL::PKey::RSA.new private_key
25
+ rsa_key signing_private_key
26
26
  rescue
27
- errors.add(:private_key, "Invalid private key")
27
+ errors.add(:signing_private_key, "Invalid signing private key")
28
28
  end
29
29
 
30
30
  begin
31
- OpenSSL::X509::Certificate.new cert
31
+ OpenSSL::X509::Certificate.new signing_certificate
32
32
  rescue
33
- errors.add(:cert, "Invalid certificate")
33
+ errors.add(:signing_certificate, "Invalid signing certificate")
34
34
  end
35
35
  end
36
36
 
37
- def check_signing_cert
37
+ def check_signing_csr
38
38
  return unless command == :create_certificate
39
39
 
40
- unless cert_request_valid?(signing_cert_pkcs10)
41
- errors.add(:signing_cert_pkcs10, SIGNING_CERT_REQUEST_ERROR_MESSAGE)
40
+ unless cert_request_valid?(signing_csr)
41
+ errors.add(:signing_csr, SIGNING_CERT_REQUEST_ERROR_MESSAGE)
42
42
  end
43
43
  end
44
44
 
45
45
  def check_encryption_cert_request
46
46
  return unless command == :create_certificate
47
47
 
48
- unless cert_request_valid?(encryption_cert_pkcs10)
49
- errors.add(:encryption_cert_pkcs10, ENCRYPTION_CERT_REQUEST_ERROR_MESSAGE)
48
+ unless cert_request_valid?(encryption_csr)
49
+ errors.add(:encryption_csr, ENCRYPTION_CERT_REQUEST_ERROR_MESSAGE)
50
50
  end
51
51
  end
52
52
 
@@ -76,6 +76,9 @@ module Sepa
76
76
  :create_certificate,
77
77
  :get_bank_certificate].include? command
78
78
 
79
+ # Danske Bank does not use target_id
80
+ return if bank == :danske
81
+
79
82
  check_presence_and_length(:target_id, 80, TARGET_ID_ERROR_MESSAGE)
80
83
  end
81
84
 
@@ -97,44 +100,31 @@ module Sepa
97
100
  check_presence_and_length(:pin, 10, PIN_ERROR_MESSAGE)
98
101
  end
99
102
 
100
- def check_bank_root_cert_serial
101
- return unless command == :get_bank_certificate
102
-
103
- unless bank_root_cert_serial && bank_root_cert_serial.length.between?(1, 64)
104
- errors.add(:bank_root_cert_serial, "Invalid bank root certificate serial")
105
- end
106
- end
107
-
108
103
  def check_environment
109
104
  return if command == :get_bank_certificate
110
105
 
111
- environments = ['PRODUCTION', 'TEST', 'customertest']
112
-
113
- unless environments.include? environment
106
+ unless Client::ENVIRONMENTS.include? environment
114
107
  errors.add(:environment, ENVIRONMENT_ERROR_MESSAGE)
115
108
  end
116
109
  end
117
110
 
118
111
  def check_customer_id
119
- return if command == :get_bank_certificate
120
-
121
112
  unless customer_id && customer_id.length.between?(1, 16)
122
113
  errors.add(:customer_id, CUSTOMER_ID_ERROR_MESSAGE)
123
114
  end
124
115
  end
125
116
 
126
- def check_enc_cert
127
- return unless command == :create_certificate
117
+ def check_encryption_certificate
118
+ return unless bank == :danske
119
+ return if command == :get_bank_certificate
128
120
 
129
- errors.add(:enc_cert, ENCRYPTION_CERT_ERROR_MESSAGE) unless enc_cert
121
+ errors.add(:encryption_certificate, ENCRYPTION_CERT_ERROR_MESSAGE) unless encryption_certificate
130
122
  end
131
123
 
132
124
  def check_status
133
125
  return unless [:download_file_list, :download_file].include? command
134
126
 
135
- statuses = ['NEW', 'DOWNLOADED', 'ALL']
136
-
137
- unless status && statuses.include?(status)
127
+ unless status && Client::STATUSES.include?(status)
138
128
  errors.add :status, STATUS_ERROR_MESSAGE
139
129
  end
140
130
  end
@@ -147,5 +137,15 @@ module Sepa
147
137
  end
148
138
  end
149
139
 
140
+ def check_encryption_private_key
141
+ return unless bank == :danske
142
+ return if [:create_certificate, :get_bank_certificate].include? command
143
+
144
+ rsa_key encryption_private_key
145
+
146
+ rescue
147
+ errors.add :encryption_private_key, ENCRYPTION_PRIVATE_KEY_ERROR_MESSAGE
148
+ end
149
+
150
150
  end
151
151
  end
@@ -1,27 +1,43 @@
1
1
  module Sepa
2
2
  class DanskeResponse < Response
3
3
 
4
- def bank_encryption_cert
5
- @bank_encryption_cert ||= extract_cert(doc, 'BankEncryptionCert', DANSKE_PKI)
4
+ def application_response
5
+ @application_response ||= decrypt_application_response
6
6
  end
7
7
 
8
- def bank_signing_cert
9
- @bank_signing_cert ||= extract_cert(doc, 'BankSigningCert', DANSKE_PKI)
8
+ def bank_encryption_certificate
9
+ return unless @command == :get_bank_certificate
10
+
11
+ @bank_encryption_certificate ||= extract_cert(doc, 'BankEncryptionCert', DANSKE_PKI)
10
12
  end
11
13
 
12
- def bank_root_cert
13
- @bank_root_cert ||= extract_cert(doc, 'BankRootCert', DANSKE_PKI)
14
+ def bank_signing_certificate
15
+ return unless @command == :get_bank_certificate
16
+
17
+ @bank_signing_certificate ||= extract_cert(doc, 'BankSigningCert', DANSKE_PKI)
14
18
  end
15
19
 
16
- def own_encryption_cert
17
- @own_encryption_cert ||= extract_cert(doc, 'EncryptionCert', DANSKE_PKI)
20
+ def bank_root_certificate
21
+ return unless @command == :get_bank_certificate
22
+
23
+ @bank_root_certificate ||= extract_cert(doc, 'BankRootCert', DANSKE_PKI)
18
24
  end
19
25
 
20
- def own_signing_cert
21
- @own_signing_cert ||= extract_cert(doc, 'SigningCert', DANSKE_PKI)
26
+ def own_encryption_certificate
27
+ return unless @command == :create_certificate
28
+
29
+ @own_encryption_certificate ||= extract_cert(doc, 'EncryptionCert', DANSKE_PKI)
30
+ end
31
+
32
+ def own_signing_certificate
33
+ return unless @command == :create_certificate
34
+
35
+ @own_signing_certificate ||= extract_cert(doc, 'SigningCert', DANSKE_PKI)
22
36
  end
23
37
 
24
38
  def ca_certificate
39
+ return unless @command == :create_certificate
40
+
25
41
  @ca_certificate ||= extract_cert(doc, 'CACert', DANSKE_PKI)
26
42
  end
27
43
 
@@ -41,5 +57,28 @@ module Sepa
41
57
  node
42
58
  end
43
59
 
60
+ def decrypt_application_response
61
+ encrypted_application_response = extract_application_response(BXD)
62
+ encrypted_application_response = xml_doc encrypted_application_response
63
+ enc_key = encrypted_application_response.css('CipherValue', 'xmlns' => XMLENC)[0].content
64
+ enc_key = decode enc_key
65
+ key = @encryption_private_key.private_decrypt(enc_key)
66
+
67
+ encypted_data = encrypted_application_response
68
+ .css('CipherValue', 'xmlns' => XMLENC)[1]
69
+ .content
70
+
71
+ encypted_data = decode encypted_data
72
+ iv = encypted_data[0, 8]
73
+ encypted_data = encypted_data[8, encypted_data.length]
74
+
75
+ decipher = OpenSSL::Cipher.new('DES-EDE3-CBC')
76
+ decipher.decrypt
77
+ decipher.key = key
78
+ decipher.iv = iv
79
+
80
+ decipher.update(encypted_data) + decipher.final
81
+ end
82
+
44
83
  end
45
84
  end
@@ -15,12 +15,12 @@ module Sepa
15
15
  end
16
16
 
17
17
  def encrypt_application_request
18
- encryption_cert = OpenSSL::X509::Certificate.new(@enc_cert)
19
- encryption_public_key = encryption_cert.public_key
20
- encryption_cert = format_cert(encryption_cert)
21
- encrypted_ar, key = encrypt_ar
18
+ encryption_certificate = OpenSSL::X509::Certificate.new(@encryption_certificate)
19
+ encryption_public_key = encryption_certificate.public_key
20
+ encryption_certificate = format_cert(encryption_certificate)
21
+ encrypted_application_request, key = encrypt_ar
22
22
  encrypted_key = encrypt_key(key, encryption_public_key)
23
- build_encrypted_ar(encryption_cert, encrypted_key, encrypted_ar)
23
+ build_encrypted_ar(encryption_certificate, encrypted_key, encrypted_application_request)
24
24
  end
25
25
 
26
26
  # Encrypts a given symmetric encryption key with a public key and returns it in base64 encoded
@@ -60,7 +60,7 @@ module Sepa
60
60
  set_node(@template, 'bxd|Timestamp', iso_time)
61
61
  set_node(@template, 'bxd|Language', @language)
62
62
  set_node(@template, 'bxd|UserAgent', "Sepa Transfer Library version " + VERSION)
63
- set_node(@template, 'bxd|ReceiverId', @target_id)
63
+ set_node(@template, 'bxd|ReceiverId', "DABAFIHH")
64
64
  end
65
65
 
66
66
  def set_create_cert_contents
@@ -90,6 +90,7 @@ module Sepa
90
90
  end
91
91
 
92
92
  def build_certificate_request
93
+ @environment = :customertest if @environment == :test
93
94
  set_create_cert_contents
94
95
  encrypted_request = encrypt_application_request
95
96
  add_encrypted_request_to_soap(encrypted_request)
@@ -2,7 +2,7 @@ module Sepa
2
2
  class NordeaResponse < Response
3
3
  include Utilities
4
4
 
5
- def own_signing_cert
5
+ def own_signing_certificate
6
6
  application_response = extract_application_response(NORDEA_PKI)
7
7
  at = 'xmlns|Certificate > xmlns|Certificate'
8
8
  node = Nokogiri::XML(application_response).at(at, xmlns: NORDEA_XML_DATA)
@@ -11,9 +11,7 @@ module Sepa
11
11
 
12
12
  cert_value = process_cert_value node.content
13
13
  cert = x509_certificate cert_value
14
- cert_plain = cert.to_s
15
-
16
- encode cert_plain
14
+ cert.to_s
17
15
  end
18
16
 
19
17
  end
data/lib/sepa/client.rb CHANGED
@@ -5,13 +5,28 @@ module Sepa
5
5
  include ErrorMessages
6
6
  include AttributeChecks
7
7
 
8
- attr_accessor :bank, :cert, :command, :content, :customer_id, :enc_cert,
9
- :encryption_cert_pkcs10, :environment, :file_reference,
10
- :file_type, :key_generator_type, :language, :pin, :private_key,
11
- :signing_cert_pkcs10, :status, :target_id, :csr, :service, :bank_root_cert_serial
8
+ attr_accessor :bank,
9
+ :command,
10
+ :content,
11
+ :customer_id,
12
+ :target_id,
13
+ :environment,
14
+ :file_reference,
15
+ :file_type,
16
+ :language,
17
+ :status,
18
+ :pin,
19
+ :signing_private_key,
20
+ :signing_certificate,
21
+ :signing_csr,
22
+ :encryption_private_key,
23
+ :encryption_certificate,
24
+ :encryption_csr
12
25
 
13
26
  BANKS = [:nordea, :danske]
14
27
  LANGUAGES = ['FI', 'SE', 'EN']
28
+ ENVIRONMENTS = [:production, :test]
29
+ STATUSES = ['NEW', 'DOWNLOADED', 'ALL']
15
30
 
16
31
  validates :bank, inclusion: { in: BANKS }
17
32
  validates :language, inclusion: { in: LANGUAGES }, allow_nil: true
@@ -26,15 +41,15 @@ module Sepa
26
41
  validate :check_command
27
42
  validate :check_wsdl
28
43
  validate :check_keys
29
- validate :check_enc_cert
44
+ validate :check_encryption_certificate
30
45
  validate :check_encryption_cert_request
31
- validate :check_signing_cert
32
- validate :check_bank_root_cert_serial
46
+ validate :check_signing_csr
33
47
  validate :check_file_reference
48
+ validate :check_encryption_private_key
34
49
 
35
50
  def initialize(hash = {})
36
51
  self.attributes hash
37
- self.environment ||= 'PRODUCTION'
52
+ self.environment ||= :production
38
53
  self.language ||= 'EN'
39
54
  self.status ||= 'NEW'
40
55
  end
@@ -47,6 +62,10 @@ module Sepa
47
62
  @command = value.to_sym
48
63
  end
49
64
 
65
+ def environment=(value)
66
+ @environment = value.downcase.to_sym
67
+ end
68
+
50
69
  def attributes(hash)
51
70
  hash.each do |name, value|
52
71
  send("#{name}=", value)
@@ -72,6 +91,7 @@ module Sepa
72
91
  error: error,
73
92
  command: command
74
93
  }
94
+ options[:encryption_private_key] = rsa_key(encryption_private_key) if encryption_private_key
75
95
 
76
96
  case bank
77
97
  when :nordea
@@ -84,7 +104,7 @@ module Sepa
84
104
  private
85
105
 
86
106
  def create_hash
87
- initialize_private_key
107
+ initialize_signing_private_key
88
108
  iv = {}
89
109
 
90
110
  # Create hash of all instance variables
@@ -98,8 +118,8 @@ module Sepa
98
118
  iv
99
119
  end
100
120
 
101
- def initialize_private_key
102
- @private_key = OpenSSL::PKey::RSA.new(@private_key) if @private_key
121
+ def initialize_signing_private_key
122
+ @signing_private_key = rsa_key(@signing_private_key) if @signing_private_key
103
123
  end
104
124
 
105
125
  # Returns path to WSDL file
@@ -1,7 +1,7 @@
1
1
  module Sepa
2
2
  module ErrorMessages
3
3
  CUSTOMER_ID_ERROR_MESSAGE = 'Customer Id needs to be present and needs to have a length of less than 17 characters'
4
- ENVIRONMENT_ERROR_MESSAGE = 'Environment needs to be either PRODUCTION, TEST or customertest'
4
+ ENVIRONMENT_ERROR_MESSAGE = 'Environment needs to be either production or test'
5
5
  TARGET_ID_ERROR_MESSAGE = 'Target Id needs to be present and under 80 characters'
6
6
  FILE_TYPE_ERROR_MESSAGE = 'File type needs to be present and under 35 characters'
7
7
  CONTENT_ERROR_MESSAGE = 'Content needs to be present for this command'
@@ -11,5 +11,6 @@ module Sepa
11
11
  ENCRYPTION_CERT_ERROR_MESSAGE = 'Invalid encryption certificate'
12
12
  STATUS_ERROR_MESSAGE = 'Status is required for this command and must be either NEW, DOWNLOADED or ALL'
13
13
  FILE_REFERENCE_ERROR_MESSAGE = 'File reference is required for this command and must be under 33 characters'
14
+ ENCRYPTION_PRIVATE_KEY_ERROR_MESSAGE = 'Encryption private key is needed for this bank and this command'
14
15
  end
15
16
  end
data/lib/sepa/response.rb CHANGED
@@ -6,14 +6,15 @@ module Sepa
6
6
  attr_reader :soap, :error, :command
7
7
 
8
8
  validates :soap, presence: true
9
- validate :validate_document_format
10
- validate :document_must_validate_against_schema
11
- validate :client_errors
9
+ validate :validate_document_format
10
+ validate :document_must_validate_against_schema
11
+ validate :client_errors
12
12
 
13
13
  def initialize(hash = {})
14
14
  @soap = hash[:response]
15
15
  @command = hash[:command]
16
16
  @error = hash[:error]
17
+ @encryption_private_key = hash[:encryption_private_key]
17
18
  end
18
19
 
19
20
  def doc
@@ -108,6 +109,18 @@ module Sepa
108
109
  @soap
109
110
  end
110
111
 
112
+ def bank_encryption_certificate; end
113
+
114
+ def bank_signing_certificate; end
115
+
116
+ def bank_root_certificate; end
117
+
118
+ def own_encryption_certificate; end
119
+
120
+ def own_signing_certificate; end
121
+
122
+ def ca_certificate; end
123
+
111
124
  private
112
125
 
113
126
  # Finds all reference nodes with digest values in the document and returns
@@ -148,6 +161,8 @@ module Sepa
148
161
  end
149
162
 
150
163
  def document_must_validate_against_schema
164
+ return if command.to_sym == :get_bank_certificate
165
+
151
166
  check_validity_against_schema(doc, 'soap.xsd')
152
167
  end
153
168
 
@@ -6,23 +6,23 @@ module Sepa
6
6
 
7
7
  # SoapBuilder creates the SOAP structure.
8
8
  def initialize(params)
9
- @bank = params[:bank]
10
- @cert = params[:cert]
11
- @command = params[:command]
12
- @content = params[:content]
13
- @customer_id = params[:customer_id]
14
- @enc_cert = params[:enc_cert]
15
- @environment = params[:environment]
16
- @file_reference = params[:file_reference]
17
- @file_type = params[:file_type]
18
- @language = params[:language]
19
- @private_key = params[:private_key]
20
- @status = params[:status]
21
- @target_id = params[:target_id]
22
-
23
- @application_request = ApplicationRequest.new params
24
- @header_template = load_header_template
25
- @template = load_body_template SOAP_TEMPLATE_PATH
9
+ @bank = params[:bank]
10
+ @signing_certificate = params[:signing_certificate]
11
+ @command = params[:command]
12
+ @content = params[:content]
13
+ @customer_id = params[:customer_id]
14
+ @encryption_certificate = params[:encryption_certificate]
15
+ @environment = params[:environment]
16
+ @file_reference = params[:file_reference]
17
+ @file_type = params[:file_type]
18
+ @language = params[:language]
19
+ @signing_private_key = params[:signing_private_key]
20
+ @status = params[:status]
21
+ @target_id = params[:target_id]
22
+
23
+ @application_request = ApplicationRequest.new params
24
+ @header_template = load_header_template
25
+ @template = load_body_template SOAP_TEMPLATE_PATH
26
26
 
27
27
  find_correct_bank_extension
28
28
  end
@@ -64,7 +64,7 @@ module Sepa
64
64
  inclusive_namespaces = nil, with_comments = false
65
65
  )
66
66
 
67
- signature = @private_key.sign(sha1, canon_signed_info_node)
67
+ signature = @signing_private_key.sign(sha1, canon_signed_info_node)
68
68
  encode(signature).gsub(/\s+/, "")
69
69
  end
70
70
 
@@ -84,23 +84,54 @@ module Sepa
84
84
  end
85
85
 
86
86
  def process_header
87
+ set_token_id
88
+
87
89
  set_node(@header_template, 'wsu|Created', iso_time)
88
90
  set_node(@header_template, 'wsu|Expires', (Time.now.utc + 300).iso8601)
89
91
 
92
+ timestamp_id = set_timestamp_id
93
+
90
94
  timestamp_digest = calculate_digest(@header_template, 'wsu|Timestamp')
91
- dsig = 'dsig|Reference[URI="#dsfg8sdg87dsf678g6dsg6ds7fg"] dsig|DigestValue'
95
+ dsig = "dsig|Reference[URI='##{timestamp_id}'] dsig|DigestValue"
92
96
  set_node(@header_template, dsig, timestamp_digest)
93
97
 
98
+ body_id = set_body_id
99
+
94
100
  body_digest = calculate_digest(@template, 'env|Body')
95
- dsig = 'dsig|Reference[URI="#sdf6sa7d86f87s6df786sd87f6s8fsda"] dsig|DigestValue'
101
+ dsig = "dsig|Reference[URI='##{body_id}'] dsig|DigestValue"
96
102
  set_node(@header_template, dsig, body_digest)
97
103
 
98
104
  signature = calculate_signature(@header_template, 'dsig|SignedInfo')
99
105
  set_node(@header_template, 'dsig|SignatureValue', signature)
100
106
 
101
- formatted_cert = format_cert(@cert)
107
+ formatted_cert = format_cert(@signing_certificate)
102
108
  set_node(@header_template, 'wsse|BinarySecurityToken', formatted_cert)
103
109
  end
104
110
 
111
+ def set_token_id
112
+ security_token_id = "token-#{SecureRandom.uuid}"
113
+
114
+ @header_template.at('wsse|BinarySecurityToken')['wsu:Id'] = security_token_id
115
+ @header_template.at('wsse|Reference')['URI'] = "##{security_token_id}"
116
+ end
117
+
118
+ def set_timestamp_id
119
+ timestamp_id = "timestamp-#{SecureRandom.uuid}"
120
+
121
+ @header_template.at('wsu|Timestamp')['wsu:Id'] = timestamp_id
122
+ @header_template.css('dsig|Reference')[0]['URI'] = "##{timestamp_id}"
123
+
124
+ timestamp_id
125
+ end
126
+
127
+ def set_body_id
128
+ body_id = "body-#{SecureRandom.uuid}"
129
+
130
+ @template.at('env|Body')['wsu:Id'] = body_id
131
+ @header_template.css('dsig|Reference')[1]['URI'] = "##{body_id}"
132
+
133
+ body_id
134
+ end
135
+
105
136
  end
106
137
  end
@@ -143,5 +143,9 @@ module Sepa
143
143
  Base64.encode64 value
144
144
  end
145
145
 
146
+ def rsa_key(key_as_string)
147
+ OpenSSL::PKey::RSA.new key_as_string
148
+ end
149
+
146
150
  end
147
151
  end
data/lib/sepa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sepa
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -228,7 +228,7 @@
228
228
  </wsdl:binding>
229
229
  <wsdl:service name="CorporateFileService">
230
230
  <wsdl:port binding="tns:CorporateFileServiceHttpBinding" name="CorporateFileServiceHttpPort">
231
- <wsdlsoap:address location="https://businessWS.danskebank.com/edifileservice/edifileservice.asmx"/>
231
+ <wsdlsoap:address location="https://businessws.sampopankki.fi/edifileservice/edifileservice.asmx"/>
232
232
  </wsdl:port>
233
233
  </wsdl:service>
234
234
  </wsdl:definitions>
@@ -8,7 +8,6 @@
8
8
  <FileReferences>
9
9
  <FileReference></FileReference>
10
10
  </FileReferences>
11
- <TargetId></TargetId>
12
11
  <SoftwareId></SoftwareId>
13
12
  <FileType></FileType>
14
13
  <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">