diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..c7b7409e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,106 @@ +# CLAUDE.md + +Guidance for working in this repository. + +## What this is + +`epics` is a Ruby gem implementing the [EBICS](https://www.ebics.org/) protocol +(Electronic Banking Internet Communication Standard) — a bank-communication +standard used mainly in Germany/France/Switzerland. It handles the key +initialization handshake (INI / HIA / HPB), signs requests, and exchanges +payment and statement order types with a bank's EBICS server. + +- Pure library gem (no Rails). Entry point: `require "epics"`. +- Supports **EBICS 2.5 (H004, default)** and **EBICS 3.0 (H005, opt-in)**. +- License LGPL-3.0. Published to RubyGems as `epics`. + +## Commands + +```bash +bin/setup # bundle install +bundle exec rspec # run the full test suite +bundle exec rspec spec/client_spec.rb # single file +bundle exec rspec spec/client_spec.rb:42 # single example +bin/console # irb with the gem loaded (pry available) +``` + +- Ruby: developed on **3.3.7** (`.tool-versions`); CI matrix runs 3.2 / 3.3 / 3.4 / 4.0. +- `required_ruby_version >= 3.1`. +- CI is Semaphore (`.semaphore/semaphore.yml`) — just `bundle install` + `rspec`. +- No linter/formatter is configured; match surrounding style. + +## Architecture + +Everything is namespaced under the `Epics` module (`Ebics` is an alias). +`lib/epics.rb` is the manifest: it `require`s every file explicitly (no +autoloading) and defines protocol constants (`EBICS_PROTOCOLS`, `DEFAULT_VERSION`). + +### The three layers + +1. **`Epics::Client`** (`lib/epics/client.rb`) — the public API and the only + object users instantiate. Holds credentials + RSA keys, exposes one method + per order type (`STA`, `CCT`, `CDD`, `HPB`, `HTD`, …) plus convenience + wrappers (`credit`, `debit`, `statements`). Owns the Faraday `connection` + and key encryption/decryption (AES-256-CBC over a passphrase). + +2. **Order classes** (`lib/epics/.rb`, e.g. `sta.rb`, `cct.rb`) — one + small class per EBICS order type. Each subclasses `GenericRequest` + (downloads) or `GenericUploadRequest` (uploads) and typically only overrides + `#header` to declare `order_type`, `order_attribute`, and params. This is + the dominant pattern — to add an order type, copy the closest sibling. + +3. **Request builders + middleware** + - `generic_request.rb` / `generic_upload_request.rb` / `header_request.rb` — + build the EBICS XML envelope via Nokogiri. + - `middleware/xmlsig.rb` — Faraday middleware that signs the outgoing XML + (`Epics::Signer` + `signer.rb`) before it leaves. + - `middleware/parse_ebics.rb` — Faraday middleware that wraps every response + in `Epics::Response` and raises `Epics::Error::TechnicalError` / + `BusinessError` on non-OK return codes. + +### Transaction flow + +`Client#download` / `#upload` (near the bottom of `client.rb`) run the +multi-step EBICS handshake: an initialization POST returns a `transaction_id`, +followed by transfer/receipt POSTs. `download_and_unzip` additionally unpacks +the ZIP payload (used by camt orders C52/C53/C54, Z-types, BKA…). Response +parsing lives in `response.rb`; RSA/key handling in `key.rb`. + +### H004 vs H005 (important) + +The gem defaults to H004. H005 is selected via `Epics::Client.new(..., version: :h005)`. + +- `client.protocol` / `namespace` / `protocol_version` / `revision` / `h005?` + derive from the configured version. +- Under H005 there is **no flat OrderTypes list** — transactions are + **BTF services** (`btf.rb`, `btf_mapping.rb`, `Client#services`). Generic + transfer is `BTU` (upload, replaces FUL) / `BTD` (download, replaces FDL). +- Many classic order methods branch: e.g. `CCT`/`CDD`/`STA`/`C53` call + `btf_upload` / `btf_download` when `h005?`. When touching an order type, + check whether it needs an H005 branch. +- X.509 certificate support (`x_509_certificate.rb`, `letter/ini_with_certs.erb`) + is part of the H005 path. + +### INI letter + +`letter_renderer.rb` renders the paper initialization letter from +`lib/letter/*.erb`, localized via `lib/letter/locales/*.yml` (de/en/fr, i18n). + +## Tests + +- RSpec, config in `spec/spec_helper.rb` (`--require spec_helper` via `.rspec`). +- **WebMock** stubs all HTTP — tests never hit a real bank. +- Real EBICS responses live as fixtures in `spec/fixtures/xml/`; RSA keys/certs + in `spec/fixtures/*.pem` and `*.key`. Compare XML with `equivalent-xml`'s + `be_equivalent_to` matcher (namespace/whitespace-insensitive). +- H005-specific coverage is in `spec/h005_client_spec.rb`. +- Helpers/shared setup in `spec/support/`. + +## Conventions + +- One file per order type, named after the 3-letter EBICS code, lowercased + (`cct.rb` → `Epics::CCT`). Register new files in `lib/epics.rb`. +- Keep order classes minimal — push shared logic into the `Generic*` base + classes, not into individual order types. +- `# frozen_string_literal: true` is used on newer files; keep it when editing them. +- Bump `Epics::VERSION` (`lib/epics/version.rb`) and update `CHANGELOG.md` for releases. diff --git a/README.md b/README.md index 77d6f4a6..947c2ca1 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,44 @@ You can choose to configure some default values like this e = Epics::Client.new(keys, 'passphrase', 'url', 'host', 'user', 'partner', locale: :fr, product_name: 'Mon Epic Client EBICS') ``` +### EBICS 3.0 (H005) + +The gem defaults to EBICS 2.5 (`H004`). To use EBICS 3.0 (`H005`), pass `version: :h005`: + +```ruby +e = Epics::Client.new(keys, 'passphrase', 'url', 'host', 'user', 'partner', version: :h005) +``` + +In EBICS 3.0 the classic order types are replaced by the Business Transaction +Format (BTF): uploads use `BTU`, downloads use `BTD`, each described by a +`Service` instead of a `FileFormat`. + +```ruby +# Upload (replaces FUL). `service` is an Epics::BTF (or a hash with the same keys). +e.BTU(document, Epics::BTF.new(service_name: 'SCT', scope: 'DE', msg_name: 'pain.001', msg_version: '03')) + +# Download (replaces FDL). +e.BTD(Epics::BTF.new(service_name: 'EOP', scope: 'DE', container: 'ZIP', msg_name: 'camt.053', msg_version: '08'), from: '2026-01-01', to: '2026-01-31') +``` + +The common German convenience methods (`CCT`, `CDD`, `CDB`, `STA`, `C52`, `C53`, +`C54`, `VMK`) automatically route to `BTU`/`BTD` via `Epics::BtfMapping` when the +client is on `:h005`. The BTF message versions in that table are commonly-used +defaults and **are bank-specific** — verify them against your bank's BTF mapping +("Auftragsarten" annex) and override with the raw `BTU`/`BTD` API when needed. + +EBICS 3.0 requires every key to be transmitted as an X.509 certificate. For +shared-key banks (e.g. German banks) the gem generates self-signed certificates +automatically for `INI`/`HIA` when no certificate is supplied. + +> Note: All generated H005 requests (INI/HIA/HPB, the admin downloads, and +> BTU/BTD in every transaction phase) are validated against the official H005 +> XSD schema set in the test suite, and the INI key payload against the S002 +> signature schema. Full end-to-end verification against a live H005 bank +> endpoint is the remaining step. Known limitation: the `X509IssuerSerial` +> currently reports the certificate version rather than its serial number +> (pre-existing behaviour shared with the H004 X.509 path). + ## Features ### Initialization diff --git a/lib/epics.rb b/lib/epics.rb index bf681fbd..85db7476 100644 --- a/lib/epics.rb +++ b/lib/epics.rb @@ -9,6 +9,33 @@ require 'faraday' require 'securerandom' require 'time' + +module Epics + DEFAULT_PRODUCT_NAME = 'EPICS - a ruby ebics kernel' + DEFAULT_LOCALE = :de + DEFAULT_VERSION = :h004 + + # The electronic-signature version used for the user (bank-technical) key. + # This gem is A006-only: A006 (RSASSA-PSS, SHA-256) is signed by Epics::Key#sign + # and declared in every SignatureVersion element. A006 is valid under both + # H004 and H005 (which mandates it); the legacy A005 (RSA PKCS#1 v1.5) is not + # supported — the authentication key X002 stays PKCS#1 v1.5 on its own path. + SIGNATURE_VERSION = 'A006' + + # EBICS protocol version descriptors. The gem defaults to H004 (EBICS 2.5) so + # that existing users are unaffected; H005 (EBICS 3.0) is opt-in via the + # `version:` client option. + EBICS_PROTOCOLS = { + h004: { namespace: 'urn:org:ebics:H004', version: 'H004', revision: '1' }, + h005: { namespace: 'urn:org:ebics:H005', version: 'H005', revision: '1' }, + }.freeze + + # Raised when an order type is requested under an EBICS protocol version that + # does not support it (e.g. a classic H004 business order under H005, which + # expresses business transactions as BTF services instead). + class VersionSupportError < StandardError; end +end + require "epics/version" require "epics/key" require "epics/response" @@ -59,15 +86,14 @@ require "epics/hia" require "epics/ini" require "epics/hev" +require "epics/btf" +require "epics/btf_mapping" +require "epics/btd" +require "epics/btu" require "epics/signer" require "epics/x_509_certificate" require "epics/client" I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'letter/locales', '*.yml')] -module Epics - DEFAULT_PRODUCT_NAME = 'EPICS - a ruby ebics kernel' - DEFAULT_LOCALE = :de -end - Ebics = Epics diff --git a/lib/epics/btd.rb b/lib/epics/btd.rb new file mode 100644 index 00000000..3703f7ae --- /dev/null +++ b/lib/epics/btd.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# EBICS 3.0 (H005) generic download order. Replaces the H004 FDL order: instead +# of a FileFormat string the transfer is described by a BTF . +# +# client.BTD(Epics::BTF.new(service_name: "EOP", scope: "DE", msg_name: "camt.053", msg_name_version: "08"), from: "2026-01-01", to: "2026-01-31") +class Epics::BTD < Epics::GenericRequest + def header + client.header_request.build( + nonce: nonce, + timestamp: timestamp, + admin_order_type: 'BTD', + service: options[:service], + from: options[:from], + to: options[:to], + parameters: options[:parameters], + mutable: { TransactionPhase: 'Initialisation' } + ) + end +end diff --git a/lib/epics/btf.rb b/lib/epics/btf.rb new file mode 100644 index 00000000..e5d771df --- /dev/null +++ b/lib/epics/btf.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# Value object describing an EBICS 3.0 (H005) Business Transaction Format (BTF). +# +# A BTF replaces the H004 OrderType/FileFormat combination. It is expressed via +# the element inside BTU/BTD order params: +# +# +# SCT +# ... (optional) +# DE (optional) +# (optional) +# pain.001 +# +# +# Example: +# +# Epics::BTF.new( +# service_name: "SCT", +# scope: "DE", +# msg_name: "pain.001", +# msg_name_version: "03", +# ) +# +# A plain Hash with the same keys is accepted anywhere a BTF is expected. +class Epics::BTF + attr_reader :service_name, :service_option, :scope, :container, + :msg_name, :msg_name_version, :msg_variant, :msg_format + + def initialize(service_name:, msg_name:, scope: nil, service_option: nil, + container: nil, msg_name_version: nil, msg_variant: nil, msg_format: nil) + @service_name = service_name + @service_option = service_option + @scope = scope + @container = container + @msg_name = msg_name + @msg_name_version = msg_name_version + @msg_variant = msg_variant + @msg_format = msg_format + end + + # Normalized hash consumed by Epics::HeaderRequest#build_service. + def to_h + { + service_name: service_name, + service_option: service_option, + scope: scope, + container: container, + msg_name: { + name: msg_name, + version: msg_name_version, + variant: msg_variant, + format: msg_format, + }, + } + end +end diff --git a/lib/epics/btf_mapping.rb b/lib/epics/btf_mapping.rb new file mode 100644 index 00000000..135d0517 --- /dev/null +++ b/lib/epics/btf_mapping.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +# Maps the classic H004 order codes (CCT, CDD, C53, ...) to their EBICS 3.0 +# (H005) BTF Service descriptors, so the existing convenience API keeps working +# when a client is configured with `version: :h005`. +# +# This is a *starter set* for German (DE) banks. The message versions below are +# the commonly used ISO 20022 versions but ARE bank-specific — verify them +# against your bank's BTF mapping / "Auftragsarten" annex and override via the +# raw Epics::Client#BTU / #BTD API (passing an Epics::BTF) when they differ. +# +# Unmapped codes raise, pointing the caller at the raw BTU/BTD API. +module Epics::BtfMapping + # code => btf-attributes. Message versions are only pinned where we are fairly + # confident of the DE default; where omitted the carries no version + # attribute and the bank applies its own default. Override per call when your + # bank differs (see Epics::Client convenience methods / #BTU / #BTD). + UPLOADS = { + 'CCT' => { service_name: 'SCT', scope: 'DE', msg_name: 'pain.001', msg_name_version: '03' }, + 'CCS' => { service_name: 'SCT', scope: 'DE', msg_name: 'pain.001', msg_name_version: '03' }, + 'CDD' => { service_name: 'SDD', service_option: 'COR', scope: 'DE', msg_name: 'pain.008', msg_name_version: '02' }, + 'CDB' => { service_name: 'SDD', service_option: 'B2B', scope: 'DE', msg_name: 'pain.008', msg_name_version: '02' }, + 'AZV' => { service_name: 'XCT', scope: 'DE', msg_name: 'dtazv' }, + 'C2S' => { service_name: 'SDD', scope: 'BIL', msg_name: 'pain.008' }, + 'CDS' => { service_name: 'SDD', scope: 'BIL', msg_name: 'pain.008' }, + 'CIP' => { service_name: 'SCI', msg_name: 'pain.001' }, + 'XE2' => { service_name: 'MCT', msg_name: 'pain.001' }, + 'XE3' => { service_name: 'SDD', msg_name: 'pain.008' }, + }.freeze + + DOWNLOADS = { + 'STA' => { service_name: 'EOP', scope: 'DE', msg_name: 'mt940' }, + 'C53' => { service_name: 'EOP', scope: 'DE', container: 'ZIP', msg_name: 'camt.053', msg_name_version: '08' }, + 'C52' => { service_name: 'STM', scope: 'DE', container: 'ZIP', msg_name: 'camt.052', msg_name_version: '08' }, + 'C54' => { service_name: 'REP', scope: 'DE', container: 'ZIP', msg_name: 'camt.054', msg_name_version: '08' }, + 'VMK' => { service_name: 'STM', scope: 'DE', msg_name: 'mt942' }, + 'PSR' => { service_name: 'PSR', scope: 'DE', msg_name: 'pain.002', msg_name_version: '03' }, + 'Z52' => { service_name: 'STM', container: 'ZIP', msg_name: 'camt.052' }, + 'Z53' => { service_name: 'EOP', container: 'ZIP', msg_name: 'camt.053' }, + 'Z54' => { service_name: 'EOP', service_option: 'XQRR', container: 'ZIP', msg_name: 'camt.054' }, + 'Z01' => { service_name: 'PSR', service_option: 'CH003GEN', container: 'ZIP', msg_name: 'pain.002' }, + 'BKA' => { service_name: 'EOP', scope: 'DE', container: 'ZIP', msg_name: 'camt.053' }, + 'C5N' => { service_name: 'STM', scope: 'DE', service_option: 'SCI', container: 'ZIP', msg_name: 'camt.054' }, + 'CDZ' => { service_name: 'REP', scope: 'DE', service_option: 'SDD', container: 'ZIP', msg_name: 'pain.002' }, + 'CRZ' => { service_name: 'REP', scope: 'DE', service_option: 'SCT', container: 'ZIP', msg_name: 'pain.002' }, + }.freeze + + module_function + + # `overrides` lets callers replace individual BTF attributes (e.g. scope, + # msg_name_version, service_option) on top of the starter-set defaults, so a bank + # that expects a different message version or scope can be served without + # dropping to the raw BTU/BTD API. nil overrides are ignored. + def upload(code, **overrides) + lookup(UPLOADS, code, overrides) + end + + def download(code, **overrides) + lookup(DOWNLOADS, code, overrides) + end + + def lookup(table, code, overrides = {}) + attrs = table[code.to_s] + unless attrs + raise ArgumentError, + "No H005 BTF mapping for order code #{code.inspect}. Use the raw " \ + "Epics::Client#BTU / #BTD API with an Epics::BTF instead." + end + Epics::BTF.new(**attrs.merge(overrides.compact)) + end +end diff --git a/lib/epics/btu.rb b/lib/epics/btu.rb new file mode 100644 index 00000000..86610948 --- /dev/null +++ b/lib/epics/btu.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# EBICS 3.0 (H005) generic upload order. Replaces the H004 FUL order: instead of +# a FileFormat string the transfer is described by a BTF . +# +# client.BTU(document, Epics::BTF.new(service_name: "SCT", scope: "DE", msg_name: "pain.001", msg_name_version: "03")) +class Epics::BTU < Epics::GenericUploadRequest + def header + client.header_request.build( + nonce: nonce, + timestamp: timestamp, + admin_order_type: 'BTU', + service: options[:service], + signature_flag: options.fetch(:signature_flag, true), + request_eds: options[:request_eds], + parameters: options[:parameters], + mutable: { TransactionPhase: 'Initialisation' } + ) + end +end diff --git a/lib/epics/client.rb b/lib/epics/client.rb index c71bc300..bb1f4716 100644 --- a/lib/epics/client.rb +++ b/lib/epics/client.rb @@ -2,12 +2,12 @@ class Epics::Client extend Forwardable attr_accessor :passphrase, :url, :host_id, :user_id, :partner_id, :keys, :keys_content, :locale, :product_name, - :x_509_certificates_content, :debug_mode + :x_509_certificates_content, :debug_mode, :ebics_version attr_writer :iban, :bic, :name - + def_delegators :connection, :post - + def initialize(keys_content, passphrase, url, host_id, user_id, partner_id, options = {}) self.keys_content = keys_content.respond_to?(:read) ? keys_content.read : keys_content if keys_content self.passphrase = passphrase @@ -19,6 +19,10 @@ def initialize(keys_content, passphrase, url, host_id, user_id, partner_id, opti self.locale = options[:locale] || Epics::DEFAULT_LOCALE self.product_name = options[:product_name] || Epics::DEFAULT_PRODUCT_NAME self.debug_mode = !!options[:debug_mode] + self.ebics_version = (options[:version] || Epics::DEFAULT_VERSION).to_s.downcase.to_sym + unless Epics::EBICS_PROTOCOLS.key?(ebics_version) + raise ArgumentError, "Unsupported EBICS version #{ebics_version.inspect}, expected one of #{Epics::EBICS_PROTOCOLS.keys.inspect}" + end self.x_509_certificates_content = { a: options[:x_509_certificate_a_content], x: options[:x_509_certificate_x_content], @@ -26,6 +30,26 @@ def initialize(keys_content, passphrase, url, host_id, user_id, partner_id, opti } end + def protocol + Epics::EBICS_PROTOCOLS.fetch(ebics_version) + end + + def namespace + protocol[:namespace] + end + + def protocol_version + protocol[:version] + end + + def revision + protocol[:revision] + end + + def h005? + ebics_version == :h005 + end + def inspect "#<#{self.class}:#{self.object_id} @keys=#{self.keys.keys}, @@ -38,7 +62,7 @@ def e end def a - keys["A006"] + keys[Epics::SIGNATURE_VERSION] end def x @@ -49,6 +73,16 @@ def bank_e keys["#{host_id.upcase}.E002"] end + CERTIFICATE_SUFFIX = '.crt'.freeze + + # X.509 certificates belonging to the user's keys, keyed like "A006.crt". + # Populated from the key file (entries suffixed .crt) and by generated + # self-signed certificates (H005); persisted alongside the keys via + # save_keys/dump_keys so certificates stay stable across processes. + def certificates + @certificates ||= {} + end + def bank_x keys["#{host_id.upcase}.X002"] end @@ -69,9 +103,15 @@ def order_types @order_types ||= (self.HTD; @order_types) end + # EBICS 3.0 (H005): the available business transactions as Epics::BTF services + # (there is no flat OrderTypes list anymore). Empty on H004. + def services + @services ||= (self.HTD; @services) + end + def self.setup(passphrase, url, host_id, user_id, partner_id, keysize = 2048, options = {}) client = new(nil, passphrase, url, host_id, user_id, partner_id, options) - client.keys = %w(A006 X002 E002).each_with_object({}) do |type, memo| + client.keys = [Epics::SIGNATURE_VERSION, 'X002', 'E002'].each_with_object({}) do |type, memo| memo[type] = Epics::Key.new( OpenSSL::PKey::RSA.generate(keysize) ) end @@ -123,25 +163,24 @@ def HEV end def HPB - Nokogiri::XML(download(Epics::HPB)).xpath("//xmlns:PubKeyValue", xmlns: "urn:org:ebics:H004").each do |node| + doc = Nokogiri::XML(download(Epics::HPB)) + return hpb_h005(doc) if h005? + + doc.xpath("//xmlns:PubKeyValue", xmlns: namespace).each do |node| type = node.parent.last_element_child.content modulus = Base64.decode64(node.at_xpath(".//*[local-name() = 'Modulus']").content) exponent = Base64.decode64(node.at_xpath(".//*[local-name() = 'Exponent']").content) - sequence = [] - sequence << OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(modulus, 2)) - sequence << OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(exponent, 2)) - - bank = OpenSSL::PKey::RSA.new(OpenSSL::ASN1::Sequence(sequence).to_der) - - self.keys["#{host_id.upcase}.#{type}"] = Epics::Key.new(bank) + self.keys["#{host_id.upcase}.#{type}"] = Epics::Key.new(rsa_from_modulus_exponent(modulus, exponent)) end [bank_x, bank_e] end - def AZV(document) + def AZV(document, **overrides) + return btf_upload('AZV', document, **overrides) if h005? + upload(Epics::AZV, document) end @@ -149,27 +188,39 @@ def CD1(document) upload(Epics::CD1, document) end - def CDB(document) + def CDB(document, **overrides) + return btf_upload('CDB', document, **overrides) if h005? + upload(Epics::CDB, document) end - def C2S(document) + def C2S(document, **overrides) + return btf_upload('C2S', document, **overrides) if h005? + upload(Epics::C2S, document) end - def CDD(document) + def CDD(document, **overrides) + return btf_upload('CDD', document, **overrides) if h005? + upload(Epics::CDD, document) end - def XE2(document) + def XE2(document, **overrides) + return btf_upload('XE2', document, **overrides) if h005? + upload(Epics::XE2, document) end - def XE3(document) + def XE3(document, **overrides) + return btf_upload('XE3', document, **overrides) if h005? + upload(Epics::XE3, document) end - def CDS(document) + def CDS(document, **overrides) + return btf_upload('CDS', document, **overrides) if h005? + upload(Epics::CDS, document) end @@ -177,15 +228,21 @@ def XDS(document) upload(Epics::XDS, document) end - def CCT(document) + def CCT(document, **overrides) + return btf_upload('CCT', document, **overrides) if h005? + upload(Epics::CCT, document) end - def CIP(document) + def CIP(document, **overrides) + return btf_upload('CIP', document, **overrides) if h005? + upload(Epics::CIP, document) end - def CCS(document) + def CCS(document, **overrides) + return btf_upload('CCS', document, **overrides) if h005? + upload(Epics::CCS, document) end @@ -197,7 +254,21 @@ def FUL(document) upload(Epics::FUL, document) end - def STA(from = nil, to = nil) + # EBICS 3.0 (H005) generic upload. `service` is an Epics::BTF (or a hash with + # the same keys). Replaces FUL under H005. + def BTU(document, service, signature_flag: true, request_eds: false, parameters: nil) + upload(Epics::BTU, document, service: service, signature_flag: signature_flag, request_eds: request_eds, parameters: parameters) + end + + # EBICS 3.0 (H005) generic download. `service` is an Epics::BTF (or a hash with + # the same keys). Replaces FDL under H005. + def BTD(service, from: nil, to: nil, parameters: nil) + download(Epics::BTD, service: service, from: from, to: to, parameters: parameters) + end + + def STA(from = nil, to = nil, **overrides) + return btf_download('STA', from, to, **overrides) if h005? + download(Epics::STA, from: from, to: to) end @@ -205,64 +276,104 @@ def FDL(format, from = nil, to = nil) download(Epics::FDL, file_format: format, from: from, to: to ) end - def VMK(from = nil, to = nil) + def VMK(from = nil, to = nil, **overrides) + return btf_download('VMK', from, to, **overrides) if h005? + download(Epics::VMK, from: from, to: to) end - def CDZ(from = nil, to = nil) + def CDZ(from = nil, to = nil, **overrides) + return btf_download('CDZ', from, to, **overrides) if h005? + download_and_unzip(Epics::CDZ, from: from, to: to) end - def CRZ(from = nil, to = nil) + def CRZ(from = nil, to = nil, **overrides) + return btf_download('CRZ', from, to, **overrides) if h005? + download_and_unzip(Epics::CRZ, from: from, to: to) end - def BKA(from, to) + def BKA(from, to, **overrides) + return btf_download('BKA', from, to, **overrides) if h005? + download_and_unzip(Epics::BKA, from: from, to: to) end - def C52(from, to) + def C52(from, to, **overrides) + return btf_download('C52', from, to, **overrides) if h005? + download_and_unzip(Epics::C52, from: from, to: to) end - def C53(from, to) + def C53(from, to, **overrides) + return btf_download('C53', from, to, **overrides) if h005? + download_and_unzip(Epics::C53, from: from, to: to) end - def C54(from, to) + def C54(from, to, **overrides) + return btf_download('C54', from, to, **overrides) if h005? + download_and_unzip(Epics::C54, from: from, to: to) end - def C5N(from, to) + def C5N(from, to, **overrides) + return btf_download('C5N', from, to, **overrides) if h005? + download_and_unzip(Epics::C5N, from: from, to: to) end - def Z01(from, to) + def Z01(from, to, **overrides) + return btf_download('Z01', from, to, **overrides) if h005? + download_and_unzip(Epics::Z01, from: from, to: to) end - def Z52(from, to) + def Z52(from, to, **overrides) + return btf_download('Z52', from, to, **overrides) if h005? + download_and_unzip(Epics::Z52, from: from, to: to) end - def Z53(from, to) + def Z53(from, to, **overrides) + return btf_download('Z53', from, to, **overrides) if h005? + download_and_unzip(Epics::Z53, from: from, to: to) end - def Z54(from, to) + def Z54(from, to, **overrides) + return btf_download('Z54', from, to, **overrides) if h005? + download_and_unzip(Epics::Z54, from: from, to: to) end def HAA - Nokogiri::XML(download(Epics::HAA)).at_xpath("//xmlns:OrderTypes", xmlns: "urn:org:ebics:H004").content.split(/\s/) + doc = Nokogiri::XML(download(Epics::HAA)) + if h005? + # H005: available transactions are BTF services, not a flat OrderTypes list. + doc.xpath("//xmlns:Service", xmlns: namespace).map { |s| service_from_node(s) } + else + doc.at_xpath("//xmlns:OrderTypes", xmlns: namespace).content.split(/\s/) + end end def HTD Nokogiri::XML(download(Epics::HTD)).tap do |htd| - @iban ||= htd.at_xpath("//xmlns:AccountNumber[@international='true']", xmlns: "urn:org:ebics:H004").text rescue nil - @bic ||= htd.at_xpath("//xmlns:BankCode[@international='true']", xmlns: "urn:org:ebics:H004").text rescue nil - @name ||= htd.at_xpath("//xmlns:Name", xmlns: "urn:org:ebics:H004").text rescue nil - @order_types ||= htd.search("//xmlns:OrderTypes", xmlns: "urn:org:ebics:H004").map{|o| o.content.split(/\s/) }.delete_if{|o| o == ""}.flatten + @iban ||= htd.at_xpath("//xmlns:AccountNumber[@international='true']", xmlns: namespace).text rescue nil + @bic ||= htd.at_xpath("//xmlns:BankCode[@international='true']", xmlns: namespace).text rescue nil + @name ||= htd.at_xpath("//xmlns:Name", xmlns: namespace).text rescue nil + + if h005? + # H005 replaces OrderTypes with OrderInfo entries: each has an + # AdminOrderType and, for BTU/BTD, a BTF Service. + order_infos = htd.search("//xmlns:OrderInfo", xmlns: namespace) + @order_types ||= order_infos.map { |o| o.at_xpath("./xmlns:AdminOrderType", xmlns: namespace)&.content }.compact.uniq + @services ||= order_infos.map { |o| o.at_xpath("./xmlns:Service", xmlns: namespace) }.compact.map { |s| service_from_node(s) } + else + @order_types ||= htd.search("//xmlns:OrderTypes", xmlns: namespace).map{|o| o.content.split(/\s/) }.delete_if{|o| o == ""}.flatten + @services ||= [] + end end.to_xml end @@ -289,24 +400,126 @@ def WSS def save_keys(path) File.write(path, dump_keys) end - + def x_509_certificate(type) content = x_509_certificates_content[type.to_sym] - return if content.nil? || content.empty? + if content.nil? || content.empty? + # EBICS 3.0 mandates X.509 certificates for all keys. When none was + # supplied, fall back to a self-signed certificate (valid for shared-key + # banks, e.g. German banks). H004 keeps the raw RSAKeyValue behaviour. + return unless h005? + return self_signed_certificate(type) + end Epics::X509Certificate.new(content) end - + def x_509_certificate_hash(type) - content = x_509_certificates_content[type.to_sym] - return if content.nil? || content.empty? - cert = OpenSSL::X509::Certificate.new(content) - Digest::SHA256.hexdigest(cert.to_der).upcase + # Routes through x_509_certificate so H005 self-signed certificates get a + # fingerprint too — the INI letter needs it for subscriber verification. + x_509_certificate(type)&.fingerprint end private - def upload(order_type, document) - order = order_type.new(self, document) + DSIG_NS = 'http://www.w3.org/2000/09/xmldsig#'.freeze + + HPB_KEY_INFOS = { + 'AuthenticationPubKeyInfo' => 'AuthenticationVersion', + 'EncryptionPubKeyInfo' => 'EncryptionVersion', + }.freeze + + # EBICS 3.0 (H005) HPB response: the bank's authentication and encryption keys + # are transmitted only as X.509 certificates (ds:X509Data). Extract the public + # key from each certificate rather than from a PubKeyValue/RSAKeyValue. + def hpb_h005(doc) + HPB_KEY_INFOS.each do |element, version_element| + info = doc.at_xpath("//xmlns:#{element}", xmlns: namespace) + next unless info + + type = info.at_xpath("./xmlns:#{version_element}", xmlns: namespace)&.content + next unless type + + self.keys["#{host_id.upcase}.#{type}"] = Epics::Key.new(bank_key_from_info(info)) + end + + [bank_x, bank_e] + end + + def bank_key_from_info(info) + cert = info.at_xpath(".//ds:X509Certificate", ds: DSIG_NS) + return OpenSSL::X509::Certificate.new(Base64.decode64(cert.content)).public_key if cert + + # Fallback: some banks additionally include a raw RSAKeyValue. + modulus = info.at_xpath(".//*[local-name() = 'Modulus']") + exponent = info.at_xpath(".//*[local-name() = 'Exponent']") + unless modulus && exponent + raise "HPB response: #{info.name} contains neither an X509Certificate nor an RSAKeyValue — cannot import the bank key" + end + + rsa_from_modulus_exponent(Base64.decode64(modulus.content), Base64.decode64(exponent.content)) + end + + # Parses a BTF element (from HAA/HTD responses) into an Epics::BTF. + def service_from_node(node) + msg = node.at_xpath("./xmlns:MsgName", xmlns: namespace) + container = node.at_xpath("./xmlns:Container", xmlns: namespace) + text = ->(name) { node.at_xpath("./xmlns:#{name}", xmlns: namespace)&.content } + + Epics::BTF.new( + service_name: text.call('ServiceName'), + scope: text.call('Scope'), + service_option: text.call('ServiceOption'), + container: container && (container['containerType'] || container.content), + msg_name: msg&.content, + msg_name_version: msg && msg['version'], + msg_variant: msg && msg['variant'], + msg_format: msg && msg['format'], + ) + end + + def rsa_from_modulus_exponent(modulus, exponent) + sequence = [ + OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(modulus, 2)), + OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(exponent, 2)), + ] + OpenSSL::PKey::RSA.new(OpenSSL::ASN1::Sequence(sequence).to_der) + end + + KEY_FOR_CERT_TYPE = { a: Epics::SIGNATURE_VERSION, x: 'X002', e: 'E002' }.freeze + + def self_signed_certificate(type) + key_name = KEY_FOR_CERT_TYPE.fetch(type.to_sym) + key = keys[key_name] + return unless key + + # Stored in #certificates so save_keys persists it — the certificate (and + # thus its fingerprint on the INI letter) must stay identical across + # processes, otherwise the bank cannot verify the subscriber. + certificates["#{key_name}#{CERTIFICATE_SUFFIX}"] ||= + Epics::X509Certificate.generate_self_signed( + key.key, + subject: "/CN=#{user_id}/O=#{partner_id}/OU=#{host_id}" + ) + end + + # Route a classic order code to its H005 BTF Service via Epics::BtfMapping. + # `overrides` replace individual BTF attributes (scope, msg_name_version, ...) on + # top of the mapped starter-set default. + def btf_upload(code, document, **overrides) + self.BTU(document, Epics::BtfMapping.upload(code, **overrides)) + end + + def btf_download(code, from, to, **overrides) + btf = Epics::BtfMapping.download(code, **overrides) + if btf.container == 'ZIP' + download_and_unzip(Epics::BTD, service: btf, from: from, to: to) + else + self.BTD(btf, from: from, to: to) + end + end + + def upload(order_type, document, **options) + order = order_type.new(self, document, **options) res = post(url, order.to_xml).body order.transaction_id = res.transaction_id @@ -347,13 +560,24 @@ def connection end def extract_keys - JSON.load(self.keys_content).each_with_object({}) do |(type, key), memo| - memo[type] = Epics::Key.new(decrypt(key)) if key + JSON.load(self.keys_content).each_with_object({}) do |(type, blob), memo| + next unless blob + + # Entries suffixed with .crt are persisted X.509 certificates (H005 + # self-signed certs survive process restarts this way); everything else + # is an RSA key. + if type.end_with?(CERTIFICATE_SUFFIX) + certificates[type] = Epics::X509Certificate.new(decrypt(blob)) + else + memo[type] = Epics::Key.new(decrypt(blob)) + end end end def dump_keys - JSON.dump(keys.each_with_object({}) {|(k,v),m| m[k]= encrypt(v.key.to_pem)}) + data = keys.each_with_object({}) { |(k, v), m| m[k] = encrypt(v.key.to_pem) } + certificates.each { |k, v| data[k] = encrypt(v.to_pem) } + JSON.dump(data) end def new_cipher diff --git a/lib/epics/generic_request.rb b/lib/epics/generic_request.rb index 62902c5b..627ce5ad 100644 --- a/lib/epics/generic_request.rb +++ b/lib/epics/generic_request.rb @@ -22,6 +22,17 @@ def root "ebicsRequest" end + # Namespace/version attributes for the request root element. Derived from the + # client's configured EBICS protocol version (H004 by default, H005 opt-in). + def root_attributes + { + 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', + 'xmlns' => client.namespace, + 'Version' => client.protocol_version, + 'Revision' => client.revision, + } + end + def body Nokogiri::XML::Builder.new do |xml| xml.body @@ -53,7 +64,7 @@ def auth_signature def to_transfer_xml Nokogiri::XML::Builder.new do |xml| - xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') { + xml.send(root, root_attributes) { xml.header(authenticate: true) { xml.static { xml.HostID host_id @@ -76,7 +87,7 @@ def to_transfer_xml def to_receipt_xml Nokogiri::XML::Builder.new do |xml| - xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') { + xml.send(root, root_attributes) { xml.header(authenticate: true) { xml.static { xml.HostID host_id @@ -98,7 +109,7 @@ def to_receipt_xml def to_xml Nokogiri::XML::Builder.new do |xml| - xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision'=> '1') { + xml.send(root, root_attributes) { xml.parent.add_child(header) xml.parent.add_child(auth_signature) xml.parent.add_child(body) diff --git a/lib/epics/generic_upload_request.rb b/lib/epics/generic_upload_request.rb index 8d71fdc6..b63267f0 100644 --- a/lib/epics/generic_upload_request.rb +++ b/lib/epics/generic_upload_request.rb @@ -27,16 +27,30 @@ def body xml.TransactionKey Base64.encode64(client.bank_e.key.public_encrypt(self.key)).gsub(/\n/,'') } xml.SignatureData(encrypted_order_signature, authenticate: true) + # EBICS 3.0 (H005) additionally carries the plain hash of the order + # data (the value that was signed) as a DataDigest element. + xml.DataDigest(data_digest, SignatureVersion: Epics::SIGNATURE_VERSION) if client.h005? } } end.doc.root end + # Base64-encoded SHA-256 digest of the order data — the same digest that is + # signed in #signature_value. Required in the H005 upload body. + def data_digest + Base64.strict_encode64(digester.digest(document.gsub(/\n|\r/, ""))) + end + + def signature_namespace + client.h005? ? 'http://www.ebics.org/S002' : 'http://www.ebics.org/S001' + end + def order_signature + ns = signature_namespace Nokogiri::XML::Builder.new do |xml| - xml.UserSignatureData('xmlns' => 'http://www.ebics.org/S001', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://www.ebics.org/S001 http://www.ebics.org/S001/ebics_signature.xsd') { + xml.UserSignatureData('xmlns' => ns, 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => "#{ns} #{ns}/ebics_signature.xsd") { xml.OrderSignatureData { - xml.SignatureVersion "A006" + xml.SignatureVersion Epics::SIGNATURE_VERSION xml.SignatureValue signature_value xml.PartnerID partner_id xml.UserID user_id diff --git a/lib/epics/header_request.rb b/lib/epics/header_request.rb index fc4ee043..0a6ac507 100644 --- a/lib/epics/header_request.rb +++ b/lib/epics/header_request.rb @@ -2,6 +2,12 @@ class Epics::HeaderRequest extend Forwardable attr_accessor :client + # Administrative order types that remain first-class order types under EBICS + # 3.0 (H005). Every other (business) transaction is a BTF service carried by + # BTU/BTD, so a classic business order code reaching the H005 builder is a + # caller error rather than something to silently emit as a malformed request. + H005_ADMIN_ORDER_TYPES = %w[HPB HTD HAA HKD HPD HAC PTK INI HIA].freeze + def initialize(client) self.client = client end @@ -21,12 +27,7 @@ def build(options = {}) xml.UserID user_id xml.Product(client.product_name, 'Language' => client.locale) xml.OrderDetails { - xml.OrderType options[:order_type] - xml.OrderAttribute options[:order_attribute] - xml.StandardOrderParams { - build_attributes(xml, options[:order_params]) - } if options[:order_params] - build_attributes(xml, options[:custom_order_params]) if options[:custom_order_params] + build_order_details(xml, options) } xml.BankPubKeyDigests { xml.Authentication(client.bank_x.public_digest, Version: 'X002', Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256') @@ -44,6 +45,128 @@ def build(options = {}) private + # EBICS 3.0 (H005) uses AdminOrderType plus a BTF Service structure, and drops + # OrderAttribute. EBICS 2.5 (H004) keeps the classic OrderType/OrderAttribute + # shape. The version branch is the only structural divergence in the header. + def build_order_details(xml, options) + if client.h005? + build_h005_order_details(xml, options) + else + build_h004_order_details(xml, options) + end + end + + def build_h004_order_details(xml, options) + xml.OrderType options[:order_type] + xml.OrderAttribute options[:order_attribute] + xml.StandardOrderParams { + build_attributes(xml, options[:order_params]) + } if options[:order_params] + build_attributes(xml, options[:custom_order_params]) if options[:custom_order_params] + end + + def build_h005_order_details(xml, options) + admin_order_type = options[:admin_order_type] || options[:order_type] + ensure_h005_order_type!(admin_order_type) + xml.AdminOrderType admin_order_type + + case admin_order_type + when 'BTU' + xml.BTUOrderParams { + build_service(xml, options[:service]) + # SignatureFlag is an empty element (H005). Its *presence* means the + # order carries an electronic signature and is authorised within EBICS; + # omitting it means the order is authorised outside EBICS. The optional + # requestEDS attribute spools the order into the distributed signature + # (EDS/VEU) queue. + if options.fetch(:signature_flag, true) + attrs = options[:request_eds] ? { 'requestEDS' => 'true' } : {} + xml.SignatureFlag(attrs) + end + build_parameters(xml, options[:parameters]) + } + when 'BTD' + xml.BTDOrderParams { + build_service(xml, options[:service]) + build_date_range(xml, options) + build_parameters(xml, options[:parameters]) + } + else + # Other admin order types retrieved via ebicsRequest (HTD, HAA, HKD, HPD, + # HAC, ...) require a StandardOrderParams element. INI/HIA/HPB use the + # unsecured / no-pub-key request schemas whose OrderDetails carry only the + # AdminOrderType, so they suppress it via with_order_params: false. + if options.fetch(:with_order_params, true) + xml.StandardOrderParams { + build_date_range(xml, options) + } + end + end + end + + # Reject classic business order codes under H005 instead of emitting an + # AdminOrderType the bank will reject. BTU/BTD are the generic upload/download + # transports; the whitelist covers the administrative order types that survive + # into H005. Everything else must go through a BTF service (see Epics::BtfMapping + # and Epics::Client#BTU / #BTD). + def ensure_h005_order_type!(admin_order_type) + return if %w[BTU BTD].include?(admin_order_type) + return if H005_ADMIN_ORDER_TYPES.include?(admin_order_type) + + raise Epics::VersionSupportError, + "Order type #{admin_order_type.inspect} is not available under EBICS 3.0 (H005). " \ + "H005 expresses business transactions as BTF services — use Epics::Client#BTU / #BTD " \ + "with an Epics::BTF, or add a mapping in Epics::BtfMapping. Administrative order types " \ + "supported under H005: #{H005_ADMIN_ORDER_TYPES.join(', ')}." + end + + # Builds the BTF element. The child element order follows the H005 + # schema sequence: ServiceName, Scope, ServiceOption, Container, MsgName. + def build_service(xml, service) + return if service.nil? + service = service.to_h if service.respond_to?(:to_h) + + xml.Service { + xml.ServiceName service[:service_name] || service[:ServiceName] + scope = service[:scope] || service[:Scope] + xml.Scope scope if scope + option = service[:service_option] || service[:ServiceOption] + xml.ServiceOption option if option + + container = service[:container] || service[:Container] + if container + xml.Container('containerType' => container) + end + + msg = service[:msg_name] || service[:MsgName] || {} + msg = { name: msg } unless msg.is_a?(Hash) + msg_attrs = {} + msg_attrs['version'] = msg[:version] if msg[:version] + msg_attrs['variant'] = msg[:variant] if msg[:variant] + msg_attrs['format'] = msg[:format] if msg[:format] + xml.MsgName(msg[:name] || msg[:value], msg_attrs) + } + end + + def build_date_range(xml, options) + if options[:from] && options[:to] + xml.DateRange { + xml.Start options[:from] + xml.End options[:to] + } + end + end + + def build_parameters(xml, parameters) + return if parameters.nil? + parameters.each do |name, value| + xml.Parameter { + xml.Name name + xml.Value(value, 'Type' => 'string') + } + end + end + def build_attributes(xml, attributes) attributes.each do |key, value| if value.is_a?(Hash) diff --git a/lib/epics/hia.rb b/lib/epics/hia.rb index f43879dc..8ea6b27f 100644 --- a/lib/epics/hia.rb +++ b/lib/epics/hia.rb @@ -6,8 +6,10 @@ def root def header client.header_request.build( order_type: 'HIA', + admin_order_type: 'HIA', order_attribute: 'DZNNN', with_bank_pubkey_digests: false, + with_order_params: false, mutable: {} ) end @@ -23,8 +25,10 @@ def body end def order_data + return h005_order_data if client.h005? + Nokogiri::XML::Builder.new do |xml| - xml.HIARequestOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004') { + xml.HIARequestOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => client.namespace) { xml.AuthenticationPubKeyInfo { x509_data_xml(xml, client.x_509_certificate(:x)) xml.PubKeyValue { @@ -51,9 +55,28 @@ def order_data end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8') end + # EBICS 3.0 (H005): public keys are carried exclusively as X.509 certificates + # (ds:X509Data); the H004 RSAKeyValue is no longer part of the structure. + def h005_order_data + Nokogiri::XML::Builder.new do |xml| + xml.HIARequestOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => client.namespace) { + xml.AuthenticationPubKeyInfo { + x509_data_xml(xml, client.x_509_certificate(:x)) + xml.AuthenticationVersion 'X002' + } + xml.EncryptionPubKeyInfo { + x509_data_xml(xml, client.x_509_certificate(:e)) + xml.EncryptionVersion 'E002' + } + xml.PartnerID partner_id + xml.UserID user_id + } + end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8') + end + def to_xml Nokogiri::XML::Builder.new do |xml| - xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') { + xml.send(root, root_attributes) { xml.parent.add_child(header) xml.parent.add_child(body) } diff --git a/lib/epics/hpb.rb b/lib/epics/hpb.rb index 48d1abe0..b6dc20e8 100644 --- a/lib/epics/hpb.rb +++ b/lib/epics/hpb.rb @@ -8,8 +8,10 @@ def header nonce: nonce, timestamp: timestamp, order_type: 'HPB', + admin_order_type: 'HPB', order_attribute: 'DZHNN', with_bank_pubkey_digests: false, + with_order_params: false, mutable: {} ) end diff --git a/lib/epics/ini.rb b/lib/epics/ini.rb index 40e7ea16..1946e316 100644 --- a/lib/epics/ini.rb +++ b/lib/epics/ini.rb @@ -6,8 +6,10 @@ def root def header client.header_request.build( order_type: 'INI', + admin_order_type: 'INI', order_attribute: 'DZNNN', with_bank_pubkey_digests: false, + with_order_params: false, mutable: {}, ) end @@ -23,6 +25,8 @@ def body end def key_signature + return h005_key_signature if client.h005? + Nokogiri::XML::Builder.new do |xml| xml.SignaturePubKeyOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'http://www.ebics.org/S001') { xml.SignaturePubKeyInfo { @@ -34,7 +38,23 @@ def key_signature } xml.TimeStamp timestamp } - xml.SignatureVersion 'A006' + xml.SignatureVersion Epics::SIGNATURE_VERSION + } + xml.PartnerID partner_id + xml.UserID user_id + } + end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8') + end + + # EBICS 3.0 (H005): the signature namespace is S002 and the public key is + # carried exclusively as an X.509 certificate (ds:X509Data) — the H004 + # RSAKeyValue is no longer part of the structure. + def h005_key_signature + Nokogiri::XML::Builder.new do |xml| + xml.SignaturePubKeyOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'http://www.ebics.org/S002') { + xml.SignaturePubKeyInfo { + x509_data_xml(xml, client.x_509_certificate(:a)) + xml.SignatureVersion Epics::SIGNATURE_VERSION } xml.PartnerID partner_id xml.UserID user_id @@ -44,7 +64,7 @@ def key_signature def to_xml Nokogiri::XML::Builder.new do |xml| - xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') { + xml.send(root, root_attributes) { xml.parent.add_child(header) xml.parent.add_child(body) } diff --git a/lib/epics/letter_renderer.rb b/lib/epics/letter_renderer.rb index 7bd788e0..480ebfa7 100644 --- a/lib/epics/letter_renderer.rb +++ b/lib/epics/letter_renderer.rb @@ -31,12 +31,24 @@ def use_x_509_certificate_template? def x_509_certificate_a_hash @client.x_509_certificate_hash(:a) end - + def x_509_certificate_x_hash @client.x_509_certificate_hash(:x) end - + def x_509_certificate_e_hash @client.x_509_certificate_hash(:e) end + + def x_509_certificate_a_pem + @client.x_509_certificate(:a)&.to_pem + end + + def x_509_certificate_x_pem + @client.x_509_certificate(:x)&.to_pem + end + + def x_509_certificate_e_pem + @client.x_509_certificate(:e)&.to_pem + end end diff --git a/lib/epics/response.rb b/lib/epics/response.rb index 7ac98736..0126fefe 100644 --- a/lib/epics/response.rb +++ b/lib/epics/response.rb @@ -7,6 +7,12 @@ def initialize(client, xml) self.client = client end + # EBICS protocol namespace of the configured client (H004 by default, H005 + # when opted in). All response XPaths are scoped to this namespace. + def ns + client ? client.namespace : Epics::EBICS_PROTOCOLS.fetch(Epics::DEFAULT_VERSION)[:namespace] + end + def technical_error? !["011000", "000000"].include?(technical_code) end @@ -16,7 +22,7 @@ def technical_code end def mutable_return_code - doc.xpath("//xmlns:header/xmlns:mutable/xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").text + doc.xpath("//xmlns:header/xmlns:mutable/xmlns:ReturnCode", xmlns: ns).text end def system_return_code @@ -28,7 +34,7 @@ def business_error? end def business_code - doc.xpath("//xmlns:body/xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").text + doc.xpath("//xmlns:body/xmlns:ReturnCode", xmlns: ns).text end def ok? @@ -36,29 +42,29 @@ def ok? end def last_segment? - !!doc.at_xpath("//xmlns:header/xmlns:mutable/*[@lastSegment='true']", xmlns: "urn:org:ebics:H004") + !!doc.at_xpath("//xmlns:header/xmlns:mutable/*[@lastSegment='true']", xmlns: ns) end def segmented? - !!doc.at_xpath("//xmlns:header/xmlns:mutable/xmlns:SegmentNumber", xmlns: "urn:org:ebics:H004") + !!doc.at_xpath("//xmlns:header/xmlns:mutable/xmlns:SegmentNumber", xmlns: ns) end def return_code - doc.xpath("//xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").last.content + doc.xpath("//xmlns:ReturnCode", xmlns: ns).last.content rescue NoMethodError nil end def report_text - doc.xpath("//xmlns:ReportText", xmlns: "urn:org:ebics:H004").first.content + doc.xpath("//xmlns:ReportText", xmlns: ns).first.content end def transaction_id - doc.xpath("//xmlns:header/xmlns:static/xmlns:TransactionID", xmlns: 'urn:org:ebics:H004').text + doc.xpath("//xmlns:header/xmlns:static/xmlns:TransactionID", xmlns: ns).text end def order_id - doc.xpath("//xmlns:header/xmlns:mutable/xmlns:OrderID", xmlns: "urn:org:ebics:H004").text + doc.xpath("//xmlns:header/xmlns:mutable/xmlns:OrderID", xmlns: ns).text end def digest_valid? @@ -78,13 +84,13 @@ def signature_valid? end def public_digest_valid? - encryption_pub_key_digest = doc.xpath("//xmlns:EncryptionPubKeyDigest", xmlns: 'urn:org:ebics:H004').first + encryption_pub_key_digest = doc.xpath("//xmlns:EncryptionPubKeyDigest", xmlns: ns).first client.e.public_digest == encryption_pub_key_digest.content end def order_data - order_data_encrypted = Base64.decode64(doc.xpath("//xmlns:OrderData", xmlns: 'urn:org:ebics:H004').first.content) + order_data_encrypted = Base64.decode64(doc.xpath("//xmlns:OrderData", xmlns: ns).first.content) data = (cipher.update(order_data_encrypted) + cipher.final) @@ -101,7 +107,7 @@ def cipher end def transaction_key - transaction_key_encrypted = Base64.decode64(doc.xpath("//xmlns:TransactionKey", xmlns: 'urn:org:ebics:H004').first.content) + transaction_key_encrypted = Base64.decode64(doc.xpath("//xmlns:TransactionKey", xmlns: ns).first.content) @transaction_key ||= client.e.key.private_decrypt(transaction_key_encrypted) end diff --git a/lib/epics/x_509_certificate.rb b/lib/epics/x_509_certificate.rb index 1eacaed6..8119b8d1 100644 --- a/lib/epics/x_509_certificate.rb +++ b/lib/epics/x_509_certificate.rb @@ -3,13 +3,43 @@ class Epics::X509Certificate attr_reader :certificate - def_delegators :certificate, :issuer, :version + def_delegators :certificate, :issuer, :version, :serial, :to_pem def initialize(crt_content) - @certificate = OpenSSL::X509::Certificate.new(crt_content) + @certificate = + if crt_content.is_a?(OpenSSL::X509::Certificate) + crt_content + else + OpenSSL::X509::Certificate.new(crt_content) + end end def data Base64.strict_encode64(@certificate.to_der) end -end \ No newline at end of file + + # SHA-256 fingerprint of the DER-encoded certificate (upper-case hex), as + # printed on the EBICS 3.0 INI letter. + def fingerprint + Digest::SHA256.hexdigest(@certificate.to_der).upcase + end + + # Generates a self-signed X.509 certificate wrapping the given RSA key. EBICS + # 3.0 (H005) requires every public key to be transmitted as an X.509 + # certificate; for banks using the shared-key model (e.g. German banks) a + # self-signed certificate is sufficient. + def self.generate_self_signed(rsa_key, subject:, valid_years: 10) + cert = OpenSSL::X509::Certificate.new + cert.version = 2 + cert.serial = OpenSSL::BN.new(Digest::SHA256.hexdigest(rsa_key.n.to_s(16))[0, 16].to_i(16)) + name = OpenSSL::X509::Name.parse(subject) + cert.subject = name + cert.issuer = name + cert.public_key = rsa_key.public_key + cert.not_before = Time.now + cert.not_after = Time.now + (valid_years * 365 * 24 * 60 * 60) + cert.sign(rsa_key, OpenSSL::Digest::SHA256.new) + + new(cert) + end +end diff --git a/lib/letter/ini_with_certs.erb b/lib/letter/ini_with_certs.erb index c5bdde16..ca180676 100644 --- a/lib/letter/ini_with_certs.erb +++ b/lib/letter/ini_with_certs.erb @@ -109,7 +109,7 @@

<%= t('certificate') %> :

-
<%= @client.x_509_certificates_content[:a] %>
+
<%= x_509_certificate_a_pem %>

<%= t('hash') %> (SHA-256) :

<%= x_509_certificate_a_hash.scan(/../).join(":") %>

<%= t('confirmation') %>

@@ -218,7 +218,7 @@

<%= t('certificate') %> :

-
<%= @client.x_509_certificates_content[:x] %>
+
<%= x_509_certificate_x_pem %>

<%= t('hash') %> (SHA-256) :

<%= x_509_certificate_x_hash.scan(/../).join(":") %>

@@ -298,7 +298,7 @@

<%= t('certificate') %> :

-
<%= @client.x_509_certificates_content[:e] %>
+
<%= x_509_certificate_e_pem %>

<%= t('hash') %> (SHA-256) :

<%= x_509_certificate_e_hash.scan(/../).join(":") %>

<%= t('confirmation') %>

diff --git a/spec/btf_spec.rb b/spec/btf_spec.rb new file mode 100644 index 00000000..e94dc0fd --- /dev/null +++ b/spec/btf_spec.rb @@ -0,0 +1,71 @@ +RSpec.describe Epics::BTF do + it 'normalizes attributes into the service hash consumed by HeaderRequest' do + btf = described_class.new( + service_name: 'SCT', scope: 'DE', service_option: 'URG', + container: 'ZIP', msg_name: 'pain.001', msg_name_version: '03', msg_variant: '001' + ) + + expect(btf.to_h).to eq( + service_name: 'SCT', + service_option: 'URG', + scope: 'DE', + container: 'ZIP', + msg_name: { name: 'pain.001', version: '03', variant: '001', format: nil } + ) + end +end + +RSpec.describe Epics::BtfMapping do + it 'maps a known upload code to a BTF' do + btf = described_class.upload('CCT') + expect(btf).to be_a(Epics::BTF) + expect(btf.service_name).to eq('SCT') + expect(btf.msg_name).to eq('pain.001') + end + + it 'maps a known download code to a BTF' do + btf = described_class.download('C53') + expect(btf.service_name).to eq('EOP') + expect(btf.container).to eq('ZIP') + expect(btf.msg_name).to eq('camt.053') + end + + it 'maps the extended upload set (XE2/AZV/CIP/...)' do + expect(described_class.upload('XE2').service_name).to eq('MCT') + expect(described_class.upload('AZV').msg_name).to eq('dtazv') + expect(described_class.upload('CIP').service_name).to eq('SCI') + expect(described_class.upload('C2S').scope).to eq('BIL') + end + + it 'maps the extended download set (Z53/BKA/CDZ/...)' do + expect(described_class.download('Z53').service_name).to eq('EOP') + expect(described_class.download('Z53').container).to eq('ZIP') + expect(described_class.download('CDZ').service_option).to eq('SDD') + expect(described_class.download('CRZ').service_option).to eq('SCT') + expect(described_class.download('C5N').service_option).to eq('SCI') + end + + it 'raises a helpful error for unmapped codes' do + expect { described_class.upload('ZZZ') }.to raise_error(ArgumentError, /raw/) + end + + it 'still raises for codes with no H005 form (CD1/FUL/XCT/XDS)' do + %w[CD1 FUL XCT XDS].each do |code| + expect { described_class.upload(code) }.to raise_error(ArgumentError) + end + end + + it 'applies overrides on top of the mapped defaults' do + btf = described_class.download('C53', scope: 'CH', msg_name_version: '04') + expect(btf.service_name).to eq('EOP') # default kept + expect(btf.msg_name).to eq('camt.053') # default kept + expect(btf.scope).to eq('CH') # overridden + expect(btf.msg_name_version).to eq('04') # overridden + end + + it 'ignores nil overrides, keeping the mapped default' do + btf = described_class.download('C53', scope: nil, msg_name_version: nil) + expect(btf.scope).to eq('DE') + expect(btf.msg_name_version).to eq('08') + end +end diff --git a/spec/h005_client_spec.rb b/spec/h005_client_spec.rb new file mode 100644 index 00000000..9e93ba44 --- /dev/null +++ b/spec/h005_client_spec.rb @@ -0,0 +1,331 @@ +RSpec.describe 'EBICS 3.0 (H005) client' do + let(:client) do + Epics::Client.new( + File.open(File.join(File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), + 'secret', 'https://example.com', 'SIZBN001', 'EBIX', 'EBICS', + version: :h005 + ) + end + + describe 'version wiring' do + it { expect(client.ebics_version).to eq(:h005) } + it { expect(client.namespace).to eq('urn:org:ebics:H005') } + it { expect(client.protocol_version).to eq('H005') } + it { expect(client).to be_h005 } + + it 'defaults to H004 when no version is given' do + c = Epics::Client.new(nil, 'secret', 'https://example.com', 'H', 'U', 'P') + expect(c.ebics_version).to eq(:h004) + expect(c.namespace).to eq('urn:org:ebics:H004') + expect(c).not_to be_h005 + end + + it 'rejects unknown versions' do + expect { + Epics::Client.new(nil, 'secret', 'https://example.com', 'H', 'U', 'P', version: :h006) + }.to raise_error(ArgumentError, /Unsupported EBICS version/) + end + end + + describe 'admin order types' do + it { expect(Epics::HPB.new(client).to_xml).to include('HPB') } + it { expect(Epics::HTD.new(client).to_xml).to include('HTD') } + it { expect(Epics::HPB.new(client).to_xml).not_to include('OrderAttribute') } + + context 'XSD validity', if: ebics_xsd_available?(:h005) do + %i[HPB HTD HAA HKD HPD].each do |ot| + it "#{ot} is a valid H005 document" do + expect(Epics.const_get(ot).new(client).to_xml).to be_a_valid_ebics_doc(:h005) + end + end + + it 'INI is a valid H005 document' do + expect(Epics::INI.new(client).to_xml).to be_a_valid_ebics_doc(:h005) + end + + it 'HIA is a valid H005 document' do + expect(Epics::HIA.new(client).to_xml).to be_a_valid_ebics_doc(:h005) + end + end + end + + describe 'key management embeds X.509 certificates (mandatory in H005)' do + it 'embeds a self-signed cert in HIA order data' do + data = Epics::HIA.new(client).order_data + expect(data).to include('urn:org:ebics:H005') + expect(data).to include('X509Certificate') + end + + it 'embeds a self-signed cert in the INI signature order data' do + expect(Epics::INI.new(client).key_signature).to include('X509Certificate') + end + + it 'generates a certificate for each key type' do + %i[a x e].each { |t| expect(client.x_509_certificate(t)).to be_a(Epics::X509Certificate) } + end + + it 'uses the S002 signature namespace and no RSAKeyValue' do + sig = Epics::INI.new(client).key_signature + expect(sig).to include('http://www.ebics.org/S002') + expect(sig).not_to include('RSAKeyValue') + end + + it 'renders the INI letter with the self-signed certificate fingerprints' do + letter = client.ini_letter('Testbank') + fingerprint = client.x_509_certificate_hash(:a).scan(/../).join(':') + + expect(letter).to include(fingerprint) + expect(letter).to include('BEGIN CERTIFICATE') + end + + it 'persists self-signed certificates across dump_keys/extract_keys round trips' do + fingerprint = client.x_509_certificate(:a).fingerprint + + reloaded = Epics::Client.new( + client.send(:dump_keys), 'secret', 'https://example.com', 'SIZBN001', 'EBIX', 'EBICS', + version: :h005 + ) + + expect(reloaded.x_509_certificate(:a).fingerprint).to eq(fingerprint) + end + + it 'does not leak certificate entries into the RSA key set' do + client.x_509_certificate(:a) + + reloaded = Epics::Client.new( + client.send(:dump_keys), 'secret', 'https://example.com', 'SIZBN001', 'EBIX', 'EBICS', + version: :h005 + ) + + expect(reloaded.keys.keys).not_to include(a_string_ending_with('.crt')) + expect(reloaded.certificates.keys).to include('A006.crt') + end + + context 'S002 XSD validity', if: ebics_xsd_available?(:h005) do + let(:s002) do + Nokogiri::XML::Schema(File.open(File.join(File.dirname(__FILE__), 'xsd', 'ebics_signature_S002.xsd'))) + end + + it 'INI signature order data validates against S002' do + errors = s002.validate(Nokogiri::XML(Epics::INI.new(client).key_signature)) + expect(errors).to be_empty + end + end + end + + describe 'HPB imports bank keys from X.509 certificates (H005)' do + let(:bank_auth) { OpenSSL::PKey::RSA.generate(2048) } + let(:bank_enc) { OpenSSL::PKey::RSA.generate(2048) } + + def cert_data(rsa) + Epics::X509Certificate.generate_self_signed(rsa, subject: '/CN=bank').data + end + + let(:hpb_response) do + <<~XML + + + + #{cert_data(bank_auth)} + X002 + allowed by the schema's any-wildcard + + + #{cert_data(bank_enc)} + E002 + + SIZBN001 + + XML + end + + before { allow(client).to receive(:download).with(Epics::HPB).and_return(hpb_response) } + + it 'stores the bank authentication key (X002) from its certificate' do + client.HPB + expect(client.bank_x).to be_a(Epics::Key) + expect(client.bank_x.key.n).to eq(bank_auth.n) + end + + it 'stores the bank encryption key (E002) from its certificate' do + client.HPB + expect(client.bank_e).to be_a(Epics::Key) + expect(client.bank_e.key.n).to eq(bank_enc.n) + end + + context 'when a PubKeyInfo carries neither certificate nor RSAKeyValue' do + let(:hpb_response) do + <<~XML + + + + X002 + + + E002 + + SIZBN001 + + XML + end + + it 'raises a descriptive error' do + expect { client.HPB }.to raise_error(/neither an X509Certificate nor an RSAKeyValue/) + end + end + end + + describe 'HAA lists available BTF services (H005)' do + let(:haa_response) do + <<~XML + + + + EOP + DE + + camt.053 + + + SCT + pain.001 + + + XML + end + + before { allow(client).to receive(:download).with(Epics::HAA).and_return(haa_response) } + + it 'returns parsed BTF services' do + services = client.HAA + expect(services.map(&:service_name)).to eq(%w[EOP SCT]) + expect(services.first.container).to eq('ZIP') + expect(services.first.msg_name).to eq('camt.053') + expect(services.first.msg_name_version).to eq('08') + end + end + + describe 'HTD parses account data and BTF services (H005)' do + let(:htd_response) do + <<~XML + + + + ACME Corp + SIZBN001 + + DE89370400440532013000 + COBADEFFXXX + + + BTD + + EOP + DE + + camt.053 + + Statements + + + BTU + + SCT + pain.001 + + Credit transfer + + + HAC + Acknowledgement + + + + + XML + end + + before { allow(client).to receive(:download).with(Epics::HTD).and_return(htd_response) } + + it 'parses name, iban and bic' do + expect(client.name).to eq('ACME Corp') + expect(client.iban).to eq('DE89370400440532013000') + expect(client.bic).to eq('COBADEFFXXX') + end + + it 'exposes distinct admin order types' do + expect(client.order_types).to eq(%w[BTD BTU HAC]) + end + + it 'exposes the BTF services' do + expect(client.services.map(&:service_name)).to eq(%w[EOP SCT]) + expect(client.services.first.msg_name).to eq('camt.053') + end + end + + describe 'convenience methods route to BTU/BTD under H005' do + it 'CCT builds a BTU with the SCT service' do + order = Epics::BTU.new(client, '', service: Epics::BtfMapping.upload('CCT')) + expect(order.header.to_s).to include('BTU') + expect(order.header.to_s).to include('SCT') + end + + it 'passes per-call overrides through to the rendered BTD Service' do + btf = Epics::BtfMapping.download('C53', scope: 'CH', msg_name_version: '04') + header = Epics::BTD.new(client, service: btf).header.to_s + expect(header).to include('EOP') + expect(header).to include('CH') + expect(header).to include('camt.053') + end + end + + describe 'rejects classic business orders that have no H005 form' do + it 'raises VersionSupportError instead of emitting a malformed order' do + expect { Epics::WSS.new(client).to_xml } + .to raise_error(Epics::VersionSupportError, /not available under EBICS 3.0/) + end + + it 'names the raw BTU/BTD escape hatch in the message' do + expect { Epics::FUL.new(client, '').to_xml } + .to raise_error(Epics::VersionSupportError, /BTU.*BTD|BtfMapping/) + end + + it 'still allows administrative order types (HTD)' do + expect { Epics::HTD.new(client).to_xml }.not_to raise_error + end + end + + describe 'extended convenience methods route to BTU/BTD under H005' do + it 'XE2 builds a BTU with the MCT service' do + order = Epics::BTU.new(client, '', service: Epics::BtfMapping.upload('XE2')) + expect(order.header.to_s).to include('BTU') + expect(order.header.to_s).to include('MCT') + end + + it 'Z53 builds a BTD with the EOP service' do + order = Epics::BTD.new(client, service: Epics::BtfMapping.download('Z53')) + expect(order.header.to_s).to include('BTD') + expect(order.header.to_s).to include('EOP') + end + end +end + +RSpec.describe 'EBICS 2.5 (H004) remains the default and unchanged' do + let(:client) do + Epics::Client.new( + File.open(File.join(File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), + 'secret', 'https://example.com', 'SIZBN001', 'EBIX', 'EBICS' + ) + end + + it 'still emits the classic OrderType/OrderAttribute shape' do + header = Epics::CCT.new(client, '').header.to_s + expect(header).to include('CCT') + expect(header).to include('OZHNN') + expect(header).not_to include('AdminOrderType') + end + + it 'does not auto-embed X.509 certificates' do + expect(Epics::HIA.new(client).order_data).not_to include('X509Certificate') + end +end diff --git a/spec/orders/btd_spec.rb b/spec/orders/btd_spec.rb new file mode 100644 index 00000000..f3ed4c2b --- /dev/null +++ b/spec/orders/btd_spec.rb @@ -0,0 +1,42 @@ +RSpec.describe Epics::BTD do + let(:client) do + Epics::Client.new( + File.open(File.join(File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), + 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS', + version: :h005 + ) + end + + let(:service) do + Epics::BTF.new(service_name: 'EOP', scope: 'DE', container: 'ZIP', msg_name: 'camt.053', msg_name_version: '08') + end + + subject(:order) { described_class.new(client, service: service, from: '2026-01-01', to: '2026-01-31') } + + describe 'H005 envelope' do + it { expect(order.to_xml).to include('xmlns="urn:org:ebics:H005"') } + it { expect(order.to_xml).to include('Version="H005"') } + end + + describe 'OrderDetails / BTF' do + let(:header) { order.header.to_s } + + it { expect(header).to include('BTD') } + it { expect(header).to include('') } + it { expect(header).to include('EOP') } + it { expect(header).to include('DE') } + it { expect(header).to include('') } + it { expect(header).to include('camt.053') } + it { expect(header).to match(%r{\s*2026-01-01\s*2026-01-31\s*}) } + it { expect(header).not_to include('OrderAttribute') } + end + + describe '#to_xml' do + specify { expect(order.to_xml).to be_a_valid_ebics_doc(:h005) } if ebics_xsd_available?(:h005) + end + + describe '#to_receipt_xml' do + before { order.transaction_id = SecureRandom.hex(16) } + it { expect(order.to_receipt_xml).to include('xmlns="urn:org:ebics:H005"') } + end +end diff --git a/spec/orders/btu_spec.rb b/spec/orders/btu_spec.rb new file mode 100644 index 00000000..8ec11dbe --- /dev/null +++ b/spec/orders/btu_spec.rb @@ -0,0 +1,59 @@ +RSpec.describe Epics::BTU do + let(:client) do + Epics::Client.new( + File.open(File.join(File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), + 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS', + version: :h005 + ) + end + + let(:document) { File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml')) } + let(:service) do + Epics::BTF.new(service_name: 'SCT', scope: 'DE', msg_name: 'pain.001', msg_name_version: '03') + end + + subject(:order) { described_class.new(client, document, service: service) } + + describe 'H005 envelope' do + it { expect(order.to_xml).to include('xmlns="urn:org:ebics:H005"') } + it { expect(order.to_xml).to include('Version="H005"') } + end + + describe 'OrderDetails / BTF' do + let(:header) { order.header.to_s } + + it { expect(header).to include('BTU') } + it { expect(header).to include('') } + it { expect(header).to include('SCT') } + it { expect(header).to include('pain.001') } + it { expect(header).to match(%r{}) } + it { expect(header).not_to include('OrderAttribute') } + end + + describe 'signature flag' do + it 'omits SignatureFlag when the order carries no ES' do + order = described_class.new(client, document, service: service, signature_flag: false) + expect(order.header.to_s).not_to include('SignatureFlag') + end + + it 'adds requestEDS for distributed signature' do + order = described_class.new(client, document, service: service, request_eds: true) + expect(order.header.to_s).to include('requestEDS="true"') + end + end + + describe 'H005 upload body' do + it 'includes a DataDigest with the A006 signature version' do + expect(order.to_xml).to match(%r{.+}) + end + end + + describe '#to_xml' do + specify { expect(order.to_xml).to be_a_valid_ebics_doc(:h005) } if ebics_xsd_available?(:h005) + end + + describe '#to_transfer_xml' do + before { order.transaction_id = SecureRandom.hex(16) } + it { expect(order.to_transfer_xml).to include('xmlns="urn:org:ebics:H005"') } + end +end diff --git a/spec/support/ebics_matcher.rb b/spec/support/ebics_matcher.rb index 86c9bef6..44499fcd 100644 --- a/spec/support/ebics_matcher.rb +++ b/spec/support/ebics_matcher.rb @@ -1,22 +1,38 @@ -RSpec::Matchers.define :be_a_valid_ebics_doc do +# Root schema per EBICS protocol version. Drop the official H005 schema set into +# spec/xsd/ (ebics_H005.xsd + its includes) to enable H005 validation. +EBICS_XSD_ROOT = { + h004: 'ebics_H004.xsd', + h005: 'ebics_H005.xsd', +}.freeze + +def ebics_xsd_path(version) + File.join(File.dirname(__FILE__), '..', 'xsd', EBICS_XSD_ROOT.fetch(version)) +end + +# True when the XSD schema set for the given EBICS version is available locally. +def ebics_xsd_available?(version) + File.exist?(ebics_xsd_path(version)) +end + +RSpec::Matchers.define :be_a_valid_ebics_doc do |version = :h004| ## # use #open instead of #read to have the includes working # http://stackoverflow.com/questions/11996326/nokogirixmlschema-syntaxerror-on-schema-load/22971456#22971456 - def xsd - @xsd ||= Nokogiri::XML::Schema(File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'ebics_H004.xsd') )) + def xsd(version) + @xsd ||= Nokogiri::XML::Schema(File.open(ebics_xsd_path(version))) end match do |actual| - xsd.valid?(Nokogiri::XML(actual)) + xsd(version).valid?(Nokogiri::XML(actual)) end failure_message do |actual| - "expected that #{actual} would be a valid EBICS doc:\n\n #{xsd.validate(Nokogiri::XML(actual))}" + "expected that #{actual} would be a valid EBICS doc:\n\n #{xsd(version).validate(Nokogiri::XML(actual))}" end description do "be a valid EBICS document" end -end \ No newline at end of file +end diff --git a/spec/xsd/ebics_H005.xsd b/spec/xsd/ebics_H005.xsd new file mode 100644 index 00000000..149bf263 --- /dev/null +++ b/spec/xsd/ebics_H005.xsd @@ -0,0 +1,11 @@ + + + + ebics_H005.xsd inkludiert alle Schemadateien des EBICS-Protokolls, um die Eindeutigkeit von Element- und Typnamen im EBCIS Namespace zu erzwingen. + ebics_H005.xsd includes all schema files for the EBICS protocol in order to enforce unique element and type names in the EBICS namespace. + + + + + + diff --git a/spec/xsd/ebics_keymgmt_request_H005.xsd b/spec/xsd/ebics_keymgmt_request_H005.xsd new file mode 100644 index 00000000..cb93d3c4 --- /dev/null +++ b/spec/xsd/ebics_keymgmt_request_H005.xsd @@ -0,0 +1,523 @@ + + + + + ebics_keymgmt_request_H005.xsd ist das EBICS-Protokollschema für Schlüsselmanagement-Anfragen (HIA, HPB, HSA, INI). + + + + XML-Signature. + + + + + + + Datentyp für den statischen EBICS-Header (allgemein). + + + + + Hostname des Banksystems. + + + + + Zufallswert; damit wird die Initialisierungsnachricht des Clients einzigartig; nur anzugeben, falls Authentifikationssignatur vorhanden. + + + + + aktueller Zeitstempel zur Begrenzung der serverseitigen Nonce-Speicherung; nur anzugeben, falls Authentifikationssignatur vorhanden. + + + + + Kunden-ID des serverseitig administrierten Kunden. + + + + + Teilnehmer-ID des serverseitig zu diesem Kunden administrierten Teilnehmers. + + + + + technische User-ID für Multi-User-Systeme. + + + + + Kennung des Kundenprodukts bzw. Herstellerkennung oder Name. + + + + + Auftragsdetails. + + + + + Angabe des Sicherheitsmediums, das der Kunde verwendet. + + + + + + + + Datentyp für OrderDetails im statischen EBICS-Header (allgemein). + + + + + Auftragsart. + + + + + + + Datentyp für Element mit Kennung des Kundenprodukts bzw. Herstellerkennung oder Name. + + + + + + Sprachkennzeichen der Kundenproduktversion (gemäß ISO 639). + + + + + Kennung des Herausgebers des Kundenprodukts bzw. des betreuenden Kreditinstituts. + + + + + + + + Datentyp für den leeren variablen EBICS-Header von Key Managemen Aufträgen. + + + + + + + + Anfragestruktur für ungesicherte Auftragsarten HIA (Authentifikations- und Verschlüsselungsschlüssel senden) und INI (bankfachllichen Schlüssel senden). + + + + + + enthält die technischen Transaktionsdaten. + + + + + + enhält alle festen Headereinträge. + + + + + enthält alle variablen Headereinträge. + + + + + + + + + enthält die Auftragsdaten. + + + + + + + + + Transfer von Auftragsdaten. + + + + + + enthält Auftragsdaten. + + + + + + + + + + + + + + + + + + + + + + Datentyp für den statischen EBICS-Header bei ungesicherten Sendeauftragsarten (Aufträge HIA und INI): kein Nonce, kein Timestamp, keine EU-Datei, keine X001 Authentifizierung, keine Verschlüsselung, keine Digests der öffentlichen Bankschlüssel, Nutzdaten komprimiert + + + + + + + Hostname des Banksystems. + + + + + Zufallswert; damit wird die Initialisierungsnachricht des Clients einzigartig; nicht anzugeben für ebicsUnsecuredRequest. + + + + + aktueller Zeitstempel zur Begrenzung der serverseitigen Nonce-Speicherung; nicht anzugeben für ebicsUnsecuredRequest. + + + + + Kunden-ID des serverseitig administrierten Kunden. + + + + + Teilnehmer-ID des serverseitig zu diesem Kunden administrierten Teilnehmers. + + + + + technische User-ID für Multi-User-Systeme. + + + + + Kennung des Kundenprodukts bzw. Herstellerkennung oder Name. + + + + + Auftragsdetails. + + + + + Angabe des Sicherheitsmediums, das der Kunde verwendet. + + + + + + + + + + Datentyp für OrderDetails im statischen EBICS-Header von ebicsUnsecuredRequest. + + + + + + + Auftragsart. + + + + + + + + + Anfragestruktur für Auftragsarten ohne Übertragung der Digests der öffentlichen Bankschlüssel (HPB Bankschlüssel abholen). + + + + + + enthält die technischen Transaktionsdaten. + + + + + + enhält alle festen Headereinträge. + + + + + enthält alle variablen Headereinträge. + + + + + + + + + Authentifikationssignatur. + + + + + enthält optionale Zertifikate (vorgesehen). + + + + + + + + + X.509-Daten des Teilnehmers. + + + + + + + + + + + + Datentyp für den statischen EBICS-Header bei Aufträgen ohne Übertragung der Digests der Bankschlüssel (Auftrag HBP): keine Digests der öffentlichen Bankschlüssel, keine EU-Datei, keine Nutzdaten, OrderId optional!, Nonce, Timestamp, X001 Authentifizierung, Auftragsattribut DZHNN + + + + + + + Hostname des Banksystems. + + + + + Zufallswert; damit wird die Initialisierungsnachricht des Clients einzigartig. + + + + + aktueller Zeitstempel zur Begrenzung der serverseitigen Nonce-Speicherung. + + + + + Kunden-ID des serverseitig administrierten Kunden. + + + + + Teilnehmer-ID des serverseitig zu diesem Kunden administrierten Teilnehmers. + + + + + technische User-ID für Multi-User-Systeme. + + + + + Kennung des Kundenprodukts bzw. Herstellerkennung oder Name. + + + + + Auftragsdetails. + + + + + Angabe des Sicherheitsmediums, das der Kunde verwendet. + + + + + + + + + + Datentyp für OrderDetails im statischen EBICS-Header von ebicsNoPubKeyDigestsRequest. + + + + + + + Auftragsart. + + + + + + + + + The structure for uploads contains order data and the ESs, but without an authentication signature and data digest of bank keys. + Anfragestruktur für Sendeaufträge mit EU-Datei und Nutzdaten aber ohne Authentifizierungssignatur und Digests der Bankschlüssel. + + + + + + Contains technical transaction data. + enthält die technischen Transaktionsdaten. + + + + + + Contains all fixed header entries. + enhält alle festen Headereinträge. + + + + + Contains all mutable header entries. + enthält alle variablen Headereinträge. + + + + + + + + + Contains the order data and the ESs. + enthält die Auftragsdaten und EUs. + + + + + + + + + Transfer of order data and the ESs. + Transfer von Auftragsdaten und EUs. + + + + + + Contains the ESs. + enthält Signaturdaten (EUs). + + + + + + + + + + + + Contains the order data + enthält Auftragsdaten. + + + + + + + + + + + + + + + + + + + + + + Datentyp für den statischen EBICS-Header für ebicsUnsignedRequest.Datentyp für den statischen EBICS-Header bei Aufträgen ohne Authentifizierungssignatur (Auftrag HSA): keine X001 Authentifizierung, keine Digests der öffentlichen Bankschlüssel, EU-Datei, Nutzdaten, Nonce, Timestamp, OrderId, Auftragsattribut OZNNN + + + + + + + Hostname des Banksystems. + + + + + Zufallswert; damit wird die Initialisierungsnachricht des Clients einzigartig; nicht anzugeben bei ebicsUnsignedRequest. + + + + + aktueller Zeitstempel zur Begrenzung der serverseitigen Nonce-Speicherung; nicht anzugeben bei ebicsUnsignedRequest. + + + + + Kunden-ID des serverseitig administrierten Kunden. + + + + + Teilnehmer-ID des serverseitig zu diesem Kunden administrierten Teilnehmers. + + + + + technische User-ID für Multi-User-Systeme. + + + + + Kennung des Kundenprodukts bzw. Herstellerkennung oder Name. + + + + + Auftragsdetails. + + + + + Angabe des Sicherheitsmediums, das der Kunde verwendet. + + + + + + + + + + Datentyp für OrderDetails im statischen EBICS-Header von ebicsUnsignedRequest. + + + + + + + Auftragsart. + + + + + + + diff --git a/spec/xsd/ebics_keymgmt_response_H005.xsd b/spec/xsd/ebics_keymgmt_response_H005.xsd new file mode 100644 index 00000000..dfc33909 --- /dev/null +++ b/spec/xsd/ebics_keymgmt_response_H005.xsd @@ -0,0 +1,137 @@ + + + + + ebics_keymgmt_response_H005.xsd ist das EBICS-Protokollschema für Schlüsselmanagement-Antwortnachrichten (HIA, HPB, HSA, INI). + + + + XML-Signature. + + + + + + + Electronic Banking Internet Communication Standard des Zentralen Kreditausschusses (ZKA): Multibankfähige Schnittstelle zur internetbasierten Kommunikation. + + + + + + enthält die technischen Transaktionsdaten. + + + + + + enhält alle festen Headereinträge. + + + + + + + + enthält alle variablen Headereinträge. + + + + + + + + + enthält die Auftragsdaten und den fachlichen ReturnCode. + + + + + + Transfer von Auftragsdaten; nur bei Download anzugeben (HPB). + + + + + + Informationen zur Verschlüsselung der Auftragsdaten + + + + + + + + + + + + enthält Auftragsdaten. + + + + + + + + + + + + + + + + Antwortcode für den vorangegangenen Transfer. + + + + + + + + + + + + Zeitstempel der letzten Aktualisierung der Bankparameter; nur in der Initialisierungsphase anzugeben. + + + + + + + + + + + + + + + + + + + Datentyp für den variablen EBICS-Header. + + + + + Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen (used for all key management order types except download order type HPB). + + + + + Rückmeldung des Ausführungsstatus mit einer eindeutigen Fehlernummer. + + + + + Klartext der Rückmeldung des Ausführungsstatus. + + + + + + diff --git a/spec/xsd/ebics_orders_H005.xsd b/spec/xsd/ebics_orders_H005.xsd new file mode 100644 index 00000000..30db1213 --- /dev/null +++ b/spec/xsd/ebics_orders_H005.xsd @@ -0,0 +1,2094 @@ + + + + + ebics_orders_H005.xsd contains order-based reference elements and order-based type definitions for EBICS. + ebics_orders_H005.xsd enthält auftragsbezogene Referenzelemente und auftragsbezogene Typdefinitionen für EBICS. + + + + + + + XML-Klartext-Auftragsdaten für neue EBICS-Auftragsarten. + Order data in XML format for new EBICS order types. + + + + + Auftragsdaten für Auftragsart HAA (Antwort: abrufbare Auftragsarten abholen). + Order data for order type HAA (response: receive downloadable order types). + + + + + Auftragsdaten für Auftragsart HCA (Anfrage: Änderung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung). + Order data for order type HCA (request: replace user's keys for authentication and encryption). + + + + + Auftragsdaten für Auftragsart HCS (Anfrage: Schlüsselwechsel aller Schlüssel). + Order data for order type HCS (request: replace all keys). + + + + + Auftragsdaten für Auftragsart HIA (Anfrage: Initialisierung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung). + Order data for order type HIA (request: initialise user's keys for authentication and encryption). + + + + + Order data for order type H3K (request: initialise all three user's keys). + Auftragsdaten für Auftragsart H3K (Anfrage: Initialisierung aller drei Teilnehmerschlüssel). + + + + + Auftragsdaten für Auftragsart HKD (Antwort: Kunden- und Teilnehmerdaten des Kunden abholen). + Order data for order type HKD (response: receive customer-based information on the customer and the customer's users). + + + + Schlüssel zur Identifikation des Kontos. + Key for the identification of the account. + + + + + + + Referenz auf die Konten-Identifikationsschlüssel. + Reference to the account identification keys. + + + + + + + + Auftragsdaten für Auftragsart HPB (Antwort: Transfer der Bankschlüssel). + Order data for order type HPB (response: receive bank's public keys). + + + + + Auftragsdaten für Auftragsart HPD (Antwort: Bankparameter abholen). + Order data for order type HPD (response: receive bank parameters). + + + + + Auftragsdaten für Auftragsart HTD (Antwort: Kunden- und Teilnehmerdaten des Teilnehmers abholen). + Order data for order type HTD (response: receive user-based information on the user's customer and the user herself/himself). + + + + Schlüssel zur Identifikation des Kontos. + Key for the identification of the account. + + + + + + + Referenz auf die Konten-Identifikationsschlüssel. + Reference to the account identification keys. + + + + + + + + Auftragsdaten für Auftragsart HVD (Antwort: VEU-Status abrufen). + Order data for order type HVD (response: receive the status of an order currently stored in the distributed signature processing unit). + + + + + Auftragsdaten für Auftragsart HVS (Anfrage: VEU-Storno). + Order data for order type HVS (request: reject an order currently stored in the distributed signature processing unit). + + + + + Auftragsdaten für Auftragsart HVT (Antwort: VEU-Transaktionsdetails abrufen). + Order data for order type HVT (response: receive transaction details of an order currently stored in the distributed signature processing unit). + + + + + + + + + + Auftragsdaten für Auftragsart HVU (Antwort: VEU-Übersicht abholen). + Order data for order type HVU (response: receive summary of orders currently stored in the distributed signature processing unit). + + + + + Auftragsdaten für Auftragsart HVZ (Antwort: VEU-Übersicht mit Zusatzinformationen abholen). + Order data for order type HVZ (response: receive summary of orders currently stored in the distributed signature processing unit with additional information). + + + + + + XML-Strukturen für bankfachliche Elektronische Unterschriften (EUs). + contains the digital signatures. + + + + + enthält die EU des Kreditinstituts. + contains the digital signatures. + + + + + + zusätzliche Auftragsparameter, die zur Ausführung des Auftrags notwendig sind. + additional order parameters required to execute the order. + + + + + zusätzliche Auftragsparameter für Auftragsart HVD. + additional order parameters for order type HVD. + + + + + zusätzliche Auftragsparameter für Auftragsart HVE. + additional order parameters for order type HVE. + + + + + zusätzliche Auftragsparameter für Auftragsart HVS. + additional order parameters for order type HVS. + + + + + zusätzliche Auftragsparameter für Auftragsart HVT. + additional order parameters for order type HVT. + + + + + zusätzliche Auftragsparameter für Auftragsart HVU. + additional order parameters for order type HVU. + + + + + zusätzliche Auftragsparameter für Auftragsart HVZ. + additional order parameters for order type HVZ. + + + + + zusätzliche Auftragsparameter für Standard-Auftragsarten. + additional order parameters for standard order types. + + + + + + Standard-Requeststruktur für HVx-Aufträge (HVD, HVT, HVE, HVS). + Standard request structure for HVx orders (HVD, HVT, HVE, HVS). + + + + Standard-Requestdaten. + Standard request data. + + + + Kunden-ID des Einreichers des ausgewählten Auftrags. + Customer ID of the presenter of the selected order. + + + + + BTF Service Parameter struktur im Falle von BTU/BTD + Identification of the file format in the case of FUL/FDL + + + + + Auftragsnummer des ausgewählten Auftrags. + Order ID of the selected order. + + + + + + + Marker für Elemente und deren Substrukturen, die authentifiziert werden sollen. + Marker for elements and their substructures that are to be authenticated. + + + + Das zugehörige Element ist mitsamt seinen Unterstrukturen zu authentifizieren. + The element (and its substructures) that belongs to this attribute is to be authenticated. + + + + + + optionales Support-Flag, Default = true. + optional support flag, default = true. + + + + Wird die Funktion unterstützt? + Is this function supported? + + + + + + + EU-Berechtigungsinformationen. + permission information of a user's digital signature. + + + + Unterschriftsberechtigung des Teilnehmers, der unterzeichnet hat. + Authorisation level of the user that signed the order. + + + + + + + + Datentyp für Signaturdaten des Kreditinstituts beim EU-Transfer. + Data type for digital signature data transferred using EBICS. + + + + + bankfachliche Elektronische Unterschrift. + Digital signature (either autorising an order or applied for transportation). + + + + + + + + + + + + + Datentyp für Vorabprüfung (Anfrage). + Data type for pre-validation (request). + + + + Client sendet den Hashwert der Auftragsdaten und alle weiteren Daten, die er im Rahmen der Vorabprüfung zur Verfügung stellen will + + + + Hashwert der zu übertragenden Auftragsdatendatei für die Vorabprüfung. + Hashvalue of the transmitted order data for the prevalidation. + + + + + Kontoangabe zur Kontoberechtigung für diesen Zahlungsverkehrsauftrag bei der Vorabprüfung. + Account information for authorisation checks for the payment order within the prevalidation. + + + + + + + + Datentyp für Kontenberechtigungsdaten zur Vorabprüfung. + Data type for the account authorisation data for the prevalidation. + + + + + + + Summe der Zahlungsverkehrsaufträge dieses Kontos für die Höchstbetragsprüfung der EU. + Total sum of the ordered payments regarding this account in order to check the maximum amount limit of the signature permission grades. + + + + + + + + + Datentyp für den Transfer von Auftragsdaten (Anfrage). + Data type for the transfer of order data (request). + + + + + Transaktionsphase? + + + + Initialisierungsphase: Transfer der Signaturdaten (EUs) und des Transaktionsschlüssels. + Inituialisation phase: Transfer of signatur data (ESs) and transaktion key. + + + + Information zur Verschlüsselung der Signatur- und Auftragsdaten. + Information regarding the encryption of signature and order data. + + + + + + + + + + + + enthält Signaturdaten (EUs). + contains signature data (ESs). + + + + + + + + + + + + Hashwert der Auftragsdaten. + Hashvalue of the order data. + + + + + Additional Information about the order (unstructured, up to 255 characters). + + + + + + Transferphase: Transfer von Auftragsdaten. + Transferphase: Transfer of order data. + + + + enthält Auftragsdaten. + contains order data. + + + + + + + + + + + + + + + + + Datentyp für den Transfer von Auftragsdaten (Antwort). + + + + + Transfer des Sitzungsschlüssels und (optional) der Signaturdaten (EUs); nur in der Initialisierungsphase anzugeben. + Transfer of the session key and (optional) signature data (ESs); to be specified only in the initialisation phase. + + + + Information zur Verschlüsselung der Signatur- und Auftragsdaten. + Information regarding the encryption of signature and order data. + + + + + + + + + + + + enthält Signaturdaten (EUs). + contains signature data (ESs). + + + + + + + + + + + + + enthält Auftragsdaten. + contains order data. + + + + + + + + + + + + + + + Datentyp für den Transfer von Transferquittungen. + Data type for the transfer of transfer receipts. + + + + + Quittierungscode für Auftragsdatentransfer. + Receipt code fpr transfer of order data. + + + + + + + + Datentyp für den Transfer von Antwortcodes. + + + + + Antwortcode für den vorangegangenen Transfer. + response code for the foregoing transfer. + + + + + Zeitstempel der letzten Aktualisierung der Bankparameter. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HAA (Antwort: abrufbare Auftragsarten abholen). + Data type for order data of order type HAA (Response: Download of available order data). + + + + + Liste von Auftragsarten, für die Daten bereit stehen. + List of order types for which data are available. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HCA (Anfrage: Änderung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung). + Data type for order data regarding order type HCA (Request: Update of Subscriber's key for authentication and encryption). + + + + + öffentlicher Authentifikationsschlüssel. + public key for authentication. + + + + + öffentlicher Verschlüsselungsschlüssel. + public key for encryption. + + + + + Kunden-ID. + Partner-ID. + + + + + Teilnehmer-ID. + User-ID. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HCS (Anfrage: Schlüsselwechsel aller Schlüssel). + Data type for order data for order type HCS (Request: Update of all keys). + + + + + öffentlicher Authentifikationsschlüssel. + public key for authentication. + + + + + öffentlicher Verschlüsselungsschlüssel. + public key for encryption. + + + + + + Kunden-ID. + Partner-ID. + + + + + Teilnehmer-ID. + User-ID. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HIA (Anfrage: Initialisierung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung). + Data type for order data for order type HIA (Request: Initialisation of subcriber keys for authentication and encryption). + + + + + öffentlicher Authentifikationsschlüssel. + public key for authentication. + + + + + öffentlicher Verschlüsselungsschlüssel. + public key for encryption. + + + + + Kunden-ID. + Partner-ID. + + + + + Teilnehmer-ID. + User-ID. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart H3K (Anfrage: Initialisierung aller drei Teilnehmerschlüssel). + Order type for order data H3K (request: initialise all three user's keys). + + + + + Key for electronic Signature + Signaturschlüssel. + + + + + Authentication key + Authentifikationsschlüssel. + + + + + Encryption key + Verschlüsselungsschlüssel. + + + + + PartnerID. + Kunden-ID. + + + + + UserID. + Teilnehmer-ID. + + + + + + + Datentyp für Auftragsdaten für Auftragsart HKD (Antwort: Kunden- und Teilnehmerdaten des Kunden abholen). + Order data for order type HKD (response: receive customer based information on the customer and the customer's user. + + + + + Kundendaten. + Customer data. + + + + + Teilnehmerdaten. + User data. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HPB (Antwort: Transfer der Bankschlüssel). + Data type for order data for order type HPB (Response: Transfer of bank keys). + + + + + öffentlicher Authentifikationsschlüssel. + public authentication key + + + + + öffentlicher Verschlüsselungsschlüssel. + public encryption key + + + + + öffentlicher EU-Signaturschlüssel. + public ES key. + + + + + Banksystem-ID. + Host-ID. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HPD (Antwort: Bankparameter abholen). + Data type for order data for order type HPD (Response: Download bank parameters). + + + + + Zugangsparameter. + Access Parameter. + + + + + Protokollparameter. + Protocol Parameter. + + + + + + + Datentyp für HPD-Zugangsparameter. + data type for HPD Access Parameter. + + + + + institutsspezifische IP-Adresse/URL. + individual IP-address/URL of the bank. + + + + + + + Gültigkeitsbeginn für die angegebene URL/IP. + Valid-From-Date of the URL/IP. + + + + + + + + + Institutsbezeichnung. + Name of the bank. + + + + + + + + + + Banksystem-ID. + + + + + + + + Datentyp für HPD-Protokollparameter. + Data type for HPD's parameters regarding the EBICS protocol. + + + + + Spezifikation unterstützter Versionen. + Specification of supported versions.. + + + + + Parameter zur Recovery-Funktion (Wiederaufnahme abgebrochener Übertragungen). + Parameter denoting the recovery function (recovery of aborted transmissions). + + + + + + + + Parameter zur Vorabprüfung (über die Übermittlung der EU hinaus). + Parameter denoting the pre-validation (beyond transmission of signatures). + + + + Optionales Support-Flag, Default = true. + Optional support flag, default = true. + + + + + + + Parameter zum Download von Kunden- und Teilnehmerdaten (Auftragsarten HKD/HTD). + Parameter denoting the download of customer and user data (order types HKD/HTD). + + + + + + + + Parameter zum Abruf von Auftragsarten, zu denen Auftragsdaten verfügbar sind (Auftragsart HAA). + Parameter denoting the reception of order types which provides downloadable order data (order type HAA). + + + + + + + + + + + Datentyp für HPD-Versionsinformationen. + Data type for HPD version information. + + + + + unterstützte EBICS-Protokollversionen (H...). + supported EBICS protocol versions. (H...). + + + + + + + + unterstützte Versionen der Authentifikation (X...). + supported version for authentication (X...). + + + + + + + + unterstützte Versionen der Verschlüsselung (E...). + supported version for encryption (E...). + + + + + + + + unterstützte EU-Versionen (A...). + supported version for ES (A...). + + + + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HTD (Antwort: Kunden- und Teilnehmerdaten des Teilnehmers abholen). + Data type for order data for order type HTD (Response: Download partner- and user data). + + + + + Kundendaten. + Customer data. + + + + + Teilnehmerdaten. + User data. + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HVD (Antwort: VEU-Status abrufen). + Data type for order data for order type HVD (Response: EDS-status). + + + + + Hashwert der Auftragsdaten. + Hash value of the order data. + + + + + Begleitzettel/"Displaydatei" (entspricht der Dateianzeige im Kundenprotokoll gemäß DFÜ-Abkommen). + Accompanying ticket/"display file" (corresponds to the display file of the customer's journal according to the document "DFÜ-Abkommen"). + + + + + Kann die Auftragsdatei im Originalformat abgeholt werden? (HVT mit completeOrderData=true) + Can the order file be downloaded in the original format? (HVT with completeOrderData=true) + + + + + Größe der unkomprimierten Auftragsdaten in Bytes. + Size of the uncompressed order data (byte count). + + + + + Können die Auftragsdetails als XML-Dokument HVTResponseOrderData abgeholt werden? (HVT mit completeOrderData=false) + Can the order details be downloaded as XML document HVTResponseOrderData? (HVT with completeOrderData=false) + + + + + bankfachliche Elektronische Unterschrift des Kreditinstituts über Hashwert und Displaydatei. + Digital Signature issued by the bank, covering the hash value and the accompanying ticket. + + + + + Informationen zu den bisherigen Unterzeichnern. + Information about the already existing signers. + + + + + + + + Datentyp für zusätzliche Auftragsparameter für Auftragsart HVD. + Data type for additional order parameters for order type HVD. + + + + + + + + + Datentyp für zusätzliche Auftragsparameter für Auftragsart HVE. + Data type for additional order parameters for order type HVE. + + + + + + + + + Datentyp für zusätzliche Auftragsparameter für Auftragsart HVS. + Data type for additional order parameters for order type HVS. + + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HVS (Anfrage: VEU-Storno). + Data type for order data for order type HVS (request: EDS cancellation). + + + + + Hashwert der Auftragsdaten des stornierten Auftrags. + Hash value of order data of cancelled order. + + + + + + + + Datentyp für Antwort mit Einzelauftraginfos für Auftragsart HVT (Antwort VEU-Transaktionsdetails abrufen mit completeOrderData="false"). + Data type for a response containing information about single transactions for order type HVT (response: EDS transaction details with completeOrderData="false"). + + + + + Gesamtanzahl der Einzelaufträge für den Auftrag. + Total number of order infos for the order. + + + + + Einzelauftragsinfos. + Particular order content information requested for display matters. + + + + + + + + Datentyp für HVT-Konteninformationen. + Data type for account information regarding order type HVT. + + + + + + + + //MODIFIED - Replaced Element OrderFormat with MsgName// Datentyp für HVT-Auftragsinformationen. + + + + + + kontobezogene Details des Auftrags (Auftraggeber, Empfänger etc.). + account related details of the order (ordering party, receiver etc.). + + + + + Ausführungsdatum. + Execution date. + + + + + + + + + + Betrag. + Amount. + + + + + + + Gutschrift (isCredit = "true") oder Lastschrift (isCredit = "false")? + Credit (isCredit = "true") or debit (isCredit = "false")? + + + + + Währungscode. + Currency code. + + + + + + + + + Textfeld zur weiteren Beschreibung der Transaktion (Verwendungszweck, Auftragsdetails, Kommentar). + text field for additional descriptions regarding the transaction (remittance information, order details, annotations). + + + + + + + Beschreibungstyp. + Description type. + + + + + + Verwendungszweck + remittance information. + + + + + Auftragsdetails + Order details. + + + + + Kommentar + Annotation. + + + + + + + + + + + + + + + Datentyp für HVT-Auftragsflags. + Data type for HVT order flags. + + + + Sollen die Transaktionsdetails als Einzelauftragsinfos (completeOrderData=false) oder als komplette Originaldaten (completeOrderData=true) übertragen werden? (Vorschlag für Default=false) + Are the transaction details so be transmitted as particular order content information requested for display matters or in complete order data file form? (Proposal for Default=false) + + + + + Limit für die zu liefernden Transaktionsdetails, bei completeOrderData=false maximale Anzahl zu liefernder Einzelauftragsinfos, 0 für unbegrenzt (Vorschlag für Default=100). + Limit for the transaction details to be transmitted; if completeOrderData=false, maximum number of details of a particular order; 0 for unlimited number of details (Proposal for Default=100). + + + + + + + + + + Offset vom Anfang der Originalauftragsdatei für die zu liefernden Transaktionsdetails, bei completeOrderData=false bezogen auf laufende Nummer des Einzelauftrags (Vorschlag für Default=0). + Offset position in the original order file which marks the starting point for the transaction details to be transmitted; applies to the sequential number of a particular order if completeOrderData=false (Proposal for Default=0). + + + + + + + + + + + + Datentyp für zusätzliche Auftragsparameter für Auftragsart HVT. + Data type for additional order parameters for order type HVT. + + + + + + spezielle Flags für HVT-Aufträge. + Special order flags for orders of type HVT. + + + + + + + + + + Generische Schlüssel-Wert-Parameter + Generic key-value parameters + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HVU (Antwort: VEU-Übersicht abholen). + Data type for order data for order type HVU (Response: Download EDS overview). + + + + + + + + Auftragsinformationen. + + + + + + + + Datentyp für HVU-Auftragsdetails. + Data type for HVU order details. + + + + + Auftragsart lt. DFÜ-Abkommen des ausgewählten Auftrags. + Type of the order. + + + + + Auftragsnummer lt. DFÜ-Abkommen des ausgewählten Auftrags. + Order number. + + + + + Größe der unkomprimierten Auftragsdaten in Bytes. + Order data size in bytes. + + + + + Informationen zu den Unterschriftsmodalitäten. + Signing information. + + + + + Informationen zu den bisherigen Unterzeichnern. + Information regarding the signer. + + + + + Informationen zum Einreicher. + Information regarding the originator. + + + + + Additional Information about the order (unstructured, up to 255 characters). + Additional Information about the order (unstructured, up to 255 characters). + + + + + + + + Datentyp für zusätzliche Auftragsparameter für Auftragsart HVU. + Data type for additional order parameters for order type HVU. + + + + + Liste von Auftragsarten, für die zur Unterschrift vorliegende Aufträge abgerufen werden sollen; falls nicht angegeben, werden sämtliche für den Teilnehmer unterschriftsfähigen Aufträge abgerufen. + + + + + + + + Datentyp für zusätzliche Auftragsparameter für Auftragsart HVZ. + Data type for additional order parameters for order type HVZ. + + + + + Liste von Auftragsarten, für die zur Unterschrift vorliegende Aufträge abgerufen werden sollen; falls nicht angegeben, werden sämtliche für den Teilnehmer unterschriftsfähigen Aufträge abgerufen. + List of order types that the orders ready to be signed by the requesting user should match; if not specified, a list of all orders ready to be signed by the requesting user is returned. + + + + + + + + Datentyp für Informationen zu den HVU-Unterschriftsmodalitäten. + + + + Ist der Auftrag unterschriftsreif ("true") oder bereits vom Teilnehmer unterschrieben ("false")? + + + + + Anzahl der insgesamt zur Freigabe erforderlichen EUs. + + + + + Anzahl der bereits geleisteten EUs. + + + + + + Datentyp für Informationen zum Ersteller eines HVU-Auftrags. + + + + + Kunden-ID des Einreichers. + + + + + Teilnehmer-ID des Einreichers. + + + + + Name des Einreichers. + + + + + Zeitstempel der Einreichung (d.h. der Übertragung der Auftragsdatei). + + + + + + + + Datentyp für Auftragsdaten für Auftragsart HVZ (Antwort: VEU-Übersicht mit Zusatzinformationen abholen). + Order data for order type HVZ (response: receive summary of orders currently stored in the distributed signature processing unit with additional informations). + + + + + + + + Auftragsinformationen. + Summary of order information. + + + + + + + + Datentyp für HVZ-Auftragsdetails. + + + + + BTF Service Parameter-Struktur des ausgewählten Auftrags. + Type of the order. + + + + + Auftragsnummer lt. DFÜ-Abkommen des ausgewählten Auftrags. + ID number of the order. + + + + + Hashwert der Auftragsdaten. + Hash value of the order data. + + + + + Kann die Auftragsdatei im Originalformat abgeholt werden? (HVT mit completeOrderData=true). + Can the order file be downloaded in the original format? (HVT with completeOrderData=true) + + + + + Größe der unkomprimierten Auftragsdaten in Bytes. + Size of uncompressed order data in Bytes. + + + + + Können die Auftragsdetails als XML-Dokument HVTResponseOrderData abgeholt werden? (HVT mit completeOrderData=false). + Can the order details be downloaded as XML document HVTResponseOrderData? (HVT with completeOrderData=false) + + + + + Zusätzliche Auftragsdetails nur für Zahlungsaufträge. + Order details related to payment orders only. + + + + + Informationen zu den Unterschriftsmodalitäten. + Information regarding the signing modalities of the order. + + + + + Informationen zu den bisherigen Unterzeichnern. + Information regarding the users who already signed the order. + + + + + Informationen zum Einreicher. + Information regarding the originator of the order. + + + + + Additional Information about the order (unstructured, up to 255 characters). + + + + + + + + Standard-Requeststruktur für HVx-Aufträge (HVD, HVT, HVE, HVS). + Standard structure for HVZ OrderDetails related to payment orders + + + + + Anzahl der Zahlungssätze über alle logische Dateien entsprechend Dateianzeige. + Total transaction number for all logical files (from dispay file). + + + + + Summe der Beträge über alle logische Dateien entsprechend Dateianzeige. + Total transaction amount for all logical files (from dispay file). + + + + + + + Nur Gutschriften (isCredit = "true") oder nur Lastschriften (isCredit = "false")? Sonst keine Nutzung des Elements. + + + + + + + + + Auftragswährung (nur bei sortenreinen Zahlungen, sonst keine Angabe). + Order currency (only if identical across all transactions, ship otherwise). + + + + + Informationen aus Dateianzeige der ersten logischen Datei. + Order details from display file for first logical file. + + + + + + Auftraggeber entsprechend Dateianzeige. + Order party information (from display file). + + + + + Erstes Auftraggeberkonto entsprechend Dateianzeige. + First order party account (from display file). + + + + + + + Kontonummer (deutsches Format oder international als IBAN). + Account number (German format or international as IBAN). + + + + + + + Ist die Kontonummer im deutschen Format (international=false) oder im internationalen Format (international=true, IBAN) angegeben? + Account number given in German format (international=false) or in international format (international=true, IBAN)? + + + + + + + + + Kontonummer im freien Format. + Account number in free format. + + + + + + + Formatkennung. + Format type. + + + + + + + + + + + Bankleitzahl (deutsches Format oder international als SWIFT-BIC). + Bank sort code (German format or international as SWIFT-BIC). + + + + + + + Ist die Bankleitzahl im deutschen Format (international=false, BLZ) oder im internationalen Format (international=true, SWIFT-BIC) angegeben? + Bank sort code given in German format (international=false) or in international format (international=true, SWIFT-BIC)? + + + + + nationales Präfix für Bankleitzahlen. + National prefix for bank sort code. + + + + + + + + + Bankleitzahl im freien Format. + Bank sort code in free format. + + + + + + + Formatkennung. + Format type. + + + + + + + + + + + + + + + + + + Datentyp für Informationen zu einem Unterzeichner eines VEU-Auftrags (HVU, HVD). + + + + + Kunden-ID des Unterzeichners. + + + + + Teilnehmer-ID des Unterzeichners. + + + + + Name des Unterzeichners. + + + + + Zeitstempel der Unterzeichnung (d.h. der Übertragung der Unterschrift). + + + + + zusätzliche Informationen zu den Berechtigungen des Teilnehmers, der unterzeichnet hat. + + + + + + + + + + + Datentyp für VEU-Berechtigungsinformationen des Teilnehmers (HKD, HTD). + + + + + Liste von Auftragsarten, für die die Berechtigung des Teilnehmers gültig ist. + List of order types which the user's permission belongs to. + + + + + BTF Service Parameter struktur im Falle von BTU/BTD + Identification of the file format in the case of FUL/FDL + + + + + Verweis auf den Identifikationscode des berechtigten Kontos. + Identification codes of the affected accounts. + + + + + Betragshöchstgrenze, bis zu der die Berechtigung des Teilnehmers gültig ist. + Maximum total amount which the user's permission is valid for. + + + + + + + Unterschriftsklasse, für die der Teilnehmer berechtigt ist; nicht anzugeben bei Download-Auftragsarten. + Authorization level of the user who signed the order; to be omitted for orders of type "download". + + + + + + + Datentyp für VEU-Partnerdaten (HKD, HTD). + Data type for customer data with regard to distributed signatures (order types HKD, HTD). + + + + + Informationen zur Adresse des Kunden. + Information about the customer's adress. + + + + + Informationen zur Kreditinstitutsanbindung des Kunden. + Information about the customer's banking access paramters. + + + + + Informationen zu den Konten des Kunden. + Information about the customer's accounts. + + + + + + + + //MODIFIED//Liste der Auftragsartenbeschränkungen; falls nicht angegeben, gibt es keine Auftragsartenbeschränkungen; falls das Element ohne Service-Element geliefert wird, ist das Konto für keine Auftragsart freigegeben. + List containing the order types which contain this account is restricted to; if omitted, the account is unrestricted; if the list is empty the account is blocked for any order type. + + + + + + + Identifikationscode des Kontos. + + + + + + + + + Informationen zu den Auftragsarten, für die der Kunde berechtigt ist. + Information about order types which the customer is authorised to use. + + + + + + + Datentyp für VEU-Adressinformationen (HKD, HTD). + Data type for address information with regard to distributed signature (order types HKD, HTD). + + + + + Name des Kunden. + Customer's name. + + + + + Straße und Hausnummer. + Street and house number. + + + + + Postleitzahl. + Postal code. + + + + + Stadt. + City. + + + + + Region / Bundesland / Bundesstaat. + Region / province / federal state. + + + + + Land. + Country. + + + + + + + + Datentyp für VEU-Kreditinstitutsinformationen (HKD, HTD). + + + + + Banksystem-ID. + + + + + + + + + Datentyp für VEU-Teilnehmerinformationen (HKD, HTD). + + + + + Teilnehmer-ID. + + + + + + + Status des Teilnehmers. + + + + + + + + + Name des Teilnehmers. + + + + + Informationen zu den Berechtigungen des Teilnehmers. + + + + + + + + Datentyp für VEU-Berechtigungsinformationen zu Auftragsarten (HKD, HTD). + Data type for user permissions with regard to distributed signatures (order types HKD, HTD). + + + + + Administrative EBICS Auftragsart. + + + + + BTF Service Parameter struktur im Falle von BTU/BTD + Identification of the file format in the case of FUL/FDL + + + + + Beschreibung der Auftragsart. + + + + + Anzahl erforderlicher EUs (Default=0). + + + + + + + + Datentyp für zusätzliche Auftragsparameter bei Standard-Auftragsarten. + + + + + Datumsbereich (von-bis). + + + + + + Startdatum (inkl.). + + + + + Enddatum (inkl.). + + + + + + + + + + Attribute zur EBICS-Protokollversion und -revision. + Attributes regarding the protocol version and revision of EBICS. + + + + Version des EBICS-Protokolls (z.B. "H00x"). + Version of the EBICS protocol (e.g. "H00x"). + + + + + Revision des EBICS-Protokolls (z.B. 1). + Revision of the EBICS protocol (e.g. 1). + + + + + + + zusätzliche Auftragsparameter für Auftragsart BTD. + additional order parameters for order type BTD. + + + + + zusätzliche Auftragsparameter für Auftragsart BTU. + additional order parameters for order type BTU. + + + + + Datentyp für BTF Download Parameter + + + + + + + Service name - target system for the further processing of the order + + + + + + + + The file name on the client It can be transmitted optionally + + + + + + + + Datentyp für BTF Upload Parameter + + + + + + + Service name - target system for the further processing of the order + + + + + If not present the order doesn't contain any ES and shall be authorised outside EBICS +If present the order shall be autorised within EBICS: +1. If the attribute VEU is also present the sender desires spooling into the VEU - hence in this case the order is not rejected in the case of not sufficient number of ES +2. If the attribute is not present all necessary ES must be inside the order (else: rejection of the order) + + + + + + + The file name on the client It can be transmitted optionally + + + + + + + + Abstract Type containing all BTF params structures + + + + + Service name - target system for the further processing of the order + + + + + If not present the order doesn't contain any ES and shall be authorised outside EBICS +If present the order shall be autorised within EBICS: +1. If the attribute VEU is also present the sender desires spooling into the VEU - hence in this case the order is not rejected in the case of not sufficient number of ES +2. If the attribute is not present all necessary ES must be inside the order (else: rejection of the order) + + + + + + + + The file name on the client It can be transmitted optionally + + + + + + Datentyp für die Angabe eines (Berichts-) Zeitraums + + + + + + + + + Basis-Datentyp für Kennzeichen mit optionalem Attribut + + + + + + Datentyp für Meldungstyp-String mit optionalen Attributen + + + + + + Variant number of the message type (usable for ISO20022 messages) + + + + + Version number of the message type (usable for ISO20022 messages) + + + + + Encoding format of the message (e.g. XML, ASN1, JSON, PDF) + + + + + + + + + + + + + Basisdatentyp für BTF-Service Parameter Set + + + + + Service Code name: External list specified and maintained by EBICS. Basis is the "SWIFT-list" for the field "description" (SCT, DCT, XCT, SDD, DDD, STM, REP...) plus additional codes needed for further services + + + + + Specifies whose rules have to be taken into account for the service. This means which market / comminity has defined the rules. +If the element is absent a global definition for the service is assumed. +External list specified and maintained by EBICS. In addition the following codes may be used: +2-character ISO country code or a 3-character issuer code (defined by EBICS) + + + + + Service Option Code +Additional option for the service (also depends on used scope) + + + + + Container flag. If present, data is provided/requested in a container format specified in the attribute of the flag + + + + + Name of the message, e.g. pain.001 or mt101 National message names (issued by DK, CFONB or SIC are also allowed) + + + + + + + Type is arestriction of the generic ServiceType, defining the mandatory elements + + + + + + + Service Code name: External list specified and maintained by EBICS. Basis is the "SWIFT-list" for the field "description" (SCT, DCT, XCT, SDD, DDD, STM, REP...) plus additional codes needed for further services + + + + + Specifies whose rules have to be taken into account for the service. This means which market / comminity has defined the rules. +If the element is absent a global definition for the service is assumed. +External list specified and maintained by EBICS. +In addition the following codes may be used: +2-character ISO country code or a 3-character issuer code (defined by EBICS) + + + + + Service Option Code + Additional option for the service (also depends on used scope) + + + + + Container flag. If present, data is provided/requested in a container format specified in the attribute of the flag + + + + + Name of the message, e.g. pain.001 or mt101 National message names (issued by DK, CFONB or SIC are also allowed) + + + + + + + + + Container flag. If present, data is provided/requested in a container format specified in the attribute of the flag + + + + + + Specifies the container type - External Codelist defined by EBICS (starting values: XML, ZIP, SVC) + + + + + + + + Datentyp für BTF Signatur-Flag (ersetzt Orderkennzeichen) + + + + + + If present the sender desires spooling into EBICS distributed signature queue, only "true" is allowed + + + + + + + + Datentyp zur Kennzeichnung von Auftragsartenbeschränkungen + + + + + Service Parameter-Sets von nicht unterstützten BTF-Auftragsarten + + + + + + diff --git a/spec/xsd/ebics_request_H005.xsd b/spec/xsd/ebics_request_H005.xsd new file mode 100644 index 00000000..dc7ad70a --- /dev/null +++ b/spec/xsd/ebics_request_H005.xsd @@ -0,0 +1,349 @@ + + + + + ebics_request_H005.xsd ist das EBICS-Protokollschema für Anfragen. + ebics_request_H005.xsd is the appropriate EBICS protocol schema for standard requests. + + + + + + + Electronic Banking Internet Communication Standard of the EBICS SCRL: Multibankfähige Schnittstelle zur internetbasierten Kommunikation. + Electronic Banking Internet Communication Standard der EBICS SCRL: multi-bank capable interface for internet-based communication. + + + + + + enthält die technischen Transaktionsdaten. + contains the transaction-driven data. + + + + + + enhält alle festen Headereinträge. + contains the static header entries. + + + + + enthält alle variablen Headereinträge. + contains the mutable header entries. + + + + + + + + + + enthält die Auftragsdaten, EU(s) und weitere Nutzdaten. + contains order data, order signature(s) and further data referring to the current order. + + + + + + + + + X.509-Daten des Teilnehmers. + X.509 data of the user. + + + + + Welche Transaktionsphase? + Which transaction phase? + + + + Initialisierungs- und Transferphase. + Initialisation or transfer phase. + + + + Daten zur Vorabprüfung; nur anzugeben in der Initialisierungsphase bei Uploads mit Auftragsattribut OZH (EUs + Auftragsdaten). + Data sent for pre-validation; mandatory for initialisation phase during uploads using order attribute OZH (order signature(s) + order data). + + + + + + + + + + + + Transfer von Signatur- bzw. Auftragsdaten; nur bei Upload anzugeben. + Transfer of signature or order data; mandatory for uploads only. + + + + + + Quittierungsphase nach Download. + Receipt phase after download. + + + + Quittierung des Transfers. + Receipt of transfer. + + + + + + + + + + + + + + + + + + + + + + Datentyp für den statischen EBICS-Header. + Data type for the static EBICS header. + + + + + Hostname des Banksystems. + + + + + Transaktionsphase? + Transaction phase? + + + + Initialisierungsphase. + Initialisation phase. + + + + Zufallswert; damit wird die Initialisierungsnachricht des Clients einzigartig. + Random value, ensures the uniqueness of the client's message during initialisation phase. + + + + + aktueller Zeitstempel zur Begrenzung der serverseitigen Nonce-Speicherung. + current timestamp, used to limit storage space for nonces on the server. + + + + + Kunden-ID des serverseitig administrierten Kunden. + ID of the partner = customer, administered on the server. + + + + + Teilnehmer-ID des serverseitig zu diesem Kunden administrierten Teilnehmers. + ID of the user that is assigned to the given customer, administered on the server. + + + + + technische User-ID für Multi-User-Systeme. + ID of the system for multi-user systems. + + + + + Kennung des Kundenprodukts bzw. Herstellerkennung oder Name. + software ID / manufacturer ID / manufacturer's name of the customer's software package. + + + + + + + Sprachkennzeichen der Kundenproduktversion (gemäß ISO 639). + Language code of the customer's software package according to ISO 639. + + + + + Kennung des Herausgebers des Kundenprodukts bzw. des betreuenden Kreditinstituts. + ID of the manufacturer / financial institute providing support for the customer's software package. + + + + + + + + + Auftragsdetails. + order details. + + + + + Hashwerte der erwarteten öffentlichen Schlüssel (Verschlüsselung, Signatur, Authentifikation) des Kreditinstituts. + Digest values of the expected public keys (authentication, encryption, signature) owned by the financial institute. + + + + + + Hashwert des Authentifikationsschlüssels. + Digest value of the public authentication key. + + + + + + + Version des Authentifikationsverfahrens. + Version of the algorithm used for authentication. + + + + + + + + + Hashwert des Verschlüsselungsschlüssels. + Digest value of the public encryption key. + + + + + + + Version des Verschlüsselungsverfahrens. + Version of the algorithm used for encryption. + + + + + + + + + Hashwert des Signaturschlüssels. + Digest value of the public signature key. + + + + + + + Version des Signaturverfahrens. + Version of the algorithm used for signature creation. + + + + + + + + + + + + Angabe des Sicherheitsmediums, das der Kunde verwendet. + Classification of the security medium used by the customer. + + + + + Gesamtsegmentanzahl für diese Transaktion; nur bei Uploads anzugeben. + Total number of segments for this transaction; mandatory for uploads only. + + + + + + + Transfer- und Quittierungsphase. + Transfer or receipt phase. + + + + eindeutige, technische Transaktions-ID; wird vom Server vergeben. + unique transaction ID, provided by the server. + + + + + + + + + Datentyp für den variablen EBICS-Header. + Data type for the mutable EBICS header. + + + + + Phase, in der sich die Transaktion gerade befindet; wird bei jedem Transaktionsschritt vom Client gesetzt und vom Server übernommen. + Current phase of the transaction; this information is provided by the client for each step of the transaction, and the server adopts the setting. + + + + + enthält die Nummer des aktuellen Segments, welches gerade übertragen oder angefordert wird; nur anzugeben bei TransactionPhase=Transfer. + contains the number of the segment which is currently being transmitted or requested; mandatory for transaction phase 'Transfer' only. + + + + + + + Ist dies das letzte Segment der Übertragung? + Is this segment meant to be the last one regarding this transmission? + + + + + + + + + + + + //MODIFIED - Removed OrderAtribute ELEMENT// Datentyp für Auftragsdetails im statischen EBICS-Header. + Data type for order details stored in the static EBICS header. + + + + + //MODIFIED - Umbenannt von OrderType// Auftragsart. + type code of the order. + + + + + + + + + + Auftragsnummer für Sendeaufträge gemäß DFÜ-Abkommen. + ID of the (upload) order, formatted in accordance with the document "DFÜ-Abkommen". + + + + + + diff --git a/spec/xsd/ebics_response_H005.xsd b/spec/xsd/ebics_response_H005.xsd new file mode 100644 index 00000000..841286b7 --- /dev/null +++ b/spec/xsd/ebics_response_H005.xsd @@ -0,0 +1,167 @@ + + + + + ebics_response_H005.xsd ist das EBICS-Protokollschema für Antwortnachrichten. + ebics_response_H005.xsd is the appropriate EBICS protocol schema for standard responses. + + + + XML-Signature. + + + + + + + Electronic Banking Internet Communication Standard des Zentralen Kreditausschusses (ZKA): Multibankfähige Schnittstelle zur internetbasierten Kommunikation. + Electronic Banking Internet Communication Standard of the "Zentraler Kreditausschuss (ZKA)": multi-bank capable interface for internet-based communication. + + + + + + enthält die technischen Transaktionsdaten. + contains the transaction-driven data. + + + + + + enhält alle festen Headereinträge. + contains the static header entries. + + + + + enthält alle variablen Headereinträge. + contains the mutable header entries. + + + + + + + + + Authentifikationssignatur. + Authentication signature. + + + + + enthält die Auftragsdaten, EU(s) und weitere Nutzdaten. + contains order data, order signature(s) and further data referring to the current order. + + + + + + Transfer von Auftragsdaten; nur bei Download anzugeben. + Transfer of signature or order data; mandatory for downloads only. + + + + + fachlicher Antwortcode für den vorangegangenen Request. + order-related return code of the previous request. + + + + + + + + + + + + Zeitstempel der letzten Aktualisierung der Bankparameter; nur in der Initialisierungsphase anzugeben. + timestamp indicating the latest update of the bank parameters; may be set during initialisation phase only. + + + + + + + + + + + + + + + + + + + + //TODO - Modify anotation TransactionID// Datentyp für den statischen EBICS-Header. + Data type for the static EBICS header. + + + + + eindeutige, technische Transaktions-ID; wird vom Server vergeben, falls OrderAttribute entweder gleich "OZHNN" oder gleich "DZHNN" ist und falls tatsächlich eine Transaktion erzeugt wurde. + unique transaction ID, provided by the server if and only if the order attribute is set to either "OZHNN" or "DZHNN" and if a transaction has been established actually. + + + + + Gesamtsegmentanzahl für diese Transaktion; nur bei Downloads in der Initialisierungsphase anzugeben. + Total number of segments for this transaction; mandatory for downloads in initialisation phase only. + + + + + + + Datentyp für den variablen EBICS-Header. + Data type for the mutable EBICS header. + + + + + Phase, in der sich die Transaktion gerade befindet; wird bei jedem Transaktionsschritt vom Client gesetzt und vom Server übernommen. + Current phase of the transaction; this information is provided by the client for each step of the transaction, and the server adopts the setting. + + + + + enthält die Nummer des aktuellen Segments, welches gerade übertragen oder angefordert wird; nur anzugeben bei TransactionPhase=Transfer und (bei Download) TransactionPhase=Initialisation. + contains the number of the segment which is currently being transmitted or requested; mandatory for transaction phases 'Transfer' and (for downloads) 'Initialisation' only. + + + + + + + Ist dies das letzte Segment der Übertragung? + + + + + + + + + Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen. + + + + + Rückmeldung des technischen Status mit einer eindeutigen Fehlernummer. + Return code indicating the technical status. + + + + + Klartext der Rückmeldung des technischen Status. + Textual interpretation of the returned technical status code. + + + + + + diff --git a/spec/xsd/ebics_signature_S002.xsd b/spec/xsd/ebics_signature_S002.xsd new file mode 100644 index 00000000..3127faa7 --- /dev/null +++ b/spec/xsd/ebics_signature_S002.xsd @@ -0,0 +1,177 @@ + + + + + + ebics_signature enthält Typdefinitionen für elektronische Unterschriften der Versionen A005, A006 und folgende. + ebics_EU contains type definitions for electronic signatures: versions A005, A006 and et sqq. + + + + + XML-Strukturen für bankfachliche Elektronische Unterschriften (EUs). + contains the digital signatures. + + + + + enthält die EUs der Teilnehmer. + contains the digital signatures. + + + + + Datentyp für Signaturdaten des Teilnehmers beim EU-Transfer. + Data type for digital signature data transferred using EBICS. + + + + + bankfachliche Elektronische Unterschrift oder Transportunterschrift (strukturiertes Format). + Digital signature (either autorising an order or applied for transportation), structured format. + + + + + + + + Datentyp für kryptographische Unterschriften. + + + + + + bankfachliche Elektronische Unterschrift oder Transportunterschrift (strukturiertes Format). + Digital signature (either autorising an order or applied for transportation), structured format. + + + + + Datentyp für bankfachliche Elektronische Unterschrift oder Transportunterschrift (strukturiertes Format). + Data type according for a digital signature (either autorising an order or applied for transportation), structured format. + + + + + Version des Signaturverfahrens. + Version of the algorithm used for signature creation. + + + + + Digitale Signatur. + Digital signature. + + + + + Kunden-ID des Unterzeichners. + Customer ID of the signer. + + + + + Teilnehmer-ID. + User ID. + + + + + Parameter zur X.509-Funktionalität + Parameter for X509Data + + + + + + + Datentyp für eine Kunden-ID. + + + + + + + + Datentyp für eine Teilnehmer-ID. + + + + + + + + Datentyp für Versionsnummern zur Elektronischen Unterschrift (EU). + + + + + + + + + + Element für Public Key Dateien unabhängig von der Auftragsart / Geschäftsvorfall. + + + + + Datentyp für Public Key Dateien unabhängig von der Auftragsart / Geschäftsvorfall. + + + + + öffentlicher Signaturschlüssel. + + + + + Kunden-ID. + + + + + Teilnehmer-ID. + + + + + + + + öffentlicher Signaturschlüssel. + + + + + Datentyp für öffentliche bankfachliche Schlüssel. + + + + + + + Version des EU-Signaturverfahrens. + + + + + + + + + Datentyp für die Darstellung eines öffentlichen RSA-Schlüssels als Exponent-Modulus-Kombination oder als X509-Zertifikat. + + + + + + + + + Datentyp für Zeitstempel. + + + + diff --git a/spec/xsd/ebics_types_H005.xsd b/spec/xsd/ebics_types_H005.xsd new file mode 100644 index 00000000..ea13f06b --- /dev/null +++ b/spec/xsd/ebics_types_H005.xsd @@ -0,0 +1,1885 @@ + + + + + + + ebics_types_H005.xsd enthält einfache Typdefinitionen für EBICS. + + + + Datentyp für EBICS-Versionsnummern. + + + + + + + + + Datentyp für EBICS-Revisionsnummern. + + + + + + + + Datentyp für Versionsnummern zur Verschlüsselung. + + + + + + + + Datentyp für Versionsnummern zur Elektronischen Unterschrift (EU). + + + + + + + + + Datentyp für Versionsnummern zur Authentifikation. + + + + + + + + + Datentyp für Versionsnummern zur Verschlüsselung, Signatur und Authentifkation. + + + + + + Datentyp für Währungen (Grundtyp). + + + + + + + + + dreistelliger Währungscode gemäß ISO 4217. + + + + + + Afghanistan: Afghani + + + + + Albanien: Lek + + + + + Armenien: Dram + + + + + Niederländische Antillen: Gulden + + + + + Angola: Kwanza + + + + + Argentinien: Peso + + + + + Australien: Dollar + + + + + Aruba: Florin + + + + + Aserbaidschan: Manat + + + + + Bosnien und Herzegowina: Konvertible Mark + + + + + Barbados: Dollar + + + + + Bangladesch: Taka + + + + + Bulgarien: Lew + + + + + Bahrain: Dinar + + + + + Bermuda: Dollar + + + + + Brunei: Dollar + + + + + Bolivien: Boliviano + + + + + Brasilien: Real + + + + + Bahamas: Dollar + + + + + Bhutan: Ngultrum + + + + + Botswana: Pula + + + + + Weißrussland (Belarus): Rubel + + + + + Belize: Dollar + + + + + Kanada: Dollar + + + + + Demokratische Republik Kongo: Franc + + + + + Schweiz: Franken + + + + + Chile: Peso + + + + + China (Volksrepublik): Renminbi Yuan + + + + + Kolumbien: Peso + + + + + Costa Rica: Colón + + + + + Serbien: Dinar + + + + + Kuba: Peso + + + + + Kap Verde: Escudo + + + + + Zypern (griechischer Teil): Pfund + + + + + Tschechien: Krone + + + + + Dschibuti: Franc + + + + + Dänemark: Krone + + + + + Dominikanische Republik: Peso + + + + + Algerien: Dinar + + + + + Ecuador (bis 2000): Sucre + + + + + Estland: Krone + + + + + Ägypten: Pfund + + + + + Äthiopien: Birr + + + + + Europäische Währungsunion: Euro + + + + + Fidschi: Dollar + + + + + Falklandinseln: Pfund + + + + + Vereinigtes Königreich: Pfund + + + + + Georgien: Lari + + + + + Ghana: Cedi + + + + + Gibraltar: Pfund + + + + + Gambia: Dalasi + + + + + Guinea: Franc + + + + + Guatemala: Quetzal + + + + + Guyana: Dollar + + + + + Hongkong: Dollar + + + + + Honduras: Lempira + + + + + Kroatien: Kuna + + + + + Haiti: Gourde + + + + + Ungarn: Forint + + + + + Indonesien: Rupiah + + + + + Israel: Schekel + + + + + Indien: Rupie + + + + + Irak: Dinar + + + + + Iran: Rial + + + + + Island: Krone + + + + + Jamaika: Dollar + + + + + Jordanien: Dinar + + + + + Japan: Yen + + + + + Kenia: Schilling + + + + + Kirgisistan: Som + + + + + Kambodscha: Riel + + + + + Komoren: Franc + + + + + Nordkorea: Won + + + + + Südkorea: Won + + + + + Kuwait: Dinar + + + + + Kaimaninseln: Dollar + + + + + Kasachstan: Tenge + + + + + Laos: Kip + + + + + Libanon: Pfund + + + + + Sri Lanka: Rupie + + + + + Liberia: Dollar + + + + + Lesotho: Loti + + + + + Litauen: Litas + + + + + Lettland: Lats + + + + + Libyen: Dinar + + + + + Marokko: Dirham + + + + + Moldawien: Leu + + + + + Madagaskar: Franc + + + + + Mazedonien: Denar + + + + + Myanmar: Kyat + + + + + Mongolei: Tugrik + + + + + Macau: Pataca + + + + + Mauretanien: Ouguiya + + + + + Malta: Lira + + + + + Mauritius: Rupie + + + + + Malediven: Rufiyaa + + + + + Malawi: Kwacha + + + + + Mexiko: Peso + + + + + Malaysia: Ringgit + + + + + Mosambik: Metical + + + + + Namibia: Dollar + + + + + Nigeria: Naira + + + + + Nicaragua: Cordoba Oro + + + + + Norwegen: Krone + + + + + Nepal: Rupie + + + + + Neuseeland: Dollar + + + + + Oman: Rial + + + + + Panama: Balboa + + + + + Peru: Nuevo Sol + + + + + Papua-Neuguinea: Kina + + + + + Philippinen: Peso + + + + + Pakistan: Rupie + + + + + Polen: Zloty + + + + + Paraguay: Guaraní + + + + + Katar: Riyal + + + + + Rumänien: Leu + + + + + Russland: Rubel + + + + + Ruanda: Franc + + + + + Saudi-Arabien: Riyal + + + + + Salomonen: Dollar + + + + + Seychellen: Rupie + + + + + Sudan: Dinar + + + + + Schweden: Krone + + + + + Singapur: Dollar + + + + + St. Helena: Pfund + + + + + Slowenien: Tolar + + + + + Slowakei: Krone + + + + + Sierra Leone: Leone + + + + + Somalia: Schilling + + + + + Suriname: Dollar + + + + + São Tomé und Príncipe: Dobra + + + + + El Salvador: Colón + + + + + Syrien: Pfund + + + + + Swasiland: Lilangeni + + + + + Thailand: Baht + + + + + Tadschikistan: Somoni + + + + + Turkmenistan: Manat + + + + + Tunesien: Dinar + + + + + Tonga: Pa'anga + + + + + Türkei: Lira + + + + + Türkei: Neue Lira (ab 2005) + + + + + Trinidad und Tobago: Dollar + + + + + Taiwan: Dollar + + + + + Tansania: Schilling + + + + + Ukraine: Hrywnja + + + + + Uganda: Shilling + + + + + USA: Dollar + + + + + Uruguay: Peso + + + + + Usbekistan: Sum + + + + + Venezuela: Bolivar + + + + + Vietnam: Dong + + + + + Vanuatu: Vatu + + + + + Samoa: Tala + + + + + Zentralafrikanische Wirtschafts- und Währungsunion: CFA-Franc + + + + + Ostkaribische Währungsunion: Dollar + + + + + Westafrikanische Wirtschafts- und Währungsunion: CFA-Franc + + + + + Neukaledonien: CFP-Franc + + + + + Spezialcode für Testzwecke; keine existierende Währung + + + + + keine Währung + + + + + Jemen: Rial + + + + + Südafrika: Rand + + + + + Sambia: Kwacha + + + + + Simbabwe: Dollar + + + + + + + Datentyp für einen Betragswert (ohne Währung). + + + + + + + + + Datentyp für einen Betrag inkl. Währungscode-Attribut (Default = "EUR"). + + + + + + Währungscode, Default="EUR". + Currency code, default setting is "EUR". + + + + + + + + Datentyp für die Transaktions-ID. + + + + + + + + Datentyp für Nonces. + + + + + + + + Datentyp für die Instituts-ID. + + + + + + + + Datentyp für die Host-ID. + + + + + + + + Datentyp für die Kundenprodukt-ID. + + + + + + + + Datentyp für das Sprachkennzeichen des Kundenprodukts. + + + + + + + + Datentyp für allgemeine Auftragsarten (Grundtyp). + + + + + + + + + Datentyp für eine Auftragsnummer lt. DFÜ-Abkommen. + + + + + + + + + Datentyp für das Sicherheitsmedium. + + + + + + + + + Datentyp für die Segmentnummer. + + + + + + + + Datentyp für die Gesamtsegmentanzahl. + + + + + + + + Datentyp für die Gesamtanzahl der Einzelauftraginfos. + + + + + + + + Datentyp für die Transaktionsphase. + + + + + Transaktionsinitialisierung + + + + + Auftragsdatentransfer + + + + + Quittungstransfer + + + + + + + Datentyp für Zeitstempel. + + + + + + Datentyp für Datumswerte. + + + + + + Datentyp für eine Teilnehmer-ID. + + + + + + + + + Datentyp für eine Kunden-ID. + + + + + + + + + Datentyp für eine Konten-ID. + + + + + + + + Datentyp für eine Kontonummer (national/international). + + + + + + + + + Datentyp für eine Bankleitzahl (national/international). + + + + + + + + + Datentyp für ein nationales BLZ-Präfix. + + + + + + + + Datentyp für eine Kontonummer (freies Format). + + + + + + + + Datentyp für eine Bankleitzahl (freies Format). + + + + + + + + Datentyp für den Namen des Kontoinhabers. + + + + + + Datentyp für die Kontobeschreibung. + + + + + + Datentyp für Kontoinformationen. + + + + + + Kontonummer (deutsches Format und/oder international als IBAN). + Account number (German format and/or international=IBAN). + + + + + + + Ist die Kontonummer im deutschen Format (international=false) oder im internationalen Format (international=true, IBAN) angegeben? + Is the account number specified using the national=German or the international=IBAN format? + + + + + + + + + Kontonummer im freien Format. + Account in free format. + + + + + + + Formatkennung. + Format identification. + + + + + + + + + + + Bankleitzahl (deutsches Format und/oder international als SWIFT-BIC). + Bank code (German and/or international=SWIFT-BIC). + + + + + + + Ist die Bankleitzahl im deutschen Format (international=false, BLZ) oder im internationalen Format (international=true, SWIFT-BIC) angegeben? + Is the bank code specified using the national=German or the international SWIFT-BIC format? + + + + + nationales Präfix für Bankleitzahlen. + National=German prefix for bank codes. + + + + + + + + + Bankleitzahl im freien Format. + Bank code in free format. + + + + + + + Formatkennung. + Format identification. + + + + + + + + + + Name des Kontoinhabers. + Name of the account holder. + + + + + + Währungscode für dieses Konto, Default=EUR. + Currency code for this account, Default=EUR. + + + + + Kontobeschreibung. + Description of this account. + + + + + + Datentyp für die Rolle eines Zahlungsverkehrskontos innerhalb einer Transaktion. + + + + + Auftraggeberkonto + + + + + Empfängerkonto + + + + + Gebührenkonto + + + + + andere Kontorolle + + + + + + + Datentyp für die Rolle eines Kreditinstituts innerhalb einer Transaktion (repräsentiert durch die Bankleitzahl). + + + + + Auftraggeberbank + + + + + Empfängerbank + + + + + Korrespondenzbank + + + + + andere Bankrolle + + + + + + + Datentyp für die Rolle eines Kontoinhabers innerhalb einer Transaktion. + + + + + Auftraggeber + + + + + Empfänger + + + + + Überbringer, Einreicher + + + + + andere Rolle + + + + + + + Datentyp für Kontoinformationen inkl. der Eigenschaftszuordnung innerhalb einer Zahlungstransaktion. + + + + + + Kontonummer (deutsches Format oder international als IBAN). + Kontonummer (Account number (German format and/or international = IBAN). + + + + + + + Rolle des Kontos innerhalb der Zahlungstransaktion. + Role of the account during the transaction. + + + + + Textuelle Beschreibung der Funktion, falls role=Other ausgewählt wird. + Textual description of the role the account place during the transaction; use only if the corresponding 'role' field is set to 'other'. + + + + + Ist die Kontonummer im deutschen Format (international=false) oder im internationalen Format (international=true, IBAN) angegeben? + Is the account number specified using the national=German or the international=IBAN format? + + + + + + + + + Kontonummer im freien Format. + Account in free format. + + + + + + + Rolle des Kontos innerhalb der Zahlungstransaktion. + Role of the account during the transaction. + + + + + Textuelle Beschreibung der Funktion, falls role=Other ausgewählt wird. + Textual description of the role the account place during the transaction; use only if the corresponding 'role' field is set to 'other'. + + + + + Formatkennung. + Format identification. + + + + + + + + + + + Bankleitzahl (deutsches Format oder international als SWIFT-BIC). + Bank code (German and/or international=SWIFT-BIC). + + + + + + + Rolle des kontoführenden Instituts innerhalb der Zahlungstransaktion. + Role of the bank during the transaction. + + + + + Textuelle Beschreibung der Funktion, falls role=Other ausgewählt wird. + Textual description of the role the account place during the transaction; use only if the corresponding 'role' field is set to 'other'. + + + + + Ist die Bankleitzahl im deutschen Format (international=false, BLZ) oder im internationalen Format (international=true, SWIFT-BIC) angegeben? + Is the bank code specified using the national=German or the international=SWIFT-BIC format? + + + + + nationales Präfix für Bankleitzahlen. + National=German prefix for bank codes. + + + + + + + + + Bankleitzahl im freien Format. + Bank code in free format. + + + + + + + Rolle des kontoführenden Instituts innerhalb der Zahlungstransaktion. + Role of the bank during the transaction. + + + + + Textuelle Beschreibung der Funktion, falls role=Other ausgewählt wird. + Textual description of the role the account place during the transaction; use only if the corresponding 'role' field is set to 'other'. + + + + + Formatkennung. + Format identification. + + + + + + + + + + Name des Kontoinhabers. + Name of the account holder. + + + + + + + Rolle des Kontoinhabers innerhalb der Zahlungstransaktion. + Role of the account holder during the transaction. + + + + + Textuelle Beschreibung der Rolle, falls role=Other ausgewählt wird. + Textual description of the role the account holder place during the transaction; use only if the corresponding 'role' field is set to 'other'. + + + + + + + + + + Währungscode für dieses Konto, Default=EUR. + Currency code for this account, Default=EUR. + + + + + Kontobeschreibung. + Description of this account. + + + + + + Datentyp für binäre Signaturdaten (komprimiert, verschlüsselt und kodiert). + + + + + + Datentyp für binäre Auftragsdaten (komprimiert, verschlüsselt und kodiert). + + + + + + Datentyp für Berechtigungsklassen zur Elektronischen Unterschrift. + + + + + + Einzelunterschrift + + + + + Erstunterschrift + + + + + Zweitunterschrift + + + + + Transportunterschrift + + + + + + + Listentyp für Berechtigungsklassen zur Elektronischen Unterschrift. + + + + + + Datentyp für Hashfunktionen. + + + + + + Datentyp für Hashwerte. + + + + + + + + + Version des Signaturverfahrens. + Version of the algorithm used for signature creation. + + + + + + + + Datentyp für kryptographische Unterschriften. + + + + + + Datentyp für symmetrische Schlüssel. + + + + + + Datentyp für Hashwerte und Attribute von öffentlichen Schlüsseln. + + + + + + Hashalgorithmus. + Name of the used hash algorithm. + + + + + + + + Datentyp für die Darstellung eines öffentlichen RSA-Schlüssels als Exponent-Modulus-Kombination oder als X509-Zertifikat. + + + + + + + + + Datentyp für öffentliche Verschlüsselungsschlüssel. + + + + + + + Version des Verschlüsselungsverfahrens. + + + + + + + + + Datentyp für öffentlichen Authentfikationsschlüssel. + + + + + + + Version des Authentifikationsverfahrens. + + + + + + + + + Datentyp für öffentliche bankfachliche Schlüssel. + Data type for public authorisation (ES) key. + + + + + + + Version des EU-Signaturverfahrens. + ES-Version. + + + + + + + + + Datentyp für öffentlichen Schlüssel zur Authentisierung. + Data type for public for identification and authentication. + + + + + + + Version des Authentifikationsverfahrens. + Authentication version. + + + + + + + + + Datentyp für öffentlichen Verschlüsselungsschlüssel. + Data type for encryption key. + + + + + + + Version des Verschlüsselungsverfahrens. + Encryption Version. + + + + + + + + + Datentyp für die Zertifikate hinsichtlich der "bank-technical signature for authorisation" (ES). + Data Type for Certificates for the bank-technical signature for authorisation (ES) + + + + + + + + + Datentyp für Antwortcodes. + + + + + + + + + Datentyp für den Erklärungstext zum Antwortcode. + + + + + + + + Datentyp für Quittierungscodes. + + + + + + + + + Datentyp für Kunden-, Teilnehmer-, Straßen- oder Ortsnamen. + + + + + + Datentyp für die Beschreibung von Auftragsarten. + + + + + + + + Datentyp für den Teilnehmerstatus. + + + + + + + + generic parameter + Generic key value parameters. + + + + + + name of parameter + Name of the parameter (= key). + + + + + value of parameter + Value of the parameter. + + + + + + + XML-Typ des Parameterwerts (Vorschlag für default ist string). + XML type of the parameter value (Proposal for default is string). + + + + + + + + + + + + Datentyp für die Darstellung von Information zur Verschlüsselung der Auftragsdaten. + Data type for the modelling of information regarding the encryption of signature and order data. + + + + + Hashwert des öffentlichen Verschlüsselungsschlüssels des Empfängers der verschlüsselten Auftragsdaten. + Hash value of the public encryption key owned by the receipient of the encrypted order data. + + + + + + + Version des Verschlüsselungsverfahrens. + Version of the encryption method. + + + + + + + + + Asymmetrisch verschlüsselter symmetrischer Transaktionsschlüssel. + The asymmetrically encrypted symmetric transaction key. + + + + + + + + Authentifikationssignatur. + Authentication signature. + + + + + String up to 255 characters. + + + + + + + + + + + + + + + + Type is used for ISO variant and version + + + + + + + + + + Type ist used for original file name + + + + + + + + + Type ist used for name or rather kind of Message + + + + + + + + + + Service Code name: External list specified and maintained by EBICS. Basis is the "SWIFT-list" for the field "description" (SCT, DCT, XCT, SDD, DDD, STM, REP...) plus additional codes needed for further services + + + + + + + + + + + + + + + + + + + + + + + + + + +