epics 1.0.0

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 (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/CONTRIBUTING.md +5 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +165 -0
  8. data/README.md +197 -0
  9. data/Rakefile +7 -0
  10. data/epics.gemspec +50 -0
  11. data/lib/epics.rb +35 -0
  12. data/lib/epics/cct.rb +42 -0
  13. data/lib/epics/cd1.rb +42 -0
  14. data/lib/epics/cdd.rb +42 -0
  15. data/lib/epics/client.rb +216 -0
  16. data/lib/epics/error.rb +324 -0
  17. data/lib/epics/generic_request.rb +99 -0
  18. data/lib/epics/generic_upload_request.rb +89 -0
  19. data/lib/epics/haa.rb +40 -0
  20. data/lib/epics/hia.rb +78 -0
  21. data/lib/epics/hpb.rb +29 -0
  22. data/lib/epics/hpd.rb +40 -0
  23. data/lib/epics/htd.rb +40 -0
  24. data/lib/epics/ini.rb +69 -0
  25. data/lib/epics/key.rb +79 -0
  26. data/lib/epics/mgf.rb +41 -0
  27. data/lib/epics/middleware/parse_ebics.rb +15 -0
  28. data/lib/epics/middleware/xmlsig.rb +18 -0
  29. data/lib/epics/ptk.rb +52 -0
  30. data/lib/epics/response.rb +93 -0
  31. data/lib/epics/signer.rb +40 -0
  32. data/lib/epics/sta.rb +52 -0
  33. data/lib/epics/version.rb +3 -0
  34. data/lib/letter/ini.erb +231 -0
  35. data/spec/client_spec.rb +98 -0
  36. data/spec/fixtures/a006.pem +28 -0
  37. data/spec/fixtures/bank_e.pem +6 -0
  38. data/spec/fixtures/e002.pem +28 -0
  39. data/spec/fixtures/x002.pem +28 -0
  40. data/spec/fixtures/xml/cd1.xml +87 -0
  41. data/spec/fixtures/xml/ebics_business_nok.xml +21 -0
  42. data/spec/fixtures/xml/ebics_technical_nok.xml +12 -0
  43. data/spec/fixtures/xml/hia.xml +2 -0
  44. data/spec/fixtures/xml/hia_request_order_data.xml +2 -0
  45. data/spec/fixtures/xml/hpb.xml +34 -0
  46. data/spec/fixtures/xml/hpb_request.xml +34 -0
  47. data/spec/fixtures/xml/hpb_response.xml +21 -0
  48. data/spec/fixtures/xml/hpb_response_order.xml +22 -0
  49. data/spec/fixtures/xml/htd_order_data.xml +153 -0
  50. data/spec/fixtures/xml/ini.xml +2 -0
  51. data/spec/fixtures/xml/signature_pub_key_order_data.xml +2 -0
  52. data/spec/fixtures/xml/upload_init_response.xml +31 -0
  53. data/spec/hpb_spec.rb +15 -0
  54. data/spec/key_spec.rb +35 -0
  55. data/spec/mgf_spec.rb +36 -0
  56. data/spec/middleware/parse_ebics_spec.rb +18 -0
  57. data/spec/orders/cct_spec.rb +17 -0
  58. data/spec/orders/cd1_spec.rb +17 -0
  59. data/spec/orders/cdd_spec.rb +17 -0
  60. data/spec/orders/haa_spec.rb +11 -0
  61. data/spec/orders/hia_spec.rb +34 -0
  62. data/spec/orders/hpb_spec.rb +11 -0
  63. data/spec/orders/hpd_spec.rb +11 -0
  64. data/spec/orders/htd_spec.rb +11 -0
  65. data/spec/orders/ini_spec.rb +36 -0
  66. data/spec/orders/ptk_spec.rb +11 -0
  67. data/spec/orders/sta_spec.rb +11 -0
  68. data/spec/response_spec.rb +34 -0
  69. data/spec/signer_spec.rb +34 -0
  70. data/spec/spec_helper.rb +43 -0
  71. data/spec/support/ebics_matcher.rb +22 -0
  72. data/spec/xsd/ebics_H004.xsd +11 -0
  73. data/spec/xsd/ebics_hev.xsd +135 -0
  74. data/spec/xsd/ebics_keymgmt_request_H004.xsd +543 -0
  75. data/spec/xsd/ebics_keymgmt_response_H004.xsd +137 -0
  76. data/spec/xsd/ebics_orders_H004.xsd +1892 -0
  77. data/spec/xsd/ebics_request_H004.xsd +355 -0
  78. data/spec/xsd/ebics_response_H004.xsd +166 -0
  79. data/spec/xsd/ebics_signature.xsd +217 -0
  80. data/spec/xsd/ebics_types_H004.xsd +2426 -0
  81. data/spec/xsd/xmldsig-core-schema.xsd +318 -0
  82. metadata +319 -0
@@ -0,0 +1,99 @@
1
+ class Epics::GenericRequest
2
+ extend Forwardable
3
+ attr_accessor :client
4
+
5
+ def initialize(client)
6
+ self.client = client
7
+ end
8
+
9
+ def nonce
10
+ SecureRandom.hex(16)
11
+ end
12
+
13
+ def timestamp
14
+ Time.now.utc.iso8601
15
+ end
16
+
17
+ def_delegators :client, :host_id, :user_id, :partner_id
18
+
19
+ def root
20
+ "ebicsRequest"
21
+ end
22
+
23
+ def body
24
+ ""
25
+ end
26
+
27
+ def auth_signature
28
+ {
29
+ "ds:SignedInfo" => {
30
+ "ds:CanonicalizationMethod/" => {
31
+ :@Algorithm => "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
32
+ },
33
+ "ds:SignatureMethod/" => {
34
+ :@Algorithm => "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
35
+ },
36
+ "ds:Reference/" => {
37
+ :@URI => "#xpointer(//*[@authenticate='true'])",
38
+ "ds:Transforms" => {
39
+ "ds:Transform/" => {
40
+ :@Algorithm => "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
41
+ }
42
+ },
43
+ "ds:DigestMethod/" => {
44
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256"
45
+ },
46
+ "ds:DigestValue/" => ""
47
+ }
48
+ },
49
+ "ds:SignatureValue/" => ""
50
+ }
51
+ end
52
+
53
+ def to_transfer_xml
54
+ Nokogiri::XML.parse(Gyoku.xml({
55
+ root => {
56
+ :"@xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#",
57
+ :@xmlns => "urn:org:ebics:H004",
58
+ :@Version => "H004",
59
+ :@Revision => "1",
60
+ "header" => {
61
+ :@authenticate => true,
62
+ "static" => {
63
+ "HostID" => host_id,
64
+ "TransactionID" => transaction_id
65
+ },
66
+ "mutable" => {
67
+ "TransactionPhase" => "Transfer",
68
+ "SegmentNumber" => {
69
+ :@lastSegment => true,
70
+ :content! => 1
71
+ }
72
+ }
73
+ },
74
+ "AuthSignature" => auth_signature,
75
+ "body" => {
76
+ "DataTransfer" => {
77
+ "OrderData" => encrypted_order_data
78
+ }
79
+ }
80
+ }
81
+ }), nil, "utf-8").to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
82
+ end
83
+
84
+ def to_xml
85
+ Nokogiri::XML.parse(Gyoku.xml( {
86
+ root => {
87
+ :"@xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#",
88
+ :@xmlns => "urn:org:ebics:H004",
89
+ :@Version => "H004",
90
+ :@Revision => "1",
91
+ :header => header,
92
+ "AuthSignature" => auth_signature,
93
+ "body" => body
94
+ }
95
+ }), nil, "utf-8").to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
96
+ end
97
+
98
+
99
+ end
@@ -0,0 +1,89 @@
1
+ class Epics::GenericUploadRequest < Epics::GenericRequest
2
+
3
+ attr_accessor :key
4
+ attr_accessor :document
5
+ attr_accessor :transaction_id
6
+
7
+ def initialize(client, document)
8
+ super(client)
9
+ self.document = document
10
+ self.key ||= cipher.random_key
11
+ end
12
+
13
+ def cipher
14
+ @cipher ||= OpenSSL::Cipher::Cipher.new("aes-128-cbc")
15
+ end
16
+
17
+ def digester
18
+ @digester ||= OpenSSL::Digest::SHA256.new
19
+ end
20
+
21
+ def body
22
+ {
23
+ "DataTransfer" => {
24
+ "DataEncryptionInfo" => {
25
+ :@authenticate => true,
26
+ "EncryptionPubKeyDigest" => {
27
+ :"@Version" => "E002",
28
+ :"@Algorithm" => "http://www.w3.org/2001/04/xmlenc#sha256",
29
+ :content! => client.bank_e.public_digest
30
+ },
31
+ "TransactionKey" => Base64.encode64(client.bank_e.key.public_encrypt(self.key)).gsub(/\n/,'')
32
+ },
33
+ "SignatureData" => {
34
+ :@authenticate => true,
35
+ :content! => encrypted_order_signature
36
+ }
37
+ }
38
+ }
39
+ end
40
+
41
+ def order_signature
42
+ Gyoku.xml("UserSignatureData" => {
43
+ :"@xmlns" => "http://www.ebics.org/S001",
44
+ :"@xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
45
+ :"@xsi:schemaLocation" => "http://www.ebics.org/S001 http://www.ebics.org/S001/ebics_signature.xsd",
46
+ "OrderSignatureData" => {
47
+ "SignatureVersion" => "A006",
48
+ "SignatureValue" => signature_value,
49
+ "PartnerID" => partner_id,
50
+ "UserID" => user_id
51
+ }
52
+ })
53
+ end
54
+
55
+ def signature_value
56
+ Base64.encode64(client.a.sign( digester.digest(document.gsub(/\n|\r/, "")) )).gsub(/\n/, "")
57
+ end
58
+
59
+ def encrypt(d)
60
+ cipher.encrypt
61
+ cipher.padding = 0
62
+ cipher.key = self.key
63
+ (cipher.update(pad(d)) + cipher.final)
64
+ end
65
+
66
+ def encrypted_order_data
67
+ dst = Zlib::Deflate.deflate(document)
68
+
69
+ Base64.encode64(encrypt(dst)).gsub(/\n/,'')
70
+ end
71
+
72
+ def encrypted_order_signature
73
+ dst = Zlib::Deflate.deflate(order_signature)
74
+
75
+ Base64.encode64(encrypt(dst)).gsub(/\n/,'')
76
+ end
77
+
78
+ def pad(d)
79
+ if d.size % 32 == 0
80
+ return d
81
+ else
82
+ len = 32*((d.size / 32)+1)
83
+ padded = d.ljust(len, "\x01")
84
+ padded[-1] = ["#{len - d.size}".rjust(2, "0")].pack("*H")
85
+ padded
86
+ end
87
+ end
88
+
89
+ end
data/lib/epics/haa.rb ADDED
@@ -0,0 +1,40 @@
1
+ class Epics::HAA < Epics::GenericRequest
2
+
3
+ def header
4
+ {
5
+ :@authenticate => true,
6
+ static: {
7
+ "HostID" => host_id,
8
+ "Nonce" => nonce,
9
+ "Timestamp" => timestamp,
10
+ "PartnerID" => partner_id,
11
+ "UserID" => user_id,
12
+ "Product" => {
13
+ :@Language => "de",
14
+ :content! => "EPICS - a ruby ebics kernel"
15
+ },
16
+ "OrderDetails" => {
17
+ "OrderType" => "HAA",
18
+ "OrderAttribute" => "DZHNN",
19
+ "StandardOrderParams/" => ""
20
+ },
21
+ "BankPubKeyDigests" => {
22
+ "Authentication" => {
23
+ :@Version => "X002",
24
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256",
25
+ :content! => client.bank_x.public_digest
26
+ },
27
+ "Encryption" => {
28
+ :@Version => "E002",
29
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256",
30
+ :content! => client.bank_e.public_digest
31
+ }
32
+ },
33
+ "SecurityMedium" => "0000"
34
+ },
35
+ "mutable" => {
36
+ "TransactionPhase" => "Initialisation"
37
+ }
38
+ }
39
+ end
40
+ end
data/lib/epics/hia.rb ADDED
@@ -0,0 +1,78 @@
1
+ class Epics::HIA < Epics::GenericRequest
2
+
3
+ def root
4
+ "ebicsUnsecuredRequest"
5
+ end
6
+
7
+ def header
8
+ {
9
+ :@authenticate => true,
10
+ static: {
11
+ "HostID" => host_id,
12
+ "PartnerID" => partner_id,
13
+ "UserID" => user_id,
14
+ "Product" => {
15
+ :@Language => "de",
16
+ :content! => "EPICS - a ruby ebics kernel"
17
+ },
18
+ "OrderDetails" => {
19
+ "OrderType" => "HIA",
20
+ "OrderAttribute" => "DZNNN"
21
+ },
22
+ "SecurityMedium" => "0000"
23
+ },
24
+ "mutable" => ""
25
+ }
26
+ end
27
+
28
+ def body
29
+ {
30
+ "DataTransfer" => {
31
+ "OrderData" => Base64.strict_encode64(Zlib::Deflate.deflate(order_data))
32
+ }
33
+ }
34
+ end
35
+
36
+ def order_data
37
+ "<?xml version='1.0' encoding='utf-8'?>\n"+
38
+ Gyoku.xml("HIARequestOrderData" => {
39
+ :"@xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#",
40
+ :"@xmlns" => "urn:org:ebics:H004",
41
+ "AuthenticationPubKeyInfo" => {
42
+ "PubKeyValue" => {
43
+ "ds:RSAKeyValue" => {
44
+ "ds:Modulus" => Base64.strict_encode64([client.x.n].pack("H*")),
45
+ "ds:Exponent" => Base64.strict_encode64(client.x.key.e.to_s(2))
46
+ }
47
+ },
48
+ "AuthenticationVersion" => "X002"
49
+ },
50
+ "EncryptionPubKeyInfo" => {
51
+ "PubKeyValue" => {
52
+ "ds:RSAKeyValue" => {
53
+ "ds:Modulus" => Base64.strict_encode64([client.e.n].pack("H*")),
54
+ "ds:Exponent" => Base64.strict_encode64(client.e.key.e.to_s(2))
55
+ }
56
+ },
57
+ "EncryptionVersion" => "E002"
58
+ },
59
+
60
+ "PartnerID" => partner_id,
61
+ "UserID" => user_id
62
+ })
63
+ end
64
+
65
+ def to_xml
66
+ Nokogiri::XML.parse(Gyoku.xml( {
67
+ root => {
68
+ :"@xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#",
69
+ :@xmlns => "urn:org:ebics:H004",
70
+ :@Version => "H004",
71
+ :@Revision => "1",
72
+ :header => header,
73
+ "body" => body
74
+ }
75
+ }), nil, "utf-8").to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
76
+ end
77
+
78
+ end
data/lib/epics/hpb.rb ADDED
@@ -0,0 +1,29 @@
1
+ class Epics::HPB < Epics::GenericRequest
2
+
3
+ def root
4
+ "ebicsNoPubKeyDigestsRequest"
5
+ end
6
+
7
+ def header
8
+ {
9
+ :@authenticate => true,
10
+ static: {
11
+ "HostID" => host_id,
12
+ "Nonce" => nonce,
13
+ "Timestamp" => timestamp,
14
+ "PartnerID" => partner_id,
15
+ "UserID" => user_id,
16
+ "Product" => {
17
+ :@Language => "de",
18
+ :content! => "EPICS - a ruby ebics kernel"
19
+ },
20
+ "OrderDetails" => {
21
+ "OrderType" => "HPB",
22
+ "OrderAttribute" => "DZHNN"
23
+ },
24
+ "SecurityMedium" => "0000"
25
+ },
26
+ "mutable/" => ""
27
+ }
28
+ end
29
+ end
data/lib/epics/hpd.rb ADDED
@@ -0,0 +1,40 @@
1
+ class Epics::HPD < Epics::GenericRequest
2
+
3
+ def header
4
+ {
5
+ :@authenticate => true,
6
+ static: {
7
+ "HostID" => host_id,
8
+ "Nonce" => nonce,
9
+ "Timestamp" => timestamp,
10
+ "PartnerID" => partner_id,
11
+ "UserID" => user_id,
12
+ "Product" => {
13
+ :@Language => "de",
14
+ :content! => "EPICS - a ruby ebics kernel"
15
+ },
16
+ "OrderDetails" => {
17
+ "OrderType" => "HPD",
18
+ "OrderAttribute" => "DZHNN",
19
+ "StandardOrderParams/" => ""
20
+ },
21
+ "BankPubKeyDigests" => {
22
+ "Authentication" => {
23
+ :@Version => "X002",
24
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256",
25
+ :content! => client.bank_x.public_digest
26
+ },
27
+ "Encryption" => {
28
+ :@Version => "E002",
29
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256",
30
+ :content! => client.bank_e.public_digest
31
+ }
32
+ },
33
+ "SecurityMedium" => "0000"
34
+ },
35
+ "mutable" => {
36
+ "TransactionPhase" => "Initialisation"
37
+ }
38
+ }
39
+ end
40
+ end
data/lib/epics/htd.rb ADDED
@@ -0,0 +1,40 @@
1
+ class Epics::HTD < Epics::GenericRequest
2
+
3
+ def header
4
+ {
5
+ :@authenticate => true,
6
+ static: {
7
+ "HostID" => host_id,
8
+ "Nonce" => nonce,
9
+ "Timestamp" => timestamp,
10
+ "PartnerID" => partner_id,
11
+ "UserID" => user_id,
12
+ "Product" => {
13
+ :@Language => "de",
14
+ :content! => "EPICS - a ruby ebics kernel"
15
+ },
16
+ "OrderDetails" => {
17
+ "OrderType" => "HTD",
18
+ "OrderAttribute" => "DZHNN",
19
+ "StandardOrderParams/" => ""
20
+ },
21
+ "BankPubKeyDigests" => {
22
+ "Authentication" => {
23
+ :@Version => "X002",
24
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256",
25
+ :content! => client.bank_x.public_digest
26
+ },
27
+ "Encryption" => {
28
+ :@Version => "E002",
29
+ :@Algorithm => "http://www.w3.org/2001/04/xmlenc#sha256",
30
+ :content! => client.bank_e.public_digest
31
+ }
32
+ },
33
+ "SecurityMedium" => "0000"
34
+ },
35
+ "mutable" => {
36
+ "TransactionPhase" => "Initialisation"
37
+ }
38
+ }
39
+ end
40
+ end
data/lib/epics/ini.rb ADDED
@@ -0,0 +1,69 @@
1
+ class Epics::INI < Epics::GenericRequest
2
+
3
+ def root
4
+ "ebicsUnsecuredRequest"
5
+ end
6
+
7
+ def header
8
+ {
9
+ :@authenticate => true,
10
+ static: {
11
+ "HostID" => host_id,
12
+ "PartnerID" => partner_id,
13
+ "UserID" => user_id,
14
+ "Product" => {
15
+ :@Language => "de",
16
+ :content! => "EPICS - a ruby ebics kernel"
17
+ },
18
+ "OrderDetails" => {
19
+ "OrderType" => "INI",
20
+ "OrderAttribute" => "DZNNN"
21
+ },
22
+ "SecurityMedium" => "0000"
23
+ },
24
+ "mutable" => ""
25
+ }
26
+ end
27
+
28
+ def body
29
+ {
30
+ "DataTransfer" => {
31
+ "OrderData" => Base64.strict_encode64(Zlib::Deflate.deflate(key_signature))
32
+ }
33
+ }
34
+ end
35
+
36
+ def key_signature
37
+ "<?xml version='1.0' encoding='utf-8'?>\n"+
38
+ Gyoku.xml("SignaturePubKeyOrderData" => {
39
+ :"@xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#",
40
+ :"@xmlns" => "http://www.ebics.org/S001",
41
+ "SignaturePubKeyInfo" => {
42
+ "PubKeyValue" => {
43
+ "ds:RSAKeyValue" => {
44
+ "ds:Modulus" => Base64.strict_encode64([client.a.n].pack("H*")),
45
+ "ds:Exponent" => Base64.strict_encode64(client.a.key.e.to_s(2))
46
+ },
47
+ "TimeStamp" => timestamp
48
+ },
49
+ "SignatureVersion" => "A006"
50
+ },
51
+ "PartnerID" => partner_id,
52
+ "UserID" => user_id
53
+ })
54
+ end
55
+
56
+ def to_xml
57
+ Nokogiri::XML.parse(Gyoku.xml( {
58
+ root => {
59
+ :"@xmlns:ds" => "http://www.w3.org/2000/09/xmldsig#",
60
+ :@xmlns => "urn:org:ebics:H004",
61
+ :@Version => "H004",
62
+ :@Revision => "1",
63
+ :header => header,
64
+ "body" => body
65
+ }
66
+ }), nil, "utf-8").to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
67
+ end
68
+
69
+ end