sepafm 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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#">