epics 2.10.0 → 3.0.0.rc1

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 (245) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.semaphore/semaphore.yml +17 -8
  4. data/CHANGELOG.md +97 -0
  5. data/EBICS_REFERENCES.md +169 -0
  6. data/README.md +219 -50
  7. data/lib/epics/azv.rb +3 -10
  8. data/lib/epics/b2b.rb +3 -10
  9. data/lib/epics/bka.rb +3 -14
  10. data/lib/epics/builders/body_builder/base.rb +26 -0
  11. data/lib/epics/builders/body_builder/v2.rb +9 -0
  12. data/lib/epics/builders/body_builder/v3.rb +9 -0
  13. data/lib/epics/builders/body_builder.rb +6 -0
  14. data/lib/epics/builders/data_encryption_info_builder.rb +29 -0
  15. data/lib/epics/builders/data_transfer_builder/base.rb +52 -0
  16. data/lib/epics/builders/data_transfer_builder/v2.rb +9 -0
  17. data/lib/epics/builders/data_transfer_builder/v3.rb +12 -0
  18. data/lib/epics/builders/data_transfer_builder.rb +6 -0
  19. data/lib/epics/builders/header_builder/base.rb +26 -0
  20. data/lib/epics/builders/header_builder/v2.rb +9 -0
  21. data/lib/epics/builders/header_builder/v3.rb +9 -0
  22. data/lib/epics/builders/header_builder.rb +6 -0
  23. data/lib/epics/builders/mutable_builder.rb +28 -0
  24. data/lib/epics/builders/order_details_builder/base.rb +100 -0
  25. data/lib/epics/builders/order_details_builder/v2.rb +21 -0
  26. data/lib/epics/builders/order_details_builder/v3.rb +51 -0
  27. data/lib/epics/builders/order_details_builder.rb +10 -0
  28. data/lib/epics/builders/request_builder.rb +25 -0
  29. data/lib/epics/builders/static_builder/base.rb +75 -0
  30. data/lib/epics/builders/static_builder/v2.rb +9 -0
  31. data/lib/epics/builders/static_builder/v3.rb +9 -0
  32. data/lib/epics/builders/static_builder.rb +9 -0
  33. data/lib/epics/builders/transfer_receipt_builder.rb +19 -0
  34. data/lib/epics/builders/xml_builder/base.rb +92 -0
  35. data/lib/epics/builders/xml_builder/v24.rb +31 -0
  36. data/lib/epics/builders/xml_builder/v25.rb +31 -0
  37. data/lib/epics/builders/xml_builder/v3.rb +31 -0
  38. data/lib/epics/builders/xml_builder.rb +7 -0
  39. data/lib/epics/builders.rb +13 -0
  40. data/lib/epics/c2s.rb +3 -10
  41. data/lib/epics/c52.rb +2 -14
  42. data/lib/epics/c53.rb +2 -14
  43. data/lib/epics/c54.rb +2 -14
  44. data/lib/epics/c5n.rb +3 -14
  45. data/lib/epics/ccs.rb +3 -10
  46. data/lib/epics/cct.rb +3 -10
  47. data/lib/epics/cd1.rb +3 -10
  48. data/lib/epics/cdb.rb +3 -10
  49. data/lib/epics/cdd.rb +3 -10
  50. data/lib/epics/cds.rb +3 -10
  51. data/lib/epics/cdz.rb +3 -14
  52. data/lib/epics/cip.rb +3 -10
  53. data/lib/epics/client.rb +491 -123
  54. data/lib/epics/crypt/aes.rb +56 -0
  55. data/lib/epics/crypt/x_509.rb +52 -0
  56. data/lib/epics/crypt.rb +5 -0
  57. data/lib/epics/crz.rb +3 -14
  58. data/lib/epics/factories/crypt/aes_factory.rb +5 -0
  59. data/lib/epics/factories/crypt.rb +4 -0
  60. data/lib/epics/factories/request_factory/base.rb +236 -0
  61. data/lib/epics/factories/request_factory/v2.rb +194 -0
  62. data/lib/epics/factories/request_factory/v24.rb +32 -0
  63. data/lib/epics/factories/request_factory/v25.rb +31 -0
  64. data/lib/epics/factories/request_factory/v3.rb +305 -0
  65. data/lib/epics/factories/request_factory.rb +8 -0
  66. data/lib/epics/factories.rb +5 -0
  67. data/lib/epics/fdl.rb +3 -18
  68. data/lib/epics/ful.rb +6 -0
  69. data/lib/epics/generic_request.rb +31 -92
  70. data/lib/epics/generic_upload_request.rb +14 -67
  71. data/lib/epics/haa.rb +3 -9
  72. data/lib/epics/hac.rb +3 -14
  73. data/lib/epics/handlers/auth_signature_handler.rb +102 -0
  74. data/lib/epics/handlers/order_data_handler/base.rb +98 -0
  75. data/lib/epics/handlers/order_data_handler/v2.rb +39 -0
  76. data/lib/epics/handlers/order_data_handler/v24.rb +11 -0
  77. data/lib/epics/handlers/order_data_handler/v25.rb +11 -0
  78. data/lib/epics/handlers/order_data_handler/v3.rb +41 -0
  79. data/lib/epics/handlers/order_data_handler.rb +8 -0
  80. data/lib/epics/handlers/user_signature_handler/base.rb +10 -0
  81. data/lib/epics/handlers/user_signature_handler/v2.rb +17 -0
  82. data/lib/epics/handlers/user_signature_handler/v3.rb +17 -0
  83. data/lib/epics/handlers/user_signature_handler.rb +6 -0
  84. data/lib/epics/handlers.rb +6 -0
  85. data/lib/epics/hev.rb +2 -15
  86. data/lib/epics/hia.rb +4 -55
  87. data/lib/epics/hkd.rb +3 -9
  88. data/lib/epics/hpb.rb +3 -13
  89. data/lib/epics/hpd.rb +3 -9
  90. data/lib/epics/htd.rb +3 -9
  91. data/lib/epics/ini.rb +4 -46
  92. data/lib/epics/keyring.rb +17 -0
  93. data/lib/epics/letter_renderer.rb +17 -22
  94. data/lib/epics/ptk.rb +3 -14
  95. data/lib/epics/response.rb +34 -29
  96. data/lib/epics/services/crypt_service.rb +62 -0
  97. data/lib/epics/services/digest_resolver/base.rb +30 -0
  98. data/lib/epics/services/digest_resolver/v2.rb +13 -0
  99. data/lib/epics/services/digest_resolver/v3.rb +19 -0
  100. data/lib/epics/services/digest_resolver.rb +6 -0
  101. data/lib/epics/services.rb +5 -0
  102. data/lib/epics/signature.rb +50 -0
  103. data/lib/epics/{key.rb → signature_algorithm/base.rb} +14 -21
  104. data/lib/epics/signature_algorithm/rsa.rb +50 -0
  105. data/lib/epics/signature_algorithm/rsapkcs1.rb +16 -0
  106. data/lib/epics/signature_algorithm/rsapss.rb +20 -0
  107. data/lib/epics/signature_algorithm.rb +2 -0
  108. data/lib/epics/sta.rb +3 -14
  109. data/lib/epics/version.rb +1 -1
  110. data/lib/epics/vmk.rb +3 -14
  111. data/lib/epics/wss.rb +3 -9
  112. data/lib/epics/xct.rb +3 -10
  113. data/lib/epics/xds.rb +3 -10
  114. data/lib/epics/xe2.rb +3 -10
  115. data/lib/epics/xe3.rb +3 -10
  116. data/lib/epics/xek.rb +5 -0
  117. data/lib/epics/yct.rb +6 -0
  118. data/lib/epics/z01.rb +2 -14
  119. data/lib/epics/z52.rb +2 -14
  120. data/lib/epics/z53.rb +2 -14
  121. data/lib/epics/z54.rb +2 -14
  122. data/lib/epics/zsr.rb +5 -0
  123. data/lib/epics.rb +69 -5
  124. data/lib/letter/ini.erb +27 -6
  125. data/spec/aes_spec.rb +46 -0
  126. data/spec/auth_signature_handler_spec.rb +58 -0
  127. data/spec/builders_spec.rb +616 -0
  128. data/spec/certificate_handling_spec.rb +189 -0
  129. data/spec/client_setup_block_spec.rb +41 -0
  130. data/spec/client_spec.rb +143 -91
  131. data/spec/crypt_service_spec.rb +132 -0
  132. data/spec/date_range_spec.rb +46 -0
  133. data/spec/digest_resolver_spec.rb +164 -0
  134. data/spec/fixtures/bank_x509.pem +3 -0
  135. data/spec/fixtures/xml/haa.xml +40 -1
  136. data/spec/fixtures/xml/haa_receipt.xml +33 -30
  137. data/spec/fixtures/xml/haa_response_h004.xml +4 -0
  138. data/spec/fixtures/xml/haa_response_h005.xml +38 -0
  139. data/spec/fixtures/xml/hia_request_order_data.xml +24 -1
  140. data/spec/fixtures/xml/hpb_request.xml +1 -1
  141. data/spec/fixtures/xml/hpb_response_x509.xml +16 -0
  142. data/spec/fixtures/xml/htd_order_data_h005.xml +55 -0
  143. data/spec/fixtures/xml/jruby/hia.xml +20 -22
  144. data/spec/fixtures/xml/jruby/ini.xml +1 -3
  145. data/spec/fixtures/xml/ruby/hia.xml +21 -1
  146. data/spec/fixtures/xml/ruby/ini.xml +21 -1
  147. data/spec/handlers_spec.rb +267 -0
  148. data/spec/hpb_malformed_certificate_spec.rb +36 -0
  149. data/spec/key_file_decryption_spec.rb +27 -0
  150. data/spec/key_file_preservation_spec.rb +78 -0
  151. data/spec/keyring_spec.rb +349 -0
  152. data/spec/middleware/parse_ebics_spec.rb +2 -1
  153. data/spec/order_id_spec.rb +65 -0
  154. data/spec/orders/azv_spec.rb +63 -7
  155. data/spec/orders/b2b_spec.rb +68 -3
  156. data/spec/orders/bka_spec.rb +34 -4
  157. data/spec/orders/c2s_spec.rb +62 -9
  158. data/spec/orders/c52_spec.rb +34 -4
  159. data/spec/orders/c53_spec.rb +34 -4
  160. data/spec/orders/c54_spec.rb +36 -4
  161. data/spec/orders/c5n_spec.rb +36 -4
  162. data/spec/orders/camt_parity_spec.rb +80 -0
  163. data/spec/orders/ccs_spec.rb +62 -9
  164. data/spec/orders/cct_spec.rb +83 -9
  165. data/spec/orders/cd1_spec.rb +50 -7
  166. data/spec/orders/cdb_spec.rb +64 -7
  167. data/spec/orders/cdd_spec.rb +64 -7
  168. data/spec/orders/cds_spec.rb +74 -0
  169. data/spec/orders/cdz_spec.rb +67 -4
  170. data/spec/orders/cip_spec.rb +61 -9
  171. data/spec/orders/crz_spec.rb +67 -4
  172. data/spec/orders/fdl_spec.rb +143 -13
  173. data/spec/orders/ful_spec.rb +63 -0
  174. data/spec/orders/haa_spec.rb +115 -9
  175. data/spec/orders/hac_spec.rb +89 -10
  176. data/spec/orders/hev_spec.rb +1 -6
  177. data/spec/orders/hia_spec.rb +25 -22
  178. data/spec/orders/hkd_spec.rb +23 -4
  179. data/spec/orders/hpb_spec.rb +7 -4
  180. data/spec/orders/hpd_spec.rb +23 -4
  181. data/spec/orders/htd_spec.rb +23 -4
  182. data/spec/orders/ini_spec.rb +23 -18
  183. data/spec/orders/ptk_spec.rb +27 -4
  184. data/spec/orders/sta_spec.rb +129 -11
  185. data/spec/orders/vmk_spec.rb +36 -4
  186. data/spec/orders/wss_spec.rb +29 -3
  187. data/spec/orders/x_509_certificate_spec.rb +9 -1
  188. data/spec/orders/xct_spec.rb +63 -0
  189. data/spec/orders/xds_spec.rb +13 -6
  190. data/spec/orders/xe2_spec.rb +64 -7
  191. data/spec/orders/xe3_spec.rb +64 -7
  192. data/spec/orders/xek_spec.rb +31 -0
  193. data/spec/orders/yct_spec.rb +43 -0
  194. data/spec/orders/z01_spec.rb +34 -4
  195. data/spec/orders/z52_spec.rb +34 -4
  196. data/spec/orders/z53_spec.rb +34 -4
  197. data/spec/orders/z54_spec.rb +36 -4
  198. data/spec/orders/zsr_spec.rb +31 -0
  199. data/spec/request_factory_spec.rb +444 -0
  200. data/spec/response_business_error_spec.rb +45 -0
  201. data/spec/response_validation_spec.rb +23 -0
  202. data/spec/{key_spec.rb → signature_algorithm/rsa_pss_spec.rb} +4 -13
  203. data/spec/support/ebics_matcher.rb +17 -9
  204. data/spec/support/ebics_shared_examples.rb +642 -0
  205. data/spec/support/h005_client_helper.rb +23 -0
  206. data/spec/upload_digest_spec.rb +69 -0
  207. data/spec/user_signature_handler_spec.rb +25 -0
  208. data/spec/version_support_error_spec.rb +76 -0
  209. data/spec/xsd/{ebics_hev.xsd → H000/ebics_hev.xsd} +0 -0
  210. data/spec/xsd/H003/ebics.xsd +11 -0
  211. data/spec/xsd/H003/ebics_keymgmt_request.xsd +555 -0
  212. data/spec/xsd/H003/ebics_keymgmt_response.xsd +131 -0
  213. data/spec/xsd/H003/ebics_orders.xsd +1811 -0
  214. data/spec/xsd/H003/ebics_request.xsd +354 -0
  215. data/spec/xsd/H003/ebics_response.xsd +161 -0
  216. data/spec/xsd/{ebics_signature.xsd → H003/ebics_signature.xsd} +0 -0
  217. data/spec/xsd/H003/ebics_types.xsd +2361 -0
  218. data/spec/xsd/H003/xmldsig-core-schema.xsd +318 -0
  219. data/spec/xsd/H004/ebics_signature.xsd +217 -0
  220. data/spec/xsd/H005/ebics_H005.xsd +11 -0
  221. data/spec/xsd/H005/ebics_keymgmt_request_H005.xsd +523 -0
  222. data/spec/xsd/H005/ebics_keymgmt_response_H005.xsd +137 -0
  223. data/spec/xsd/H005/ebics_orders_H005.xsd +2094 -0
  224. data/spec/xsd/H005/ebics_request_H005.xsd +349 -0
  225. data/spec/xsd/H005/ebics_response_H005.xsd +167 -0
  226. data/spec/xsd/H005/ebics_signature_S002.xsd +177 -0
  227. data/spec/xsd/H005/ebics_types_H005.xsd +1885 -0
  228. data/spec/xsd/H005/xmldsig-core-schema.xsd +318 -0
  229. metadata +200 -36
  230. data/lib/epics/header_request.rb +0 -58
  231. data/lib/epics/middleware/xmlsig.rb +0 -16
  232. data/lib/epics/signer.rb +0 -40
  233. data/lib/epics/x_509_certificate.rb +0 -15
  234. data/lib/letter/ini_with_certs.erb +0 -335
  235. data/spec/generic_upload_spec.rb +0 -58
  236. data/spec/hpb_spec.rb +0 -15
  237. data/spec/signer_spec.rb +0 -34
  238. /data/spec/xsd/{ebics_H004.xsd → H004/ebics_H004.xsd} +0 -0
  239. /data/spec/xsd/{ebics_keymgmt_request_H004.xsd → H004/ebics_keymgmt_request_H004.xsd} +0 -0
  240. /data/spec/xsd/{ebics_keymgmt_response_H004.xsd → H004/ebics_keymgmt_response_H004.xsd} +0 -0
  241. /data/spec/xsd/{ebics_orders_H004.xsd → H004/ebics_orders_H004.xsd} +0 -0
  242. /data/spec/xsd/{ebics_request_H004.xsd → H004/ebics_request_H004.xsd} +0 -0
  243. /data/spec/xsd/{ebics_response_H004.xsd → H004/ebics_response_H004.xsd} +0 -0
  244. /data/spec/xsd/{ebics_types_H004.xsd → H004/ebics_types_H004.xsd} +0 -0
  245. /data/spec/xsd/{xmldsig-core-schema.xsd → H004/xmldsig-core-schema.xsd} +0 -0
data/lib/epics/z01.rb CHANGED
@@ -1,17 +1,5 @@
1
1
  class Epics::Z01 < Epics::GenericRequest
2
- def header
3
- client.header_request.build(
4
- nonce: nonce,
5
- timestamp: timestamp,
6
- order_type: 'Z01',
7
- order_attribute: 'DZHNN',
8
- order_params: {
9
- DateRange: {
10
- Start: options[:from],
11
- End: options[:to]
12
- }
13
- },
14
- mutable: { TransactionPhase: 'Initialisation' }
15
- )
2
+ def to_xml
3
+ request_factory.create_z01(options[:from], options[:to], **service_options).to_xml
16
4
  end
17
5
  end
data/lib/epics/z52.rb CHANGED
@@ -1,17 +1,5 @@
1
1
  class Epics::Z52 < Epics::GenericRequest
2
- def header
3
- client.header_request.build(
4
- nonce: nonce,
5
- timestamp: timestamp,
6
- order_type: 'Z52',
7
- order_attribute: 'DZHNN',
8
- order_params: {
9
- DateRange: {
10
- Start: options[:from],
11
- End: options[:to]
12
- }
13
- },
14
- mutable: { TransactionPhase: 'Initialisation' }
15
- )
2
+ def to_xml
3
+ request_factory.create_z52(options[:from], options[:to], **service_options).to_xml
16
4
  end
17
5
  end
data/lib/epics/z53.rb CHANGED
@@ -1,17 +1,5 @@
1
1
  class Epics::Z53 < Epics::GenericRequest
2
- def header
3
- client.header_request.build(
4
- nonce: nonce,
5
- timestamp: timestamp,
6
- order_type: 'Z53',
7
- order_attribute: 'DZHNN',
8
- order_params: {
9
- DateRange: {
10
- Start: options[:from],
11
- End: options[:to]
12
- }
13
- },
14
- mutable: { TransactionPhase: 'Initialisation' }
15
- )
2
+ def to_xml
3
+ request_factory.create_z53(options[:from], options[:to], **service_options).to_xml
16
4
  end
17
5
  end
data/lib/epics/z54.rb CHANGED
@@ -1,17 +1,5 @@
1
1
  class Epics::Z54 < Epics::GenericRequest
2
- def header
3
- client.header_request.build(
4
- nonce: nonce,
5
- timestamp: timestamp,
6
- order_type: 'Z54',
7
- order_attribute: 'DZHNN',
8
- order_params: {
9
- DateRange: {
10
- Start: options[:from],
11
- End: options[:to]
12
- }
13
- },
14
- mutable: { TransactionPhase: 'Initialisation' }
15
- )
2
+ def to_xml
3
+ request_factory.create_z54(options[:from], options[:to], **service_options).to_xml
16
4
  end
17
5
  end
data/lib/epics/zsr.rb ADDED
@@ -0,0 +1,5 @@
1
+ class Epics::ZSR < Epics::GenericRequest
2
+ def to_xml
3
+ request_factory.create_zsr(options[:from], options[:to], **service_options).to_xml
4
+ end
5
+ end
data/lib/epics.rb CHANGED
@@ -10,15 +10,19 @@ require 'faraday'
10
10
  require 'securerandom'
11
11
  require 'time'
12
12
  require "epics/version"
13
- require "epics/key"
13
+ require "epics/keyring"
14
+ require "epics/signature"
15
+ require "epics/signature_algorithm"
16
+ require "epics/signature_algorithm/base"
17
+ require "epics/signature_algorithm/rsa"
18
+ require "epics/signature_algorithm/rsapss"
19
+ require "epics/signature_algorithm/rsapkcs1"
14
20
  require "epics/response"
15
21
  require "epics/error"
16
22
  require 'epics/letter_renderer'
17
- require "epics/middleware/xmlsig"
18
23
  require "epics/middleware/parse_ebics"
19
24
  require "epics/generic_request"
20
25
  require "epics/generic_upload_request"
21
- require "epics/header_request"
22
26
  require "epics/azv"
23
27
  require "epics/hpb"
24
28
  require "epics/hkd"
@@ -26,6 +30,7 @@ require "epics/htd"
26
30
  require "epics/haa"
27
31
  require "epics/sta"
28
32
  require "epics/fdl"
33
+ require "epics/ful"
29
34
  require "epics/vmk"
30
35
  require "epics/bka"
31
36
  require "epics/c52"
@@ -55,18 +60,77 @@ require "epics/c2s"
55
60
  require "epics/cdz"
56
61
  require "epics/crz"
57
62
  require "epics/xct"
63
+ require "epics/xek"
64
+ require "epics/yct"
65
+ require "epics/zsr"
58
66
  require "epics/hia"
59
67
  require "epics/ini"
60
68
  require "epics/hev"
61
- require "epics/signer"
62
- require "epics/x_509_certificate"
63
69
  require "epics/client"
64
70
 
71
+ require 'epics/builders'
72
+ require 'epics/crypt'
73
+ require 'epics/factories'
74
+ require 'epics/handlers'
75
+ require 'epics/services'
76
+
65
77
  I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'letter/locales', '*.yml')]
66
78
 
67
79
  module Epics
68
80
  DEFAULT_PRODUCT_NAME = 'EPICS - a ruby ebics kernel'
69
81
  DEFAULT_LOCALE = :de
82
+
83
+ # EBICS 3.0 (H005) carries public keys inside `ds:X509Data`, which the key management
84
+ # schemas declare mandatory (EBICS 3.0.2 §3.9). There is no raw modulus/exponent form.
85
+ class MissingCertificateError < StandardError
86
+ attr_reader :signature_version, :option_name
87
+
88
+ def initialize(signature_version, option_name)
89
+ @signature_version = signature_version
90
+ @option_name = option_name
91
+ super("EBICS 3.0 (H005) requires an X.509 certificate for #{signature_version}. " \
92
+ "Pass #{option_name}: to Epics::Client.new, or use Epics::Client.setup " \
93
+ 'to generate a self-signed one.')
94
+ end
95
+ end
96
+
97
+ # Raised when a check needs a key the client has not loaded, e.g. verifying a bank
98
+ # signature before HPB has run.
99
+ class MissingKeyError < StandardError
100
+ def initialize(what)
101
+ super("#{what} is not available; run HPB or load a key file that contains it")
102
+ end
103
+ end
104
+
105
+ class InvalidCertificateError < StandardError
106
+ attr_reader :source
107
+
108
+ # `source` says where the certificate came from: a constructor option name, or a
109
+ # description such as "the HPB response".
110
+ def initialize(source, original = nil)
111
+ @source = source
112
+ message = "Could not parse the X.509 certificate from #{source}"
113
+ message += " (#{original.message})" if original
114
+ super(message)
115
+ end
116
+ end
117
+
118
+ class VersionSupportError < StandardError
119
+ attr_reader :version
120
+
121
+ def initialize(version, direction = 'above')
122
+ @version = version
123
+ message = case direction
124
+ when 'above'
125
+ "Supported from version #{version}"
126
+ when 'below'
127
+ "Support for versions below #{version}"
128
+ else
129
+ raise ArgumentError, "Invalid direction: #{direction}. Use 'above' or 'below'."
130
+ end
131
+ super(message)
132
+ end
133
+ end
70
134
  end
71
135
 
72
136
  Ebics = Epics
data/lib/letter/ini.erb CHANGED
@@ -100,7 +100,7 @@
100
100
  <%= t('version') %> :
101
101
  </td>
102
102
  <td>
103
- A006
103
+ <%= signature_version %>
104
104
  </td>
105
105
  </tr>
106
106
  </table>
@@ -108,12 +108,19 @@
108
108
  </td>
109
109
  </tr>
110
110
  </table>
111
+ <% if keyring.user_signature.certificate %>
112
+ <p><%= t('certificate') %> :</p>
113
+ <pre class="code"><code><%= keyring.user_signature.certificate.to_pem %></code></pre>
114
+ <p><%= t('hash') %> (SHA-256) :</p>
115
+ <p class="code"><code><%= keyring.user_signature.certificate.fingerprint.scan(/../).join(":") %></code></p>
116
+ <% else %>
111
117
  <p><%= t('exponent') %> (<%= t('bit', bit: a.key.e.num_bytes * 8) %>) :</p>
112
118
  <p class="code"><code><%= a.e %></code></p>
113
119
  <p><%= t('modulus') %> (<%= t('bit', bit: a.key.n.num_bytes * 8) %>) :</p>
114
120
  <p class="code"><code><%= a.n.scan(/.{2}/).join(' ') %></code></p>
115
121
  <p><%= t('hash') %> (SHA-256) :</p>
116
- <p class="code"><code><%= Base64.decode64(a.public_digest).unpack('H*').join.upcase.scan(/.{2}/).join(' ') %></code></p>
122
+ <p class="code"><code><%= confirm_digest(keyring.user_signature).upcase.scan(/.{2}/).join(' ') %></code></p>
123
+ <% end %>
117
124
  <p><%= t('confirmation') %></p>
118
125
  <br/>
119
126
  <br/>
@@ -211,7 +218,7 @@
211
218
  <%= t('version') %> :
212
219
  </td>
213
220
  <td>
214
- X002
221
+ <%= authentication_version %>
215
222
  </td>
216
223
  </tr>
217
224
  </table>
@@ -219,12 +226,19 @@
219
226
  </td>
220
227
  </tr>
221
228
  </table>
229
+ <% if keyring.user_authentication.certificate %>
230
+ <p><%= t('certificate') %> :</p>
231
+ <pre class="code"><code><%= keyring.user_authentication.certificate.to_pem %></code></pre>
232
+ <p><%= t('hash') %> (SHA-256) :</p>
233
+ <p class="code"><code><%= keyring.user_authentication.certificate.fingerprint.scan(/../).join(":") %></code></p>
234
+ <% else %>
222
235
  <p><%= t('exponent') %> (<%= t('bit', bit: x.key.e.num_bytes * 8) %>) :</p>
223
236
  <p class="code"><code><%= x.e %></code></p>
224
237
  <p><%= t('modulus') %> (<%= t('bit', bit: x.key.n.num_bytes * 8) %>) :</p>
225
238
  <p class="code"><code><%= x.n.scan(/.{2}/).join(' ') %></code></p>
226
239
  <p><%= t('hash') %> (SHA-256) :</p>
227
- <p class="code"><code><%= Base64.decode64(x.public_digest).unpack('H*').join.upcase.scan(/.{2}/).join(' ') %></code></p>
240
+ <p class="code"><code><%= confirm_digest(keyring.user_authentication).upcase.scan(/.{2}/).join(' ') %></code></p>
241
+ <% end %>
228
242
  </div>
229
243
  <div style="page-break-after:always"></div>
230
244
  <div>
@@ -293,7 +307,7 @@
293
307
  <%= t('version') %> :
294
308
  </td>
295
309
  <td>
296
- E002
310
+ <%= encryption_version %>
297
311
  </td>
298
312
  </tr>
299
313
  </table>
@@ -301,12 +315,19 @@
301
315
  </td>
302
316
  </tr>
303
317
  </table>
318
+ <% if keyring.user_encryption.certificate %>
319
+ <p><%= t('certificate') %> :</p>
320
+ <pre class="code"><code><%= keyring.user_encryption.certificate.to_pem %></code></pre>
321
+ <p><%= t('hash') %> (SHA-256) :</p>
322
+ <p class="code"><code><%= keyring.user_encryption.certificate.fingerprint.scan(/../).join(":") %></code></p>
323
+ <% else %>
304
324
  <p><%= t('exponent') %> (<%= t('bit', bit: e.key.e.num_bytes * 8) %>) :</p>
305
325
  <p class="code"><code><%= e.e %></code></p>
306
326
  <p><%= t('modulus') %> (<%= t('bit', bit: e.key.n.num_bytes * 8) %>) :</p>
307
327
  <p class="code"><code><%= e.n.scan(/.{2}/).join(' ') %></code></p>
308
328
  <p><%= t('hash') %> (SHA-256) :</p>
309
- <p class="code"><code><%= Base64.decode64(e.public_digest).unpack('H*').join.upcase.scan(/.{2}/).join(' ') %></code></p>
329
+ <p class="code"><code><%= confirm_digest(keyring.user_encryption).upcase.scan(/.{2}/).join(' ') %></code></p>
330
+ <% end %>
310
331
  <p><%= t('confirmation') %></p>
311
332
  <br/>
312
333
  <br/>
data/spec/aes_spec.rb ADDED
@@ -0,0 +1,46 @@
1
+ RSpec.describe Epics::Crypt::Aes do
2
+ subject { described_class.new.tap { |aes| aes.key = Base64.decode64('5fXINXF7C+gRpK+q1Y12lw==') } }
3
+ let(:pad) {
4
+ ->(text) {
5
+ cipher = subject.instance_eval { use_cipher(:encrypt) }
6
+ subject.instance_eval { pad(cipher, text) }
7
+ }
8
+ }
9
+ let(:unpad) {
10
+ ->(text) {
11
+ subject.instance_eval { unpad(text) }
12
+ }
13
+ }
14
+
15
+ describe '#encrypt' do
16
+ it 'valid' do
17
+ expect(Base64.strict_encode64(subject.encrypt('a' * 13))).to eq('f8kId9dqBLaEbhSz9PBv7g==')
18
+ end
19
+ end
20
+
21
+ describe '#decrypt' do
22
+ it 'valid' do
23
+ expect(subject.decrypt(Base64.strict_decode64('f8kId9dqBLaEbhSz9PBv7g=='))).to eq('a' * 13)
24
+ end
25
+ end
26
+
27
+ describe '#pad' do
28
+ it 'will complete the block to the next 16byte' do
29
+ expect(pad.("\x01" * 13).size).to eq(16)
30
+ end
31
+
32
+ it 'will pad a complete block if the size is a multiple of 16' do
33
+ expect(pad.("\x01" * 16).size).to eq(32)
34
+ end
35
+
36
+ it 'will set the last byte to the padding length' do
37
+ expect(pad.("\x01" * 13)[-1]).to eq([3].pack('C*'))
38
+ end
39
+ end
40
+
41
+ describe '#unpad' do
42
+ it 'valid' do
43
+ expect(unpad.(pad.('a' * 13))).to eq('a' * 13)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,58 @@
1
+ RSpec.describe Epics::Handlers::AuthSignatureHandler do
2
+ let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3
+ let(:hpb) { Epics::HPB.new(client) }
4
+
5
+ before { allow(SecureRandom).to receive(:hex).with(16).and_return('014a82626a51ee1cab547bbaf18a13a0') }
6
+ before { allow(Time).to receive(:now).and_return(Time.parse('2014-09-09T09:33:12Z')) }
7
+
8
+ subject { Nokogiri::XML(hpb.to_xml) }
9
+ let(:headers_node) { subject.xpath("//*[@authenticate='true']").first }
10
+ let(:crypt_service) { Epics::Services::CryptService.new }
11
+ let(:header_hash) { crypt_service.hash(headers_node.canonicalize) }
12
+ let(:digest_node) { subject.xpath('//ds:DigestValue', ds: 'http://www.w3.org/2000/09/xmldsig#').first }
13
+ let(:signature_value_node) { subject.xpath('//ds:SignatureValue', ds: 'http://www.w3.org/2000/09/xmldsig#').first }
14
+ let(:signature_node) { subject.xpath('//ds:SignedInfo', ds: 'http://www.w3.org/2000/09/xmldsig#').first }
15
+
16
+ describe '#digest!' do
17
+ it 'creates a digest of the *[authorized=true] nodes' do
18
+ expect(digest_node.content).to eq('j0WiGMS9D6Bt1xw92ZAOWUsAJ+OBlUYKtHRQI7TbpbY=')
19
+ end
20
+
21
+ it 'bar' do
22
+ expect(digest_node.content).to eq(Base64.strict_encode64(header_hash))
23
+ end
24
+ end
25
+
26
+ describe '#sign!' do
27
+ it 'signs the complete ds:SignedInfo node' do
28
+ expect(signature_value_node.content).to eq('K3FNqdg90AoFqgc1bM2CgAKHNfy7SWWcrm03CXEfu9XF4q4/2QWRyOAShcoF+kG60lnKjADqMqLTpMqXMTKg2AX9IItdl3p8IDocaZ4fVBdL8yUvE4/iH9569oj8QX4gvndwwS46TRVVYyZno1l44r9aEuUfaaqATp3ITQcyM3xDXFsNwVdJuUjzYHPTEOMXGxZlD/wIcLTQwMLLn0D/gitgsXQKqvGH3VI80bAG7aIxmLpcPEBqrAaZGCIghZWvJK2CBfgjSstcdmIK5YRCYF5UjCqoEywnp8ELaFtWMTcLPtq0GfJ1e84vGCVSNRdIH30dNRKINDWl+4YtzJpa5A==')
29
+ end
30
+
31
+ it 'can be verified with the same key' do
32
+ expect(client.keyring.user_authentication.key.verify(signature_value_node.content, signature_node.canonicalize)).to be(true)
33
+ end
34
+ end
35
+
36
+ describe 'XML structure' do
37
+ it 'inserts AuthSignature before body element' do
38
+ body_node = subject.at('body')
39
+ auth_signature_node = subject.at('AuthSignature')
40
+ expect(auth_signature_node).not_to be_nil
41
+ expect(body_node.previous).to eq(auth_signature_node)
42
+ end
43
+
44
+ it 'replaces placeholder with actual signature value' do
45
+ expect(signature_value_node.content).not_to eq('PLACEHOLDER')
46
+ expect(signature_value_node.content).not_to be_empty
47
+ expect(signature_value_node.content).to match(%r{\A[A-Za-z0-9+/=]+\z})
48
+ end
49
+
50
+ it 'canonicalizes SignedInfo in main document context' do
51
+ signed_info_canonicalized = signature_node.canonicalize
52
+ expect(signed_info_canonicalized).to include('ds:SignedInfo')
53
+ expect(signed_info_canonicalized).to include('ds:CanonicalizationMethod')
54
+ expect(signed_info_canonicalized).to include('ds:SignatureMethod')
55
+ expect(signed_info_canonicalized).to include('ds:Reference')
56
+ end
57
+ end
58
+ end