sepafm 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8fbb8495a8ef64c200672b7b95856c63373e4d2
4
- data.tar.gz: 0d89865ffa9d69de4c25252ead68e6865d99d326
3
+ metadata.gz: bd61a928b1047406c415f8e76b8dddbd8f303ca8
4
+ data.tar.gz: 999e4c7a9d47219e5a22907cf59d85e9921ff4b7
5
5
  SHA512:
6
- metadata.gz: 229d1763748a90cbc02c9d2395c2b7d8737fdc584d68c97c96becca0aecca888780a72e4f73067a86c3bf1307e3812535e472b1912bf0a0c4ea06d6235a1501b
7
- data.tar.gz: 12e4f735a16657b501354349d886f6e52e88a9a8e2e33b4567d83b23107f347983e73c0d943c100a856be1b71171dfb057990ad60bca7fa27cc6844febc1039e
6
+ metadata.gz: 0c0e5960cc2e6a0941533fae597be7a041b8f4274a3eec0b92b69b9ca84bc5d69c5eb456f8049ecce39f87060a564cd32e1f2ab50426bb10c55e27bd77f1e732
7
+ data.tar.gz: 1e27582d39e099255357ffd6068bee42521e385e4410565cfbc9ff467c4b94eea80c39781aad39b7144144c465054915ef46f02be476d403905890a1185c57e2
@@ -8,18 +8,18 @@ module Sepa
8
8
  instance_variable_set("@#{key}", value)
9
9
  end
10
10
 
11
- @ar = load_body_template AR_TEMPLATE_PATH
11
+ @application_request = load_body_template AR_TEMPLATE_PATH
12
12
  end
13
13
 
14
14
  def to_xml
15
15
  set_common_nodes
16
16
  set_nodes_contents
17
17
  process_signature
18
- @ar.to_xml
18
+ @application_request.to_xml
19
19
  end
20
20
 
21
21
  def to_base64
22
- Base64.encode64(to_xml)
22
+ encode to_xml
23
23
  end
24
24
 
25
25
  def to_nokogiri
@@ -29,11 +29,11 @@ module Sepa
29
29
  private
30
30
 
31
31
  def set_node(node, value)
32
- @ar.at_css(node).content = value
32
+ @application_request.at_css(node).content = value
33
33
  end
34
34
 
35
35
  def set_node_b(node, value)
36
- set_node node, Base64.encode64(value)
36
+ set_node node, encode(value)
37
37
  end
38
38
 
39
39
  def pretty_command
@@ -109,28 +109,30 @@ module Sepa
109
109
  end
110
110
 
111
111
  def remove_node(node, xmlns)
112
- @ar.at_css("xmlns|#{node}", 'xmlns' => xmlns).remove
112
+ @application_request.at_css("xmlns|#{node}", 'xmlns' => xmlns).remove
113
113
  end
114
114
 
115
115
  def add_node_to_root(node)
116
- @ar.root.add_child(node)
116
+ @application_request.root.add_child(node)
117
117
  end
118
118
 
119
119
  def calculate_digest
120
120
  sha1 = OpenSSL::Digest::SHA1.new
121
- Base64.encode64(sha1.digest(@ar.canonicalize))
121
+ encode(sha1.digest(@application_request.canonicalize))
122
122
  end
123
123
 
124
124
  def add_value_to_signature(node, value)
125
- sig = @ar.at_css("dsig|#{node}", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#')
125
+ dsig = 'http://www.w3.org/2000/09/xmldsig#'
126
+ sig = @application_request.at_css("dsig|#{node}", 'dsig' => dsig)
126
127
  sig.content = value
127
128
  end
128
129
 
129
130
  def calculate_signature
130
131
  sha1 = OpenSSL::Digest::SHA1.new
131
- node = @ar.at_css("dsig|SignedInfo", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#')
132
+ dsig = 'http://www.w3.org/2000/09/xmldsig#'
133
+ node = @application_request.at_css("dsig|SignedInfo", 'dsig' => dsig)
132
134
  signature = @private_key.sign(sha1, node.canonicalize)
133
- Base64.encode64(signature)
135
+ encode signature
134
136
  end
135
137
 
136
138
  def process_signature
@@ -3,29 +3,26 @@ module Sepa
3
3
  include ActiveModel::Validations
4
4
  include Utilities
5
5
 
6
- attr_accessor :ar, :certificate
6
+ attr_reader :xml
7
7
 
8
8
  validate :response_must_validate_against_schema
9
9
  validate :validate_document_format
10
10
 
11
11
  def initialize(app_resp)
12
- self.ar = app_resp
13
- self.certificate = extract_cert(ar, 'X509Certificate', 'http://www.w3.org/2000/09/xmldsig#')
12
+ @xml = app_resp
13
+ end
14
+
15
+ def doc
16
+ @doc ||= xml_doc @xml
14
17
  end
15
18
 
16
19
  # Checks that the hash value reported in the signature matches the actual one.
17
20
  def hashes_match?
18
- are = ar.clone
21
+ are = doc.clone
19
22
 
20
- digest_value = are.at_css(
21
- 'xmlns|DigestValue',
22
- 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
23
- ).content.strip
23
+ digest_value = are.at('xmlns|DigestValue', xmlns: DSIG).content.strip
24
24
 
25
- are.at_css(
26
- "xmlns|Signature",
27
- 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
28
- ).remove
25
+ are.at('xmlns|Signature', xmlns: DSIG).remove
29
26
 
30
27
  actual_digest = calculate_digest(are)
31
28
 
@@ -36,31 +33,34 @@ module Sepa
36
33
 
37
34
  # Checks that the signature is signed with the private key of the certificate's public key.
38
35
  def signature_is_valid?
39
- node = ar.at_css('xmlns|SignedInfo', 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#')
40
-
36
+ node = doc.at('xmlns|SignedInfo', 'xmlns' => DSIG)
41
37
  node = node.canonicalize
42
38
 
43
- signature = ar.at_css(
44
- 'xmlns|SignatureValue',
45
- 'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
46
- ).content
47
-
48
- signature = Base64.decode64(signature)
39
+ signature = doc.at('xmlns|SignatureValue', 'xmlns' => DSIG).content
40
+ signature = decode(signature)
49
41
 
50
42
  # Return true or false
51
43
  certificate.public_key.verify(OpenSSL::Digest::SHA1.new, signature, node)
52
44
  end
53
45
 
46
+ def to_s
47
+ @xml
48
+ end
49
+
50
+ def certificate
51
+ extract_cert(doc, 'X509Certificate', DSIG)
52
+ end
53
+
54
54
  private
55
55
 
56
56
  def validate_document_format
57
- unless ar.respond_to?(:canonicalize)
58
- errors.add(:base, 'Document must be a Nokogiri XML file')
57
+ unless doc.respond_to?(:canonicalize)
58
+ errors.add(:base, 'Document must be a valid XML file')
59
59
  end
60
60
  end
61
61
 
62
62
  def response_must_validate_against_schema
63
- check_validity_against_schema(ar, 'application_response.xsd')
63
+ check_validity_against_schema(doc, 'application_response.xsd')
64
64
  end
65
65
 
66
66
  end
@@ -50,27 +50,6 @@ module Sepa
50
50
  end
51
51
  end
52
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
53
  def check_wsdl
75
54
  return unless wsdl.present?
76
55
 
@@ -1,19 +1,45 @@
1
1
  module Sepa
2
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)
3
+
4
+ def bank_encryption_cert
5
+ @bank_encryption_cert ||= extract_cert(doc, 'BankEncryptionCert', DANSKE_PKI)
6
+ end
7
+
8
+ def bank_signing_cert
9
+ @bank_signing_cert ||= extract_cert(doc, 'BankSigningCert', DANSKE_PKI)
10
+ end
11
+
12
+ def bank_root_cert
13
+ @bank_root_cert ||= extract_cert(doc, 'BankRootCert', DANSKE_PKI)
14
+ end
15
+
16
+ def own_encryption_cert
17
+ @own_encryption_cert ||= extract_cert(doc, 'EncryptionCert', DANSKE_PKI)
18
+ end
19
+
20
+ def own_signing_cert
21
+ @own_signing_cert ||= extract_cert(doc, 'SigningCert', DANSKE_PKI)
22
+ end
23
+
24
+ def ca_certificate
25
+ @ca_certificate ||= extract_cert(doc, 'CACert', DANSKE_PKI)
26
+ end
27
+
28
+ def certificate
29
+ if @command == :create_certificate
30
+ @certificate ||= begin
31
+ extract_cert(doc, 'X509Certificate', DSIG)
32
+ end
33
+ end
17
34
  end
35
+
36
+ private
37
+
38
+ def find_node_by_uri(uri)
39
+ node = doc.at("[xml|id='#{uri}']")
40
+ node.at('xmlns|Signature', xmlns: DSIG).remove
41
+ node
42
+ end
43
+
18
44
  end
19
45
  end
@@ -1,132 +1,134 @@
1
1
  module Sepa
2
2
  module DanskeSoapRequest
3
3
 
4
- def find_correct_build
5
- case @command
6
- when :create_certificate
7
- build_certificate_request
8
- when :upload_file, :download_file, :get_user_info, :download_file_list
9
- build_danske_generic_request
10
- when :get_bank_certificate
11
- build_get_bank_certificate_request
4
+ private
5
+
6
+ def find_correct_build
7
+ case @command
8
+ when :create_certificate
9
+ build_certificate_request
10
+ when :upload_file, :download_file, :get_user_info, :download_file_list
11
+ build_danske_generic_request
12
+ when :get_bank_certificate
13
+ build_get_bank_certificate_request
14
+ end
15
+ end
16
+
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
22
+ encrypted_key = encrypt_key(key, encryption_public_key)
23
+ build_encrypted_ar(encryption_cert, encrypted_key, encrypted_ar)
24
+ end
25
+
26
+ # Encrypts a given symmetric encryption key with a public key and returns it in base64 encoded
27
+ # format
28
+ def encrypt_key(key, public_key)
29
+ encrypted_key = public_key.public_encrypt(key)
30
+ encode encrypted_key
31
+ end
32
+
33
+ # Encrypts the application request and returns it in base64 encoded format.
34
+ # Also returns the key needed to decrypt it
35
+ def encrypt_ar
36
+ cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
37
+
38
+ key = cipher.random_key
39
+ iv = cipher.random_iv
40
+
41
+ encrypted_data = cipher.update(@application_request.to_xml)
42
+ encrypted_data << cipher.final
43
+ encrypted_data = iv + encrypted_data
44
+ encrypted_data = encode encrypted_data
45
+
46
+ return encrypted_data, key
47
+ end
48
+
49
+ def build_encrypted_ar(cert, encrypted_data, encrypted_key)
50
+ ar = Nokogiri::XML File.open "#{AR_TEMPLATE_PATH}/encrypted_request.xml"
51
+ set_node(ar, 'dsig|X509Certificate', cert)
52
+ set_node(ar, 'dsig|KeyInfo xenc|CipherValue', encrypted_data)
53
+ set_node(ar, 'xenc|EncryptedData > xenc|CipherData > xenc|CipherValue', encrypted_key)
54
+ ar
55
+ end
56
+
57
+ def set_generic_request_contents
58
+ set_node(@template, 'bxd|SenderId', @customer_id)
59
+ set_node(@template, 'bxd|RequestId', request_id)
60
+ set_node(@template, 'bxd|Timestamp', iso_time)
61
+ set_node(@template, 'bxd|Language', @language)
62
+ set_node(@template, 'bxd|UserAgent', "Sepa Transfer Library version " + VERSION)
63
+ set_node(@template, 'bxd|ReceiverId', @target_id)
64
+ end
65
+
66
+ def set_create_cert_contents
67
+ set_node(@template, 'pkif|SenderId', @customer_id)
68
+ set_node(@template, 'pkif|CustomerId', @customer_id)
69
+ set_node(@template, 'pkif|RequestId', request_id)
70
+ set_node(@template, 'pkif|Timestamp', iso_time)
71
+ set_node(@template, 'pkif|InterfaceVersion', 1)
72
+ set_node(@template, 'pkif|Environment', @environment)
73
+ end
74
+
75
+ def set_bank_certificate_contents
76
+ set_node(@template, 'pkif|SenderId', @customer_id)
77
+ set_node(@template, 'pkif|CustomerId', @customer_id)
78
+ set_node(@template, 'pkif|RequestId', request_id)
79
+ set_node(@template, 'pkif|Timestamp', iso_time)
80
+ set_node(@template, 'pkif|InterfaceVersion', 1)
81
+ end
82
+
83
+ def build_danske_generic_request
84
+ set_generic_request_contents
85
+ encrypted_request = encrypt_application_request
86
+ add_encrypted_generic_request_to_soap(encrypted_request)
87
+
88
+ process_header
89
+ add_body_to_header
90
+ end
91
+
92
+ def build_certificate_request
93
+ set_create_cert_contents
94
+ encrypted_request = encrypt_application_request
95
+ add_encrypted_request_to_soap(encrypted_request)
96
+ end
97
+
98
+ def build_get_bank_certificate_request
99
+ set_bank_certificate_contents
100
+ add_bank_certificate_body_to_soap
101
+ end
102
+
103
+ def add_encrypted_request_to_soap(encrypted_request)
104
+ encrypted_request = Nokogiri::XML(encrypted_request.to_xml)
105
+ encrypted_request = encrypted_request.root
106
+ @template.at_css('pkif|CreateCertificateIn').add_child(encrypted_request)
107
+
108
+ @template
109
+ end
110
+
111
+ def add_encrypted_generic_request_to_soap(encrypted_request)
112
+ encrypted_request = Nokogiri::XML(encrypted_request.to_xml)
113
+ encrypted_request = encrypted_request.root
114
+ encrypted_request = encode encrypted_request.to_xml
115
+ @template.at_css('bxd|ApplicationRequest').add_child(encrypted_request)
116
+
117
+ @template
118
+ end
119
+
120
+ def add_bank_certificate_body_to_soap
121
+ ar = @application_request.to_nokogiri
122
+
123
+ ar = ar.at_css('elem|GetBankCertificateRequest')
124
+ @template.at_css('pkif|GetBankCertificateIn').add_child(ar)
125
+
126
+ @template
127
+ end
128
+
129
+ def request_id
130
+ SecureRandom.hex(5)
12
131
  end
13
- end
14
-
15
- def encrypt_application_request
16
- encryption_cert = OpenSSL::X509::Certificate.new(@enc_cert)
17
- encryption_public_key = encryption_cert.public_key
18
- encryption_cert = format_cert(encryption_cert)
19
- encrypted_ar, key = encrypt_ar
20
- encrypted_key = encrypt_key(key, encryption_public_key)
21
- build_encrypted_ar(encryption_cert, encrypted_key, encrypted_ar)
22
- end
23
-
24
- # Encrypts a given symmetric encryption key with a public key and returns it in base64 encoded
25
- # format
26
- def encrypt_key(key, public_key)
27
- encrypted_key = public_key.public_encrypt(key)
28
- Base64.encode64(encrypted_key)
29
- end
30
-
31
- # Encrypts the application request and returns it in base64 encoded format.
32
- # Also returns the key needed to decrypt it
33
- def encrypt_ar
34
- cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
35
-
36
- key = cipher.random_key
37
- iv = cipher.random_iv
38
-
39
- encrypted_data = cipher.update(@ar.to_xml)
40
- encrypted_data << cipher.final
41
- encrypted_data = iv + encrypted_data
42
- encrypted_data = Base64.encode64(encrypted_data)
43
-
44
- return encrypted_data, key
45
- end
46
-
47
- def build_encrypted_ar(cert, encrypted_data, encrypted_key)
48
- ar = Nokogiri::XML File.open "#{AR_TEMPLATE_PATH}/encrypted_request.xml"
49
- set_node(ar, 'dsig|X509Certificate', cert)
50
- set_node(ar, 'dsig|KeyInfo xenc|CipherValue', encrypted_data)
51
- set_node(ar, 'xenc|EncryptedData > xenc|CipherData > xenc|CipherValue', encrypted_key)
52
- ar
53
- end
54
-
55
- def set_generic_request_contents
56
- set_node(@template, 'bxd|SenderId', @customer_id)
57
- set_node(@template, 'bxd|RequestId', request_id)
58
- set_node(@template, 'bxd|Timestamp', iso_time)
59
- set_node(@template, 'bxd|Language', @language)
60
- set_node(@template, 'bxd|UserAgent', "Sepa Transfer Library version " + VERSION)
61
- set_node(@template, 'bxd|ReceiverId', @target_id)
62
- end
63
-
64
- def set_create_cert_contents
65
- set_node(@template, 'pkif|SenderId', @customer_id)
66
- set_node(@template, 'pkif|CustomerId', @customer_id)
67
- set_node(@template, 'pkif|RequestId', request_id)
68
- set_node(@template, 'pkif|Timestamp', iso_time)
69
- set_node(@template, 'pkif|InterfaceVersion', 1)
70
- set_node(@template, 'pkif|Environment', @environment)
71
- end
72
-
73
- def set_bank_certificate_contents
74
- set_node(@template, 'pkif|SenderId', @customer_id)
75
- set_node(@template, 'pkif|CustomerId', @customer_id)
76
- set_node(@template, 'pkif|RequestId', request_id)
77
- set_node(@template, 'pkif|Timestamp', iso_time)
78
- set_node(@template, 'pkif|InterfaceVersion', 1)
79
- end
80
-
81
- def build_danske_generic_request
82
- set_generic_request_contents
83
- encrypted_request = encrypt_application_request
84
- add_encrypted_generic_request_to_soap(encrypted_request)
85
-
86
- process_header
87
- add_body_to_header
88
- end
89
-
90
- def build_certificate_request
91
- set_create_cert_contents
92
- encrypted_request = encrypt_application_request
93
- add_encrypted_request_to_soap(encrypted_request)
94
- end
95
-
96
- def build_get_bank_certificate_request
97
- set_bank_certificate_contents
98
- add_bank_certificate_body_to_soap
99
- end
100
-
101
- def add_encrypted_request_to_soap(encrypted_request)
102
- encrypted_request = Nokogiri::XML(encrypted_request.to_xml)
103
- encrypted_request = encrypted_request.root
104
- @template.at_css('pkif|CreateCertificateIn').add_child(encrypted_request)
105
-
106
- @template
107
- end
108
-
109
- def add_encrypted_generic_request_to_soap(encrypted_request)
110
- encrypted_request = Nokogiri::XML(encrypted_request.to_xml)
111
- encrypted_request = encrypted_request.root
112
- encrypted_request = Base64.encode64(encrypted_request.to_xml)
113
- @template.at_css('bxd|ApplicationRequest').add_child(encrypted_request)
114
-
115
- @template
116
- end
117
-
118
- def add_bank_certificate_body_to_soap
119
- ar = @ar.to_nokogiri
120
-
121
- ar = ar.at_css('elem|GetBankCertificateRequest')
122
- @template.at_css('pkif|GetBankCertificateIn').add_child(ar)
123
-
124
- @template
125
- end
126
-
127
- def request_id
128
- SecureRandom.hex(5)
129
- end
130
132
 
131
133
  end
132
134
  end