diff --git a/.claude/commands/prepare-github-release.md b/.claude/commands/prepare-github-release.md new file mode 100644 index 00000000..54ee10bf --- /dev/null +++ b/.claude/commands/prepare-github-release.md @@ -0,0 +1,49 @@ +--- +description: Draft and publish a GitHub release for the current pom version, with AI-written categorized notes covering merged PRs AND direct commits. +argument-hint: "[--draft] [version]" +allowed-tools: Bash(git:*), Bash(gh:*), Bash(./mvnw:*), Read, Write +--- + +Prepare a GitHub release for this repository (`ebics-java/ebics-java-client`). Follow these +steps. Do NOT create the tag or release until the user has approved the drafted notes. + +## 1. Determine the version and previous tag +- Version to release: `./mvnw -q help:evaluate -Dexpression=project.version -DforceStdout` + (or use an explicit version passed in `$ARGUMENTS`). The tag is the bare version, e.g. `2.1.0` + (no `v` prefix — match existing tags). The release title is `EBICS Java Version `. +- Previous released tag: the most recent existing tag by version, e.g. + `git tag --sort=-v:refname | head -5` — pick the highest tag that is not the new version. + +## 2. Gather the raw material (this is the whole point — cover EVERYTHING, not just PRs) +- All commits in range, including direct-to-master commits and merges: + `git log ..HEAD --pretty=format:'%h %s (%an)'` +- GitHub's PR-based data (for accurate PR links, @author attribution, new contributors, and the + compare URL): + `gh api repos/ebics-java/ebics-java-client/releases/generate-notes -f tag_name= -f previous_tag_name= -f target_commitish=master --jq '.body'` + +## 3. Draft the notes +Write clean Markdown release notes that: +- Group changes under these headings (omit any that are empty): + `## New Features & Enhancements`, `## Bug Fixes`, `## Dependency Updates`, `## Other Changes`. +- Reword terse commit subjects into clear, user-facing bullets (e.g. drop `feat(cli):` prefixes, + make them read as human sentences). Do not invent changes — every bullet must trace to a real + commit or PR. +- Include direct-to-master commits that have no PR, alongside the PR-based entries. +- Preserve PR links and `@author` attribution where a change came from a PR. +- Keep a `## New Contributors` section and the `**Full Changelog**: ` line from the + generated data if present. +- Lead with a one or two sentence summary of the release if there's a notable theme. + +## 4. Review with the user +Show the full drafted notes in the chat and ask the user to approve or request edits. STOP here +until they approve. Iterate on wording if asked. + +## 5. Publish (only after approval) +- Confirm local `HEAD` is pushed to `origin/master` (`git rev-parse HEAD` == `git rev-parse origin/master`); warn if not. +- Create the tag if it does not exist, then push it: + `git tag ` (skip if it exists) and `git push origin `. +- Write the approved notes to a temp file in the scratchpad, then create the release: + `gh release create --title "EBICS Java Version " --notes-file --verify-tag` +- If `$ARGUMENTS` contains `--draft`, add `--draft` so the user can eyeball it on GitHub before + it goes public. +- Report the release URL that `gh` prints. diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..11e1b509 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,22 @@ +# Controls how GitHub groups the auto-generated release notes +# (used by `gh release create --generate-notes` and the "Generate release notes" button). +# PRs are bucketed by their labels; anything unlabeled falls under "Other changes". +changelog: + exclude: + labels: + - ignore-for-release + categories: + - title: New Features & Enhancements + labels: + - enhancement + - feature + - title: Bug Fixes + labels: + - bug + - fix + - title: Dependency Updates + labels: + - dependencies + - title: Other Changes + labels: + - "*" diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 00000000..fa7dfd95 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,29 @@ +name: Java CI with Maven + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + permissions: + contents: write + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn -B package --file pom.xml + + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + - name: Update dependency graph + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository + uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/.gitignore b/.gitignore index 1b823e3d..0ee15992 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target/ .idea -*.iml \ No newline at end of file +*.iml +/client/ +/.envrc diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..c0bcafe9 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/README.md b/README.md index cb73be7d..4b7f4e88 100644 --- a/README.md +++ b/README.md @@ -5,46 +5,86 @@ This library allows to interact with banks using the EBICS (Electronic Banking I You can use the `EbicsClient` as command line tool or use it from your Java application. +Features: + +- EBICS 3.0 +- Support for French, German and Swiss banks +- Command line client to do the setup, initialization and to download files from the bank +- Tested extensively with [ZKB](https://zkb.ch) + How to get started: -https://github.com/uwemaurer/ebics-java-client/wiki/EBICS-Client-HowTo +https://github.com/ebics-java/ebics-java-client/wiki/EBICS-Client-HowTo -You can build it directly from the source with maven or use the releases from [JitPack](https://jitpack.io/#uwemaurer/ebics-java-client/). +Parameterized launcher (without `ebics.txt`): -Gradle: ``` -allprojects { - repositories { - ... - maven { url 'https://jitpack.io' } - } -} +export EBICS_PASSWORD='changeit' +export EBICS_USER_ID='USER123' +export EBICS_PARTNER_ID='PARTNER123' +export EBICS_HOST_ID='HOST123' +export EBICS_BANK_URL='https://bank.example/ebics' + +mvn exec:java \ + -Dexec.mainClass=org.kopi.ebics.client.ParameterizedEbicsClientLauncher \ + -Dexec.args="--create --ini --hia --hpb" +``` + +This mode is useful for containerized or ephemeral environments where `ebics.txt` should not be persisted. + +The library is published to [Maven Central](https://central.sonatype.com/artifact/io.github.ebics-java/ebics-java-client). + +Maven: +``` + + io.github.ebics-java + ebics-java-client + 2.2.0 + +``` +Gradle: +``` dependencies { - implementation 'com.github.uwemaurer:ebics-java-client:97867ac56e' + implementation 'io.github.ebics-java:ebics-java-client:2.2.0' } ``` -Maven + +You can also build it directly from the source with Maven (`./mvnw clean install`). +See [RELEASING.md](RELEASING.md) for how releases are published to Maven Central. + +### Snapshot / unreleased builds via JitPack + +To pull in a specific commit or an unreleased version (any tag, branch, or commit hash) before it +reaches Maven Central, use [JitPack](https://jitpack.io/#ebics-java/ebics-java-client): + +Maven: ``` - - jitpack.io - https://jitpack.io - + + jitpack.io + https://jitpack.io + - com.github.uwemaurer + com.github.ebics-java ebics-java-client - 97867ac56e + master-SNAPSHOT ``` - -This project is based on https://sourceforge.net/p/ebics/ +Gradle: +``` +repositories { + maven { url 'https://jitpack.io' } +} + +dependencies { + implementation 'com.github.ebics-java:ebics-java-client:master-SNAPSHOT' +} +``` -Main differences with this fork: +Note that JitPack builds keep the `com.github.ebics-java` group id (derived from the GitHub repo), +whereas released artifacts on Maven Central use `io.github.ebics-java`. -- Support for French, German and Swiss banks -- Command line client to do the setup, initialization and to download files from the bank -- Use of maven for compilation instead of ant + Makefile + .sh scripts diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 00000000..efde7bf2 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - openjdk17 diff --git a/mvnw b/mvnw new file mode 100755 index 00000000..bd8896bf --- /dev/null +++ b/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 00000000..5761d948 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml index c6e7bdae..8f3c38d4 100644 --- a/pom.xml +++ b/pom.xml @@ -1,121 +1,128 @@ 4.0.0 - org.kopi - ebics + io.github.ebics-java + ebics-java-client jar - 1.1-SNAPSHOT - ebics - https://github.com/uwemaurer/ebics-java-client + 2.2.0 + EBICS Java Client + EBICS (Electronic Banking Internet Communication Standard) client library for Java. + Supports EBICS 3.0 and French, German and Swiss banks, with a command line client for + bank setup, key initialization and file download. + https://github.com/ebics-java/ebics-java-client + + + + GNU Lesser General Public License, Version 2.1 + https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt + repo + + + + + + ebics-java + EBICS Java Client contributors + https://github.com/ebics-java/ebics-java-client/graphs/contributors + + + + + scm:git:https://github.com/ebics-java/ebics-java-client.git + scm:git:git@github.com:ebics-java/ebics-java-client.git + https://github.com/ebics-java/ebics-java-client + HEAD + org.apache.xmlbeans xmlbeans - 3.1.0 - - - commons-codec - commons-codec - 1.14 - - - org.apache.httpcomponents - httpclient - 4.5.11 - - - commons-logging - commons-logging - 1.2 - - - org.jdom - jdom - 2.0.2 + 5.3.0 org.bouncycastle - bcprov-jdk16 - 1.46 - - - log4j - log4j - 1.2.17 + bcprov-jdk18on + 1.84 - org.gnu - gnu-crypto - 2.0.1 + org.slf4j + slf4j-api + 2.0.17 - xalan - xalan - 2.7.2 + org.slf4j + slf4j-simple + 2.0.17 + true - xml-security + org.apache.santuario xmlsec - 1.3.0 + 4.0.4 commons-cli commons-cli - 1.4 + 1.11.0 org.junit.jupiter junit-jupiter-api - 5.6.0 + 6.1.0 test org.junit.jupiter junit-jupiter-engine - 5.6.0 + 6.1.0 test org.mockito mockito-core - 3.2.4 + 5.23.0 test - org.codehaus.mojo - xmlbeans-maven-plugin - 2.3.3 + org.apache.xmlbeans + xmlbeans + 5.3.0 - xmlbeans + compile - true - src/main/xsd - src/main/xsd/config - 1.8 + src/main/xsd + + src/main/xsd/config/config.xsdconfig + + + ebics + org.kopi.ebics.metadata - org.apache.maven.plugins maven-compiler-plugin - 3.1 + 3.14.1 - 1.7 - 1.7 + 17 org.apache.maven.plugins maven-source-plugin - 3.0.0 + 3.3.1 attach-sources @@ -125,23 +132,86 @@ - - org.apache.maven.plugins - maven-eclipse-plugin - 2.10 - - true - true - - org.apache.maven.plugins maven-surefire-plugin - 2.22.1 + 3.5.4 UTF-8 + + + + + release + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.12.0 + + + attach-javadocs + + jar + + + + + + none + false + true + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.8 + + + sign-artifacts + verify + + sign + + + + bc + + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.11.0 + true + + + central + + false + + ${project.groupId}:${project.artifactId}:${project.version} + + + + + + diff --git a/release-settings.xml b/release-settings.xml new file mode 100644 index 00000000..7a8a4b9d --- /dev/null +++ b/release-settings.xml @@ -0,0 +1,17 @@ + + + + + + central + ${env.CENTRAL_USERNAME} + ${env.CENTRAL_PASSWORD} + + + diff --git a/scripts/github-release.sh b/scripts/github-release.sh new file mode 100755 index 00000000..8c67d698 --- /dev/null +++ b/scripts/github-release.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# +# Copyright Uwe Maurer +# +# Tag the current pom version and publish a GitHub release with an auto-generated changelog. +# +# GitHub builds the changelog from the pull requests merged since the previous tag; the +# grouping is configured in .github/release.yml. Run this AFTER the Maven Central release +# (scripts/release.sh) has been published, from a clean, pushed master. +# +# Usage: +# scripts/github-release.sh # tag , push it, create the release +# scripts/github-release.sh --draft # extra flags are forwarded to `gh release create` +# +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$REPO_ROOT" + +VERSION="$(./mvnw -q help:evaluate -Dexpression=project.version -DforceStdout)" +TAG="$VERSION" +TITLE="EBICS Java Version $VERSION" + +echo "Releasing $TAG ($TITLE)" + +# Create the tag locally if it does not exist yet, then push it. +if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then + echo "Tag $TAG already exists locally." +else + git tag "$TAG" +fi +git push origin "$TAG" + +# Create the GitHub release with notes generated from merged PRs since the previous tag. +gh release create "$TAG" --title "$TITLE" --generate-notes --verify-tag "$@" diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 00000000..a2816045 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# +# Copyright Uwe Maurer +# +# Publish ebics-java-client to Maven Central (Sonatype Central Portal). +# +# Production credentials live OUTSIDE this repo in a Gradle-format properties file. +# This script reads them, exposes them to Maven as environment variables, and runs the +# `release` profile (Javadoc jar + GPG signing + Central publishing). +# +# A credential-free local build needs none of this -- just run: +# ./mvnw clean install +# +# Usage: +# scripts/release.sh # stage a deployment on the Central Portal +# scripts/release.sh -DskipTests # extra args are forwarded to Maven +# +# Credentials are read from `release.properties` in the repo root, which is git-ignored. +# Create it as a symlink to your out-of-repo credentials file, e.g.: +# ln -s ~/secret/maven-central-gradle.properties release.properties +# +# Override the location with: +# MAVEN_CENTRAL_CREDENTIALS=/path/to/file scripts/release.sh +# +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +CREDS="${MAVEN_CENTRAL_CREDENTIALS:-$REPO_ROOT/release.properties}" + +if [[ ! -f "$CREDS" ]]; then + echo "error: credentials file not found: $CREDS" >&2 + echo " set MAVEN_CENTRAL_CREDENTIALS to point at it, or build locally without" >&2 + echo " publishing using: ./mvnw clean install" >&2 + exit 1 +fi + +# Read one property value from the Gradle-style (key=value) credentials file. +prop() { + local value + value="$(grep -E "^$1=" "$CREDS" | head -1 | cut -d= -f2-)" + if [[ -z "$value" ]]; then + echo "error: property '$1' missing or empty in $CREDS" >&2 + exit 1 + fi + printf '%s' "$value" +} + +# Central Portal token -> consumed by release-settings.xml (). +export CENTRAL_USERNAME="$(prop mavenCentralUsername)" +export CENTRAL_PASSWORD="$(prop mavenCentralPassword)" + +# GPG signing -> consumed by the maven-gpg-plugin BouncyCastle signer. +export MAVEN_GPG_PASSPHRASE="$(prop signingInMemoryKeyPassword)" +# The signing key is stored on a single line with \n-escaped newlines (Gradle in-memory +# format); restore real newlines so the PGP armor parses. +export MAVEN_GPG_KEY="$(prop signingInMemoryKey | sed 's/\\n/\ +/g')" + +cd "$REPO_ROOT" +exec ./mvnw -Prelease -s release-settings.xml clean deploy "$@" diff --git a/src/main/java/org/kopi/ebics/certificate/CertificateManager.java b/src/main/java/org/kopi/ebics/certificate/CertificateManager.java index e1e37421..e92d4656 100644 --- a/src/main/java/org/kopi/ebics/certificate/CertificateManager.java +++ b/src/main/java/org/kopi/ebics/certificate/CertificateManager.java @@ -14,11 +14,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.certificate; +import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -38,11 +38,15 @@ /** * Simple manager for EBICS certificates. * - * @author hacheni * */ public class CertificateManager { + private static final String KEY_LENGTH_PROPERTY = "ebics.key.length"; + private static final String CERTIFICATE_VALIDITY_YEARS_PROPERTY = "ebics.cert.validity.years"; + private static final int DEFAULT_KEY_LENGTH = X509Constants.EBICS_KEY_SIZE; + private static final int DEFAULT_CERTIFICATE_VALIDITY_YEARS = X509Constants.DEFAULT_DURATION / 365; + public CertificateManager(EbicsUser user) { this.user = user; generator = new X509Generator(); @@ -54,15 +58,13 @@ public CertificateManager(EbicsUser user) { * @throws IOException */ public void create() throws GeneralSecurityException, IOException { - Calendar calendar; - - calendar = Calendar.getInstance(); - calendar.add(Calendar.DAY_OF_YEAR, X509Constants.DEFAULT_DURATION); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.YEAR, resolveCertificateValidityYears()); - createA005Certificate(new Date(calendar.getTimeInMillis())); - createX002Certificate(new Date(calendar.getTimeInMillis())); - createE002Certificate(new Date(calendar.getTimeInMillis())); - setUserCertificates(); + createA005Certificate(new Date(calendar.getTimeInMillis())); + createX002Certificate(new Date(calendar.getTimeInMillis())); + createE002Certificate(new Date(calendar.getTimeInMillis())); + setUserCertificates(); } /** @@ -85,26 +87,25 @@ private void setUserCertificates() { * @throws IOException */ public void createA005Certificate(Date end) throws GeneralSecurityException, IOException { - KeyPair keypair; + KeyPair keypair = KeyUtil.makeKeyPair(resolveKeyLength()); + a005Certificate = generator.generateA005Certificate(keypair, user.getDN(), new Date(), end); + a005PrivateKey = keypair.getPrivate(); + } - keypair = KeyUtil.makeKeyPair(X509Constants.EBICS_KEY_SIZE); - a005Certificate = generator.generateA005Certificate(keypair, - user.getDN(), - new Date(), - end); - a005PrivateKey = keypair.getPrivate(); + X509Certificate getA005Certificate() { + return a005Certificate; } /** * Creates the authentication certificate. - * @param the expiration date of a the certificate. + * @param end the expiration date of a certificate. * @throws GeneralSecurityException * @throws IOException */ public void createX002Certificate(Date end) throws GeneralSecurityException, IOException { KeyPair keypair; - keypair = KeyUtil.makeKeyPair(X509Constants.EBICS_KEY_SIZE); + keypair = KeyUtil.makeKeyPair(resolveKeyLength()); x002Certificate = generator.generateX002Certificate(keypair, user.getDN(), new Date(), @@ -121,7 +122,7 @@ public void createX002Certificate(Date end) throws GeneralSecurityException, IOE public void createE002Certificate(Date end) throws GeneralSecurityException, IOException { KeyPair keypair; - keypair = KeyUtil.makeKeyPair(X509Constants.EBICS_KEY_SIZE); + keypair = KeyUtil.makeKeyPair(resolveKeyLength()); e002Certificate = generator.generateE002Certificate(keypair, user.getDN(), new Date(), @@ -131,15 +132,11 @@ public void createE002Certificate(Date end) throws GeneralSecurityException, IOE /** * Saves the certificates in PKCS12 format - * @param path the certificates path - * @param pwdCallBack the password call back - * @throws GeneralSecurityException - * @throws IOException */ - public void save(String path, PasswordCallback pwdCallBack) + public void save(File directory, PasswordCallback pwdCallBack) throws GeneralSecurityException, IOException { - writePKCS12Certificate(path + "/" + user.getUserId(), pwdCallBack.getPassword()); + writePKCS12Certificate(new File(directory, user.getUserId()), pwdCallBack.getPassword()); } /** @@ -149,7 +146,7 @@ public void save(String path, PasswordCallback pwdCallBack) * @throws GeneralSecurityException * @throws IOException */ - public void load(String path, PasswordCallback pwdCallBack) + public void load(File path, PasswordCallback pwdCallBack) throws GeneralSecurityException, IOException { KeyStoreManager loader; @@ -169,24 +166,20 @@ public void load(String path, PasswordCallback pwdCallBack) /** * Writes a the generated certificates into a PKCS12 key store. - * @param filename the key store file name + * @param file the key store file * @param password the key password * @throws IOException */ - public void writePKCS12Certificate(String filename, char[] password) + public void writePKCS12Certificate(File file, char[] password) throws GeneralSecurityException, IOException { - if (filename == null || "".equals(filename)) { - throw new IOException("The file name cannot be empty"); - } - - if (!filename.toLowerCase().endsWith(".p12")) { - filename += ".p12"; - } - - FileOutputStream fos = new FileOutputStream(filename); - writePKCS12Certificate(password, fos); - fos.close(); + var outFile = file; + if (!file.getName().toLowerCase().endsWith(".p12")) { + outFile = new File(file.getParentFile(), file.getName() + ".p12"); + } + try (FileOutputStream fos = new FileOutputStream(outFile)) { + writePKCS12Certificate(password, fos); + } } /** @@ -222,8 +215,8 @@ public void writePKCS12Certificate(char[] password, OutputStream fos) // DATA MEMBERS // -------------------------------------------------------------------- - private X509Generator generator; - private EbicsUser user; + private final X509Generator generator; + private final EbicsUser user; private X509Certificate a005Certificate; private X509Certificate e002Certificate; @@ -232,4 +225,20 @@ public void writePKCS12Certificate(char[] password, OutputStream fos) private PrivateKey a005PrivateKey; private PrivateKey x002PrivateKey; private PrivateKey e002PrivateKey; + + private int resolveKeyLength() { + Integer configuredKeyLength = Integer.getInteger(KEY_LENGTH_PROPERTY); + if (configuredKeyLength == null || configuredKeyLength <= 0) { + return DEFAULT_KEY_LENGTH; + } + return configuredKeyLength; + } + + private int resolveCertificateValidityYears() { + Integer configuredYears = Integer.getInteger(CERTIFICATE_VALIDITY_YEARS_PROPERTY); + if (configuredYears == null || configuredYears <= 0) { + return DEFAULT_CERTIFICATE_VALIDITY_YEARS; + } + return configuredYears; + } } diff --git a/src/main/java/org/kopi/ebics/certificate/KeyStoreManager.java b/src/main/java/org/kopi/ebics/certificate/KeyStoreManager.java index 7d819e57..0c6cdbae 100644 --- a/src/main/java/org/kopi/ebics/certificate/KeyStoreManager.java +++ b/src/main/java/org/kopi/ebics/certificate/KeyStoreManager.java @@ -14,15 +14,14 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.certificate; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.math.BigInteger; import java.security.GeneralSecurityException; @@ -43,7 +42,6 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import org.bouncycastle.openssl.PEMReader; /** * Key store loader. This class loads a key store from @@ -51,7 +49,6 @@ * for a given alias. * The PKCS12 key store type is recommended to be used * - * @author hachani * */ public class KeyStoreManager { @@ -81,14 +78,11 @@ public final X509Certificate getCertificate(String alias) throws KeyStoreExcepti * @throws GeneralSecurityException */ public final PrivateKey getPrivateKey(String alias) throws GeneralSecurityException { - PrivateKey key; - - key = (PrivateKey) keyStore.getKey(alias, password); - if (key == null) { - throw new IllegalArgumentException("private key not found for alias " + alias); - } - - return key; + PrivateKey key = (PrivateKey) keyStore.getKey(alias, password); + if (key == null) { + throw new IllegalArgumentException("private key not found for alias " + alias); + } + return key; } /** @@ -98,7 +92,7 @@ public final PrivateKey getPrivateKey(String alias) throws GeneralSecurityExcept * @throws GeneralSecurityException * @throws IOException */ - public void load(String path, char[] password) + public void load(File path, char[] password) throws GeneralSecurityException, IOException { keyStore = KeyStore.getInstance("PKCS12", "BC"); @@ -112,8 +106,8 @@ public void load(String path, char[] password) * @throws GeneralSecurityException * @throws IOException */ - private void load(String path) throws GeneralSecurityException, IOException { - if (path.equals("")) { + private void load(File path) throws GeneralSecurityException, IOException { + if (path == null) { this.keyStore.load(null, null); } else { this.keyStore.load(new FileInputStream(path), password); @@ -127,20 +121,11 @@ private void load(String path) throws GeneralSecurityException, IOException { * @param provider the certificate provider * @return the certificate * @throws CertificateException - * @throws IOException */ public X509Certificate read(InputStream input, Provider provider) - throws CertificateException, IOException - { - X509Certificate certificate; - - certificate = (X509Certificate) CertificateFactory.getInstance("X.509", provider).generateCertificate(input); - - if (certificate == null) { - certificate = (X509Certificate)(new PEMReader(new InputStreamReader(input))).readObject(); - } - - return certificate; + throws CertificateException { + return (X509Certificate) CertificateFactory.getInstance("X.509", + provider).generateCertificate(input); } /** @@ -148,15 +133,11 @@ public X509Certificate read(InputStream input, Provider provider) * @param input the given certificate * @return The RSA public key of the given certificate * @throws GeneralSecurityException - * @throws IOException */ - public RSAPublicKey getPublicKey(InputStream input) - throws GeneralSecurityException, IOException - { - X509Certificate cert; + public RSAPublicKey getPublicKey(InputStream input) throws GeneralSecurityException { - cert = read(input, keyStore.getProvider()); - return (RSAPublicKey) cert.getPublicKey(); + X509Certificate cert = read(input, keyStore.getProvider()); + return (RSAPublicKey) cert.getPublicKey(); } public RSAPublicKey getPublicKey(BigInteger publicExponent, BigInteger modulus) @@ -168,7 +149,7 @@ public RSAPublicKey getPublicKey(BigInteger publicExponent, BigInteger modulus) return null; } } - + /** * Writes the given certificate into the key store. * @param alias the certificate alias @@ -191,7 +172,7 @@ public void save(OutputStream output) { keyStore.store(output, password); } - + /** * Returns the certificates contained in the key store. * @return the certificates contained in the key store. @@ -207,29 +188,21 @@ public Map getCertificates() { * the key of the map is the certificate alias * @throws KeyStoreException */ - public Map read(KeyStore keyStore) - throws KeyStoreException - { - Map certificates; - Enumeration enumeration; - - certificates = new HashMap(); - enumeration = keyStore.aliases(); - while (enumeration.hasMoreElements()) { - String alias; - - alias = enumeration.nextElement(); - certificates.put(alias, (X509Certificate)keyStore.getCertificate(alias)); - } - - return certificates; + public Map read(KeyStore keyStore) throws KeyStoreException { + Map certificates = new HashMap<>(); + Enumeration enumeration = keyStore.aliases(); + while (enumeration.hasMoreElements()) { + String alias = enumeration.nextElement(); + certificates.put(alias, (X509Certificate) keyStore.getCertificate(alias)); + } + return certificates; } // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- - private KeyStore keyStore; - private char[] password; - private Map certs; + private KeyStore keyStore; + private char[] password; + private Map certs; } diff --git a/src/main/java/org/kopi/ebics/certificate/KeyUtil.java b/src/main/java/org/kopi/ebics/certificate/KeyUtil.java index 0137503b..44f649d5 100644 --- a/src/main/java/org/kopi/ebics/certificate/KeyUtil.java +++ b/src/main/java/org/kopi/ebics/certificate/KeyUtil.java @@ -14,12 +14,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.certificate; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -27,18 +26,17 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPublicKey; +import java.util.HexFormat; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Hex; import org.kopi.ebics.exception.EbicsException; +import org.kopi.ebics.utils.Utils; /** * Some key utilities * - * @author hachani * */ -public class KeyUtil { +public final class KeyUtil { private KeyUtil() { } @@ -50,36 +48,16 @@ private KeyUtil() { * @return KeyPair the key pair * @throws NoSuchAlgorithmException */ - public static KeyPair makeKeyPair(int keyLen) throws NoSuchAlgorithmException{ + public static KeyPair makeKeyPair(int keyLen) throws NoSuchAlgorithmException { KeyPairGenerator keyGen; keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(keyLen, new SecureRandom()); + keyGen.initialize(keyLen, Utils.secureRandom); - KeyPair keypair = keyGen.generateKeyPair(); - - return keypair; + return keyGen.generateKeyPair(); } - /** - * Generates a random password - * - * @return the password - */ - public static String generatePassword() { - SecureRandom random; - - try { - random = SecureRandom.getInstance("SHA1PRNG"); - String pwd = Base64.encodeBase64String(random.generateSeed(5)); - - return pwd.substring(0, pwd.length() - 2); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } - /** * Returns the digest value of a given public key. * @@ -102,8 +80,8 @@ public static byte[] getKeyDigest(RSAPublicKey publicKey) throws EbicsException String hash; byte[] digest; - exponent = Hex.encodeHexString(publicKey.getPublicExponent().toByteArray()); - modulus = Hex.encodeHexString(removeFirstByte(publicKey.getModulus().toByteArray())); + exponent = HexFormat.of().formatHex(publicKey.getPublicExponent().toByteArray()); + modulus = HexFormat.of().formatHex(removeFirstByte(publicKey.getModulus().toByteArray())); hash = exponent + " " + modulus; if (hash.charAt(0) == '0') { @@ -111,14 +89,13 @@ public static byte[] getKeyDigest(RSAPublicKey publicKey) throws EbicsException } try { - digest = MessageDigest.getInstance("SHA-256", "BC").digest(hash.getBytes("US-ASCII")); + digest = MessageDigest.getInstance("SHA-256", "BC").digest(hash.getBytes( + StandardCharsets.US_ASCII)); } catch (GeneralSecurityException e) { throw new EbicsException(e.getMessage()); - } catch (UnsupportedEncodingException e) { - throw new EbicsException(e.getMessage()); } - return new String(Hex.encodeHex(digest, false)).getBytes(); + return HexFormat.of().withUpperCase().formatHex(digest).getBytes(StandardCharsets.US_ASCII); } /** diff --git a/src/main/java/org/kopi/ebics/certificate/X509Constants.java b/src/main/java/org/kopi/ebics/certificate/X509Constants.java index 3a08b5ac..2c2c7b44 100644 --- a/src/main/java/org/kopi/ebics/certificate/X509Constants.java +++ b/src/main/java/org/kopi/ebics/certificate/X509Constants.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.certificate; @@ -22,7 +21,6 @@ /** * X509 certificate constants * - * @author hachani * */ public interface X509Constants { @@ -30,9 +28,9 @@ public interface X509Constants { /** * Certificates key usage */ - int SIGNATURE_KEY_USAGE = 1; - int AUTHENTICATION_KEY_USAGE = 2; - int ENCRYPTION_KEY_USAGE = 3; + enum CertificateKeyUsage { + SIGNATURE_KEY_USAGE, AUTHENTICATION_KEY_USAGE, ENCRYPTION_KEY_USAGE, + } /** * Certificate signature algorithm diff --git a/src/main/java/org/kopi/ebics/certificate/X509Generator.java b/src/main/java/org/kopi/ebics/certificate/X509Generator.java index c59586d5..a2963c73 100644 --- a/src/main/java/org/kopi/ebics/certificate/X509Generator.java +++ b/src/main/java/org/kopi/ebics/certificate/X509Generator.java @@ -14,28 +14,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.certificate; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.PublicKey; -import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; @@ -46,15 +39,15 @@ import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.x509.X509V3CertificateGenerator; +import org.kopi.ebics.certificate.X509Constants.CertificateKeyUsage; +import org.kopi.ebics.utils.Utils; /** * An X509 certificate generator for EBICS protocol. * Generated certificates are self signed certificates. * - * @author hachani * */ @SuppressWarnings("deprecation") @@ -80,7 +73,7 @@ public X509Certificate generateA005Certificate(KeyPair keypair, issuer, notBefore, notAfter, - X509Constants.SIGNATURE_KEY_USAGE); + CertificateKeyUsage.SIGNATURE_KEY_USAGE); } /** @@ -103,7 +96,7 @@ public X509Certificate generateX002Certificate(KeyPair keypair, issuer, notBefore, notAfter, - X509Constants.AUTHENTICATION_KEY_USAGE); + CertificateKeyUsage.AUTHENTICATION_KEY_USAGE); } /** @@ -126,7 +119,7 @@ public X509Certificate generateE002Certificate(KeyPair keypair, issuer, notBefore, notAfter, - X509Constants.ENCRYPTION_KEY_USAGE); + CertificateKeyUsage.ENCRYPTION_KEY_USAGE); } /** @@ -145,15 +138,15 @@ public X509Certificate generate(KeyPair keypair, String issuer, Date notBefore, Date notAfter, - int keyusage) + CertificateKeyUsage keyusage) throws GeneralSecurityException, IOException { X509V3CertificateGenerator generator; BigInteger serial; X509Certificate certificate; - ASN1EncodableVector vector; serial = BigInteger.valueOf(generateSerial()); + generator = new X509V3CertificateGenerator(); generator.setSerialNumber(serial); generator.setIssuerDN(new X509Principal(issuer)); @@ -174,19 +167,19 @@ public X509Certificate generate(KeyPair keypair, getPublic(), issuer, serial)); - vector = new ASN1EncodableVector(); - vector.add(KeyPurposeId.id_kp_emailProtection); - generator.addExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(new DERSequence(vector))); + var purposeIds = new KeyPurposeId[] { KeyPurposeId.id_kp_emailProtection }; + + generator.addExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(purposeIds)); switch (keyusage) { - case X509Constants.SIGNATURE_KEY_USAGE: + case SIGNATURE_KEY_USAGE: generator.addExtension(X509Extensions.KeyUsage, false, new KeyUsage(KeyUsage.nonRepudiation)); break; - case X509Constants.AUTHENTICATION_KEY_USAGE: + case AUTHENTICATION_KEY_USAGE: generator.addExtension(X509Extensions.KeyUsage, false, new KeyUsage(KeyUsage.digitalSignature)); break; - case X509Constants.ENCRYPTION_KEY_USAGE: + case ENCRYPTION_KEY_USAGE: generator.addExtension(X509Extensions.KeyUsage, false, new KeyUsage(KeyUsage.keyAgreement)); break; default: @@ -194,7 +187,7 @@ public X509Certificate generate(KeyPair keypair, break; } - certificate = generator.generate(keypair.getPrivate(), "BC", new SecureRandom()); + certificate = generator.generate(keypair.getPrivate(), "BC", Utils.secureRandom); certificate.checkValidity(new Date()); certificate.verify(keypair.getPublic()); @@ -208,23 +201,14 @@ public X509Certificate generate(KeyPair keypair, * @param issuer the certificate issuer * @param serial the certificate serial number * @return the authority key identifier of the public key - * @throws IOException */ private AuthorityKeyIdentifier getAuthorityKeyIdentifier(PublicKey publicKey, String issuer, - BigInteger serial) - throws IOException - { - InputStream input; - SubjectPublicKeyInfo keyInfo; - ASN1EncodableVector vector; - - input = new ByteArrayInputStream(publicKey.getEncoded()); - keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(input).readObject()); - vector = new ASN1EncodableVector(); - vector.add(new GeneralName(new X509Name(issuer))); - - return new AuthorityKeyIdentifier(keyInfo, new GeneralNames(new DERSequence(vector)), serial); + BigInteger serial) { + SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()); + X500Name issuerName = new X500Name(issuer); + GeneralNames generalNames = new GeneralNames(new GeneralName(issuerName)); + return new AuthorityKeyIdentifier(keyInfo, generalNames, serial); } /** @@ -237,34 +221,26 @@ private AuthorityKeyIdentifier getAuthorityKeyIdentifier(PublicKey publicKey, private SubjectKeyIdentifier getSubjectKeyIdentifier(PublicKey publicKey) throws IOException { - InputStream input; - SubjectPublicKeyInfo keyInfo; - - input = new ByteArrayInputStream(publicKey.getEncoded()); - keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(input).readObject()); - - return new SubjectKeyIdentifier(keyInfo); + SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()); + return new SubjectKeyIdentifier(keyInfo.getEncoded()); } /** - * Generates a random serial number + * Generates a serial number from current timestamp * * @return the serial number */ private long generateSerial() { - Date now; - - now = new Date(); - String sNow = sdfSerial.format(now); - - return Long.valueOf(sNow).longValue(); + Date now = new Date(); + String sNow = sdfSerial.format(now); + return Long.parseLong(sNow); } // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- - private static SimpleDateFormat sdfSerial; + private static final SimpleDateFormat sdfSerial; static { sdfSerial = new SimpleDateFormat("yyyyMMddHHmmssSSS"); diff --git a/src/main/java/org/kopi/ebics/client/Bank.java b/src/main/java/org/kopi/ebics/client/Bank.java index fe743c0f..ee8afb36 100644 --- a/src/main/java/org/kopi/ebics/client/Bank.java +++ b/src/main/java/org/kopi/ebics/client/Bank.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; @@ -32,9 +31,8 @@ /** * Simple implementation of an EBICS bank. * This object is serializable to facilitate persisting of the values. - * Save the the object whenever it needs to be saved. + * Save the object whenever it needs to be saved. * - * @author Hachani * */ public class Bank implements EbicsBank, Savable { @@ -44,13 +42,11 @@ public class Bank implements EbicsBank, Savable { * @param url the bank URL * @param name the bank name * @param hostId the bank host ID - * @param useCertificate does the bank use certificates for exchange ? */ - public Bank(URL url, String name, String hostId, boolean useCertificate) { + public Bank(URL url, String name, String hostId) { this.url = url; this.name = name; this.hostId = hostId; - this.useCertificate = useCertificate; needSave = true; } @@ -129,17 +125,6 @@ public String getName() { return name; } - @Override - public boolean useCertificate() { - return useCertificate; - } - - @Override - public void setUseCertificate(boolean useCertificate) { - this.useCertificate = useCertificate; - needSave = true; - } - @Override public void setBankKeys(RSAPublicKey e002Key, RSAPublicKey x002Key) { this.e002Key = e002Key; @@ -167,25 +152,19 @@ public String getSaveName() { * The bank URL * @serial */ - private URL url; + private final URL url; /** * The bank host id * @serial */ - private String hostId; - - /** - * Does the bank use certificates for signing/crypting ? - * @serial - */ - private boolean useCertificate; + private final String hostId; /** * The bank name * @serial */ - private String name; + private final String name; /** * The bank encryption digest diff --git a/src/main/java/org/kopi/ebics/client/EbicsClient.java b/src/main/java/org/kopi/ebics/client/EbicsClient.java index f645680a..94a9ae6b 100644 --- a/src/main/java/org/kopi/ebics/client/EbicsClient.java +++ b/src/main/java/org/kopi/ebics/client/EbicsClient.java @@ -14,20 +14,18 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.net.URL; import java.security.GeneralSecurityException; -import java.util.Arrays; +import java.security.Security; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -38,26 +36,31 @@ import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; + import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.help.HelpFormatter; +import org.apache.xml.security.Init; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.NoDownloadDataAvailableException; import org.kopi.ebics.interfaces.Configuration; import org.kopi.ebics.interfaces.EbicsBank; +import org.kopi.ebics.interfaces.EbicsOrderType; import org.kopi.ebics.interfaces.EbicsUser; import org.kopi.ebics.interfaces.InitLetter; import org.kopi.ebics.interfaces.LetterManager; import org.kopi.ebics.interfaces.PasswordCallback; import org.kopi.ebics.io.IOUtils; import org.kopi.ebics.messages.Messages; -import org.kopi.ebics.schema.h003.OrderAttributeType; import org.kopi.ebics.session.DefaultConfiguration; import org.kopi.ebics.session.EbicsSession; import org.kopi.ebics.session.OrderType; import org.kopi.ebics.session.Product; import org.kopi.ebics.utils.Constants; +import org.kopi.ebics.xml.EbicsXmlFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The ebics client application. Performs necessary tasks to contact the ebics @@ -66,6 +69,24 @@ * */ public class EbicsClient { + /** + * The workspace holding ebics.txt, the user keys and the order numbers. + * + *

Overridable through EBICS_ROOT_DIR, the same variable {@link + * ParameterizedEbicsClientLauncher} uses, so that a second access (a test bank, a second + * agreement) can be initialized without writing into the workspace of the first one. The keys + * are not the only thing at stake: quitting saves the incremented order number, which the bank + * counts. + */ + private static File getRootDir() { + String configured = System.getenv("EBICS_ROOT_DIR"); + if (configured != null && !configured.isBlank()) { + return new File(configured.trim()); + } + return new File(System.getProperty("user.home"), "ebics" + File.separator + "client"); + } + + private static final Logger log = LoggerFactory.getLogger(EbicsClient.class); private final Configuration configuration; private final Map users = new HashMap<>(); @@ -77,8 +98,8 @@ public class EbicsClient { private User defaultUser; static { - org.apache.xml.security.Init.init(); - java.security.Security.addProvider(new BouncyCastleProvider()); + Init.init(); + Security.addProvider(new BouncyCastleProvider()); } /** @@ -93,7 +114,7 @@ public EbicsClient(Configuration configuration, ConfigProperties properties) { this.properties = properties; Messages.setLocale(configuration.getLocale()); this.messages = new Messages(Constants.APPLICATION_BUNDLE_NAME, configuration.getLocale()); - configuration.getLogger().info(messages.getString("init.configuration")); + log.info(messages.getString("init.configuration")); configuration.init(); } @@ -110,7 +131,7 @@ private EbicsSession createSession(User user, Product product) { * the concerned user */ public void createUserDirectories(EbicsUser user) { - configuration.getLogger().info( + log.info( messages.getString("user.create.directories", user.getUserId())); IOUtils.createDirectories(configuration.getUserDirectory(user)); IOUtils.createDirectories(configuration.getTransferTraceDirectory(user)); @@ -128,12 +149,10 @@ public void createUserDirectories(EbicsUser user) { * the bank name * @param hostId * the bank host ID - * @param useCertificate - * does the bank use certificates ? * @return the created ebics bank */ - private Bank createBank(URL url, String name, String hostId, boolean useCertificate) { - Bank bank = new Bank(url, name, hostId, useCertificate); + private Bank createBank(URL url, String name, String hostId) { + Bank bank = new Bank(url, name, hostId); banks.put(hostId, bank); return bank; } @@ -173,23 +192,21 @@ private Partner createPartner(EbicsBank bank, String partnerId) { * the user country * @param organization * the user organization or company - * @param useCertificates - * does the bank use certificates ? * @param saveCertificates * save generated certificates? * @param passwordCallback * a callback-handler that supplies us with the password. This * parameter can be null, in this case no password is used. - * @return + * @return Ebics User * @throws Exception */ public User createUser(URL url, String bankName, String hostId, String partnerId, String userId, String name, String email, String country, String organization, - boolean useCertificates, boolean saveCertificates, PasswordCallback passwordCallback) + boolean saveCertificates, PasswordCallback passwordCallback) throws Exception { - configuration.getLogger().info(messages.getString("user.create.info", userId)); + log.info(messages.getString("user.create.info", userId)); - Bank bank = createBank(url, bankName, hostId, useCertificates); + Bank bank = createBank(url, bankName, hostId); Partner partner = createPartner(bank, partnerId); try { User user = new User(partner, userId, name, email, country, organization, @@ -201,27 +218,26 @@ public User createUser(URL url, String bankName, String hostId, String partnerId configuration.getSerializationManager().serialize(bank); configuration.getSerializationManager().serialize(partner); configuration.getSerializationManager().serialize(user); - createLetters(user, useCertificates); + createLetters(user); users.put(userId, user); partners.put(partner.getPartnerId(), partner); banks.put(bank.getHostId(), bank); - configuration.getLogger().info(messages.getString("user.create.success", userId)); + log.info(messages.getString("user.create.success", userId)); return user; } catch (Exception e) { - configuration.getLogger().error(messages.getString("user.create.error"), e); + log.error(messages.getString("user.create.error"), e); throw e; } } - private void createLetters(EbicsUser user, boolean useCertificates) + private void createLetters(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException { - user.getPartner().getBank().setUseCertificate(useCertificates); LetterManager letterManager = configuration.getLetterManager(); - List letters = Arrays.asList(letterManager.createA005Letter(user), + List letters = List.of(letterManager.createA005Letter(user), letterManager.createE002Letter(user), letterManager.createX002Letter(user)); - File directory = new File(configuration.getLettersDirectory(user)); + File directory = configuration.getLettersDirectory(user); for (InitLetter letter : letters) { try (FileOutputStream out = new FileOutputStream(new File(directory, letter.getName()))) { letter.writeTo(out); @@ -231,12 +247,10 @@ private void createLetters(EbicsUser user, boolean useCertificates) /** * Loads a user knowing its ID - * - * @throws Exception */ public User loadUser(String hostId, String partnerId, String userId, PasswordCallback passwordCallback) throws Exception { - configuration.getLogger().info(messages.getString("user.load.info", userId)); + log.info(messages.getString("user.load.info", userId)); try { Bank bank; @@ -257,10 +271,10 @@ public User loadUser(String hostId, String partnerId, String userId, users.put(userId, user); partners.put(partner.getPartnerId(), partner); banks.put(bank.getHostId(), bank); - configuration.getLogger().info(messages.getString("user.load.success", userId)); + log.info(messages.getString("user.load.success", userId)); return user; } catch (Exception e) { - configuration.getLogger().error(messages.getString("user.load.error"), e); + log.error(messages.getString("user.load.error"), e); throw e; } } @@ -270,15 +284,14 @@ public User loadUser(String hostId, String partnerId, String userId, * * @param user the user * @param product the application product - * @throws Exception */ public void sendINIRequest(User user, Product product) throws Exception { String userId = user.getUserId(); - configuration.getLogger().info(messages.getString("ini.request.send", userId)); - if (user.isInitialized()) { - configuration.getLogger().info(messages.getString("user.already.initialized", userId)); - return; - } + log.info(messages.getString("ini.request.send", userId)); +// if (user.isInitialized()) { +// log.info(messages.getString("user.already.initialized", userId)); +// return; +// } EbicsSession session = createSession(user, product); KeyManagement keyManager = new KeyManagement(session); configuration.getTraceManager().setTraceDirectory( @@ -286,9 +299,9 @@ public void sendINIRequest(User user, Product product) throws Exception { try { keyManager.sendINI(null); user.setInitialized(true); - configuration.getLogger().info(messages.getString("ini.send.success", userId)); + log.info(messages.getString("ini.send.success", userId)); } catch (Exception e) { - configuration.getLogger().error(messages.getString("ini.send.error", userId), e); + log.error(messages.getString("ini.send.error", userId), e); throw e; } } @@ -300,16 +313,15 @@ public void sendINIRequest(User user, Product product) throws Exception { * the user ID. * @param product * the application product. - * @throws Exception */ public void sendHIARequest(User user, Product product) throws Exception { String userId = user.getUserId(); - configuration.getLogger().info(messages.getString("hia.request.send", userId)); - if (user.isInitializedHIA()) { - configuration.getLogger() - .info(messages.getString("user.already.hia.initialized", userId)); - return; - } + log.info(messages.getString("hia.request.send", userId)); +// if (user.isInitializedHIA()) { +// logger +// .info(messages.getString("user.already.hia.initialized", userId)); +// return; +// } EbicsSession session = createSession(user, product); KeyManagement keyManager = new KeyManagement(session); configuration.getTraceManager().setTraceDirectory( @@ -318,10 +330,10 @@ public void sendHIARequest(User user, Product product) throws Exception { keyManager.sendHIA(null); user.setInitializedHIA(true); } catch (Exception e) { - configuration.getLogger().error(messages.getString("hia.send.error", userId), e); + log.error(messages.getString("hia.send.error", userId), e); throw e; } - configuration.getLogger().info(messages.getString("hia.send.success", userId)); + log.info(messages.getString("hia.send.success", userId)); } /** @@ -329,7 +341,7 @@ public void sendHIARequest(User user, Product product) throws Exception { */ public void sendHPBRequest(User user, Product product) throws Exception { String userId = user.getUserId(); - configuration.getLogger().info(messages.getString("hpb.request.send", userId)); + log.info(messages.getString("hpb.request.send", userId)); EbicsSession session = createSession(user, product); KeyManagement keyManager = new KeyManagement(session); @@ -339,9 +351,9 @@ public void sendHPBRequest(User user, Product product) throws Exception { try { keyManager.sendHPB(); - configuration.getLogger().info(messages.getString("hpb.send.success", userId)); + log.info(messages.getString("hpb.send.success", userId)); } catch (Exception e) { - configuration.getLogger().error(messages.getString("hpb.send.error", userId), e); + log.error(messages.getString("hpb.send.error", userId), e); throw e; } } @@ -358,7 +370,7 @@ public void sendHPBRequest(User user, Product product) throws Exception { public void revokeSubscriber(User user, Product product) throws Exception { String userId = user.getUserId(); - configuration.getLogger().info(messages.getString("spr.request.send", userId)); + log.info(messages.getString("spr.request.send", userId)); EbicsSession session = createSession(user, product); KeyManagement keyManager = new KeyManagement(session); @@ -369,20 +381,19 @@ public void revokeSubscriber(User user, Product product) throws Exception { try { keyManager.lockAccess(); } catch (Exception e) { - configuration.getLogger().error(messages.getString("spr.send.error", userId), e); + log.error(messages.getString("spr.send.error", userId)); throw e; } - configuration.getLogger().info(messages.getString("spr.send.success", userId)); + log.info(messages.getString("spr.send.success", userId)); } /** * Sends a file to the ebics bank server * @throws Exception */ - public void sendFile(File file, User user, Product product, OrderType orderType) throws Exception { + public void sendFile(File file, User user, Product product, EbicsOrderType orderType, EbicsUploadParams params) throws Exception { EbicsSession session = createSession(user, product); - OrderAttributeType.Enum orderAttribute = OrderAttributeType.OZHNN; FileTransfer transferManager = new FileTransfer(session); @@ -390,20 +401,55 @@ public void sendFile(File file, User user, Product product, OrderType orderType) configuration.getTransferTraceDirectory(user)); try { - transferManager.sendFile(IOUtils.getFileContent(file), orderType, orderAttribute); + transferManager.sendFile(IOUtils.getFileContent(file), orderType, params); } catch (IOException | EbicsException e) { - configuration.getLogger() - .error(messages.getString("upload.file.error", file.getAbsolutePath()), e); + log + .error(messages.getString("upload.file.error", file.getAbsolutePath())); throw e; } } - public void sendFile(File file, OrderType orderType) throws Exception { - sendFile(file, defaultUser, defaultProduct, orderType); + public void sendFile(File file, EbicsOrderType orderType, EbicsUploadParams params) throws Exception { + sendFile(file, defaultUser, defaultProduct, orderType, params); + } + + public void sendFile(File file, EbicsOrderType orderType) throws Exception { + EbicsUploadParams params; + if (orderType == OrderType.XE2) { + var orderParams = new EbicsUploadParams.OrderParams("MCT", "CH", null, "pain.001", + "03", true); + params = new EbicsUploadParams(null, orderParams); + } else { + params = new EbicsUploadParams(defaultUser.getPartner().nextOrderId(), null); + } + sendFile(file, defaultUser, defaultProduct, orderType, params); + } + + public void fetchFile(File file, User user, Product product, EbicsOrderType orderType, + boolean isTest) throws IOException, EbicsException { + fetchFile(file, user, product, orderType, null, isTest); } - public void fetchFile(File file, User user, Product product, OrderType orderType, - boolean isTest, Date start, Date end) throws IOException, EbicsException { + /** + * Downloads a file for the default user, with EBICS 3.0 service parameters. + * + *

The counterpart of {@link #sendFile(File, EbicsOrderType, EbicsUploadParams)}: callers + * that use the default user have no other way to reach the BTD path, since the default + * product is not exposed. + */ + public void fetchFile(File file, EbicsOrderType orderType, EbicsDownloadParams downloadParams) + throws IOException, EbicsException { + fetchFile(file, defaultUser, defaultProduct, orderType, downloadParams, false); + } + + /** + * Downloads a file from the bank. + * + * @param downloadParams optional EBICS 3.0 service parameters and report period; with a + * service name set the order is sent as a BTD business transaction format order + */ + public void fetchFile(File file, User user, Product product, EbicsOrderType orderType, + EbicsDownloadParams downloadParams, boolean isTest) throws IOException, EbicsException { FileTransfer transferManager; EbicsSession session = createSession(user, product); session.addSessionParam("FORMAT", "pain.xxx.cfonb160.dct"); @@ -416,19 +462,32 @@ public void fetchFile(File file, User user, Product product, OrderType orderType configuration.getTransferTraceDirectory(user)); try { - transferManager.fetchFile(orderType, start, end, file); + transferManager.fetchFile(orderType, downloadParams, file); } catch (NoDownloadDataAvailableException e) { // don't log this exception as an error, caller can decide how to handle throw e; } catch (Exception e) { - configuration.getLogger().error(messages.getString("download.file.error"), e); + log.error("{} {}", messages.getString("download.file.error"), e.getMessage(), e); throw e; } } - public void fetchFile(File file, OrderType orderType, Date start, Date end) throws IOException, + /** + * Downloads a file for a report period. + * + *

A {@link Date} is an instant, the EBICS report period is a pair of calendar days. + * The calendar day is therefore read in the timezone of the machine running this code, so a + * {@code Date} at UTC midnight becomes the previous day in any zone west of UTC. Prefer + * {@link #fetchFile(File, User, Product, EbicsOrderType, EbicsDownloadParams, boolean)} with + * {@link java.time.LocalDate} values, which has no timezone in it. + */ + public void fetchFile(File file, EbicsOrderType orderType, Date start, Date end) throws IOException, EbicsException { - fetchFile(file, defaultUser, defaultProduct, orderType, false, start, end); + fetchFile(file, defaultUser, defaultProduct, orderType, + EbicsDownloadParams.dateRangeOnly( + start == null ? null : EbicsXmlFactory.toLocalDate(start), + end == null ? null : EbicsXmlFactory.toLocalDate(end)), + false); } /** @@ -438,7 +497,7 @@ public void quit() { try { for (User user : users.values()) { if (user.needsSave()) { - configuration.getLogger() + log .info(messages.getString("app.quit.users", user.getUserId())); configuration.getSerializationManager().serialize(user); } @@ -446,7 +505,7 @@ public void quit() { for (Partner partner : partners.values()) { if (partner.needsSave()) { - configuration.getLogger() + log .info(messages.getString("app.quit.partners", partner.getPartnerId())); configuration.getSerializationManager().serialize(partner); } @@ -454,20 +513,20 @@ public void quit() { for (Bank bank : banks.values()) { if (bank.needsSave()) { - configuration.getLogger() + log .info(messages.getString("app.quit.banks", bank.getHostId())); configuration.getSerializationManager().serialize(bank); } } } catch (EbicsException e) { - configuration.getLogger().info(messages.getString("app.quit.error")); + log.info(messages.getString("app.quit.error")); } clearTraces(); } public void clearTraces() { - configuration.getLogger().info(messages.getString("app.cache.clear")); + log.info(messages.getString("app.cache.clear")); configuration.getTraceManager().clear(); } @@ -498,20 +557,20 @@ private User createUser(ConfigProperties properties, PasswordCallback pwdHandler String userEmail = properties.get("user.email"); String userCountry = properties.get("user.country"); String userOrg = properties.get("user.org"); - boolean useCertificates = false; boolean saveCertificates = true; return createUser(new URL(bankUrl), bankName, hostId, partnerId, userId, userName, userEmail, - userCountry, userOrg, useCertificates, saveCertificates, pwdHandler); + userCountry, userOrg, saveCertificates, pwdHandler); } - private static CommandLine parseArguments(Options options, String[] args) throws ParseException { + private static CommandLine parseArguments(Options options, String[] args) + throws ParseException, IOException { CommandLineParser parser = new DefaultParser(); options.addOption(null, "help", false, "Print this help text"); CommandLine line = parser.parse(options, args); if (line.hasOption("help")) { - HelpFormatter formatter = new HelpFormatter(); + HelpFormatter formatter = HelpFormatter.builder().get(); System.out.println(); - formatter.printHelp(EbicsClient.class.getSimpleName(), options); + formatter.printHelp(EbicsClient.class.getSimpleName(), "", options, "", true); System.out.println(); System.exit(0); } @@ -526,7 +585,7 @@ public static EbicsClient createEbicsClient(File rootDir, File configFile) throw final Locale locale = new Locale(language, country); - DefaultConfiguration configuration = new DefaultConfiguration(rootDir.getAbsolutePath(), + DefaultConfiguration configuration = new DefaultConfiguration(rootDir, properties.properties) { @Override @@ -574,12 +633,12 @@ public User getDefaultUser() { return defaultUser; } - private static void addOption(Options options, OrderType type, String description) { - options.addOption(null, type.name().toLowerCase(), false, description); + private static void addOption(Options options, EbicsOrderType type, String description) { + options.addOption(null, type.getCode().toLowerCase(), false, description); } - private static boolean hasOption(CommandLine cmd, OrderType type) { - return cmd.hasOption(type.name().toLowerCase()); + private static boolean hasOption(CommandLine cmd, EbicsOrderType type) { + return cmd.hasOption(type.getCode().toLowerCase()); } public static void main(String[] args) throws Exception { @@ -589,7 +648,7 @@ public static void main(String[] args) throws Exception { addOption(options, OrderType.HPB, "Send HPB request"); options.addOption(null, "letters", false, "Create INI Letters"); options.addOption(null, "create", false, "Create and initialize EBICS user"); - addOption(options, OrderType.STA,"Fetch STA file (MT940 file)"); + addOption(options, OrderType.STA, "Fetch STA file (MT940 file)"); addOption(options, OrderType.VMK, "Fetch VMK file (MT942 file)"); addOption(options, OrderType.C52, "Fetch camt.052 file"); addOption(options, OrderType.C53, "Fetch camt.053 file"); @@ -614,8 +673,7 @@ public static void main(String[] args) throws Exception { CommandLine cmd = parseArguments(options, args); - File defaultRootDir = new File(System.getProperty("user.home") + File.separator + "ebics" - + File.separator + "client"); + File defaultRootDir = getRootDir(); File ebicsClientProperties = new File(defaultRootDir, "ebics.txt"); EbicsClient client = createEbicsClient(defaultRootDir, ebicsClientProperties); @@ -626,7 +684,7 @@ public static void main(String[] args) throws Exception { } if (cmd.hasOption("letters")) { - client.createLetters(client.defaultUser, false); + client.createLetters(client.defaultUser); } if (hasOption(cmd, OrderType.INI)) { @@ -642,24 +700,23 @@ public static void main(String[] args) throws Exception { String outputFileValue = cmd.getOptionValue("o"); String inputFileValue = cmd.getOptionValue("i"); - List fetchFileOrders = Arrays.asList(OrderType.STA, OrderType.VMK, + var fetchFileOrders = List.of(OrderType.STA, OrderType.VMK, OrderType.C52, OrderType.C53, OrderType.C54, OrderType.ZDF, OrderType.ZB6, OrderType.PTK, OrderType.HAC, OrderType.Z01); - for (OrderType type : fetchFileOrders) { + for (EbicsOrderType type : fetchFileOrders) { if (hasOption(cmd, type)) { client.fetchFile(getOutputFile(outputFileValue), client.defaultUser, - client.defaultProduct, type, false, null, null); + client.defaultProduct, type, false); break; } } - List sendFileOrders = Arrays.asList(OrderType.XKD, OrderType.FUL, OrderType.XCT, + var sendFileOrders = List.of(OrderType.XKD, OrderType.FUL, OrderType.XCT, OrderType.XE2, OrderType.CCT); - for (OrderType type : sendFileOrders) { + for (EbicsOrderType type : sendFileOrders) { if (hasOption(cmd, type)) { - client.sendFile(new File(inputFileValue), client.defaultUser, - client.defaultProduct, type); + client.sendFile(new File(inputFileValue), type); break; } } diff --git a/src/main/java/org/kopi/ebics/client/EbicsDownloadParams.java b/src/main/java/org/kopi/ebics/client/EbicsDownloadParams.java new file mode 100644 index 00000000..9a701fec --- /dev/null +++ b/src/main/java/org/kopi/ebics/client/EbicsDownloadParams.java @@ -0,0 +1,56 @@ +package org.kopi.ebics.client; + +import java.time.LocalDate; + +/** + * Service parameters for an EBICS 3.0 (H005) BTD download order. + * + *

With a {@code serviceName} set, the request is sent as {@code AdminOrderType=BTD} with a + * {@code BTDOrderParams/Service} block. With {@code serviceName} left {@code null}, only the + * optional date range is applied and the legacy EBICS 2.x order type is kept, so existing + * callers keep their behaviour. + * + *

The report period is a pair of calendar days ({@link LocalDate}), not instants: EBICS sends + * it as {@code xs:date}, and a timezone in that position only creates off-by-one-day bugs. + * + *

The constructor rejects a partial or reversed range. Both would otherwise travel silently: + * a half range is dropped when the request is built, and a reversed one is schema-valid and comes + * back as "no data available", which is indistinguishable from a period that really was empty. + * This is the single place every caller passes through, so the check lives here rather than in + * each caller. + */ +public record EbicsDownloadParams( + String serviceName, + String scope, + String option, + String messageName, + String messageVersion, + String containerType, + LocalDate startDate, + LocalDate endDate) { + + public EbicsDownloadParams { + if ((startDate == null) != (endDate == null)) { + throw new IllegalArgumentException( + "startDate and endDate must be given together (--start/--end); a single one" + + " would be dropped from the bank request"); + } + if (startDate != null && endDate.isBefore(startDate)) { + throw new IllegalArgumentException( + "endDate must not be before startDate, got " + startDate + " to " + endDate); + } + } + + /** Date-range-only parameters for the legacy (non-BTD) download path. */ + public static EbicsDownloadParams dateRangeOnly(LocalDate startDate, LocalDate endDate) { + if (startDate == null && endDate == null) { + return null; + } + return new EbicsDownloadParams(null, null, null, null, null, null, startDate, endDate); + } + + /** Whether these parameters describe an EBICS 3.0 BTD business transaction format order. */ + public boolean isBtd() { + return serviceName != null; + } +} diff --git a/src/main/java/org/kopi/ebics/client/EbicsUploadParams.java b/src/main/java/org/kopi/ebics/client/EbicsUploadParams.java new file mode 100644 index 00000000..327dfdab --- /dev/null +++ b/src/main/java/org/kopi/ebics/client/EbicsUploadParams.java @@ -0,0 +1,8 @@ +package org.kopi.ebics.client; + +public record EbicsUploadParams(String orderId, OrderParams orderParams) { + + public record OrderParams(String serviceName, String scope, String option, String messageName, + String messageVersion, boolean signatureFlag) { + } +} diff --git a/src/main/java/org/kopi/ebics/client/FileTransfer.java b/src/main/java/org/kopi/ebics/client/FileTransfer.java index 55817b62..c4151144 100644 --- a/src/main/java/org/kopi/ebics/client/FileTransfer.java +++ b/src/main/java/org/kopi/ebics/client/FileTransfer.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; @@ -22,16 +21,14 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.Date; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; +import org.kopi.ebics.interfaces.EbicsOrderType; import org.kopi.ebics.io.ByteArrayContentFactory; import org.kopi.ebics.io.Joiner; import org.kopi.ebics.messages.Messages; -import org.kopi.ebics.schema.h003.OrderAttributeType; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; import org.kopi.ebics.utils.Constants; import org.kopi.ebics.utils.Utils; import org.kopi.ebics.xml.DefaultEbicsRootElement; @@ -45,7 +42,8 @@ import org.kopi.ebics.xml.TransferResponseElement; import org.kopi.ebics.xml.UploadInitializationRequestElement; import org.kopi.ebics.xml.UploadTransferRequestElement; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Handling of file transfers. @@ -74,11 +72,10 @@ * asymmetrical encryption takes place with the public encryption key of the non-technical * subscriber, i.e. the submitter of the order. * - * @author Hachani * */ public class FileTransfer { - + private static final Logger log = LoggerFactory.getLogger(FileTransfer.class); /** * Constructs a new FileTransfer session * @param session the user session @@ -94,13 +91,11 @@ public FileTransfer(EbicsSession session) { * @throws IOException * @throws EbicsException */ - public void sendFile(byte[] content, OrderType orderType, OrderAttributeType.Enum orderAttribute) + public void sendFile(byte[] content, EbicsOrderType orderType, EbicsUploadParams params) throws IOException, EbicsException { HttpRequestSender sender = new HttpRequestSender(session); - UploadInitializationRequestElement initializer = new UploadInitializationRequestElement(session, - orderType, orderAttribute, - content); + var initializer = new UploadInitializationRequestElement(session, orderType, params, content); initializer.build(); initializer.validate(); session.getConfiguration().getTraceManager().trace(initializer.getUserSignature()); @@ -128,7 +123,7 @@ public void sendFile(byte[] content, OrderType orderType, OrderAttributeType.Enu * @param factory the content factory that contain the segment data. * @param segmentNumber the segment number * @param lastSegment is it the last segment? - * @param transactionId the transaction Id + * @param transactionId the transaction id * @param orderType the order type * @throws IOException * @throws EbicsException @@ -137,7 +132,7 @@ public void sendFile(ContentFactory factory, int segmentNumber, boolean lastSegment, byte[] transactionId, - OrderType orderType) + EbicsOrderType orderType) throws IOException, EbicsException { UploadTransferRequestElement uploader; @@ -146,8 +141,7 @@ public void sendFile(ContentFactory factory, int httpCode; Messages messages = new Messages(Constants.APPLICATION_BUNDLE_NAME); - session.getConfiguration().getLogger() - .info(messages.getString("upload.segment", segmentNumber)); + log.info(messages.getString("upload.segment", segmentNumber)); uploader = new UploadTransferRequestElement(session, orderType, segmentNumber, @@ -172,53 +166,54 @@ public void sendFile(ContentFactory factory, * This type of transfer will run until everything is processed. * No transaction recovery is possible. * @param orderType type of file to fetch - * @param start optional begin of fetch term - * @param end optional end of fetch term * @param outputFile where to put the data * @throws IOException communication error * @throws EbicsException server generated error */ - public void fetchFile(OrderType orderType, - Date start, - Date end, + public void fetchFile(EbicsOrderType orderType, File outputFile) throws IOException, EbicsException { - HttpRequestSender sender; - DownloadInitializationRequestElement initializer; - DownloadInitializationResponseElement response; - ReceiptRequestElement receipt; - ReceiptResponseElement receiptResponse; - int httpCode; - TransferState state; - Joiner joiner; + fetchFile(orderType, null, outputFile); + } - sender = new HttpRequestSender(session); - initializer = new DownloadInitializationRequestElement(session, - orderType, - start, - end); + /** + * Fetches a file of the given order type from the bank. + * This type of transfer will run until everything is processed. + * No transaction recovery is possible. + * @param orderType type of file to fetch + * @param downloadParams optional EBICS 3.0 service parameters and report period + * @param outputFile where to put the data + * @throws IOException communication error + * @throws EbicsException server generated error + */ + public void fetchFile(EbicsOrderType orderType, + EbicsDownloadParams downloadParams, + File outputFile) + throws IOException, EbicsException + { + var sender = new HttpRequestSender(session); + var initializer = new DownloadInitializationRequestElement(session, orderType, downloadParams); initializer.build(); initializer.validate(); session.getConfiguration().getTraceManager().trace(initializer); - httpCode = sender.send(new ByteArrayContentFactory(initializer.prettyPrint())); + var request = initializer.prettyPrint(); + var httpCode = sender.send(new ByteArrayContentFactory(request)); Utils.checkHttpCode(httpCode); - response = new DownloadInitializationResponseElement(sender.getResponseBody(), + var response = new DownloadInitializationResponseElement(sender.getResponseBody(), orderType, DefaultEbicsRootElement.generateName(orderType)); response.build(); session.getConfiguration().getTraceManager().trace(response); response.report(); - state = new TransferState(response.getSegmentsNumber(), response.getTransactionId()); + var state = new TransferState(response.getSegmentsNumber(), response.getTransactionId()); state.setSegmentNumber(response.getSegmentNumber()); - joiner = new Joiner(session.getUser()); + var joiner = new Joiner(session.getUser()); joiner.append(response.getOrderData()); while(state.hasNext()) { - int segmentNumber; - - segmentNumber = state.next(); + int segmentNumber = state.next(); fetchFile(orderType, segmentNumber, state.isLastSegment(), @@ -229,7 +224,7 @@ public void fetchFile(OrderType orderType, try (FileOutputStream dest = new FileOutputStream(outputFile)) { joiner.writeTo(dest, response.getTransactionKey()); } - receipt = new ReceiptRequestElement(session, + var receipt = new ReceiptRequestElement(session, state.getTransactionId(), DefaultEbicsRootElement.generateName(orderType)); receipt.build(); @@ -237,7 +232,7 @@ public void fetchFile(OrderType orderType, session.getConfiguration().getTraceManager().trace(receipt); httpCode = sender.send(new ByteArrayContentFactory(receipt.prettyPrint())); Utils.checkHttpCode(httpCode); - receiptResponse = new ReceiptResponseElement(sender.getResponseBody(), + var receiptResponse = new ReceiptResponseElement(sender.getResponseBody(), DefaultEbicsRootElement.generateName(orderType)); receiptResponse.build(); session.getConfiguration().getTraceManager().trace(receiptResponse); @@ -254,7 +249,7 @@ public void fetchFile(OrderType orderType, * @throws IOException communication error * @throws EbicsException server generated error */ - public void fetchFile(OrderType orderType, + public void fetchFile(EbicsOrderType orderType, int segmentNumber, boolean lastSegment, byte[] transactionId, diff --git a/src/main/java/org/kopi/ebics/client/HttpRequestSender.java b/src/main/java/org/kopi/ebics/client/HttpRequestSender.java index 8f78ff08..82abbf71 100644 --- a/src/main/java/org/kopi/ebics/client/HttpRequestSender.java +++ b/src/main/java/org/kopi/ebics/client/HttpRequestSender.java @@ -14,29 +14,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; import java.io.IOException; -import java.io.InputStream; +import java.net.Authenticator; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.ProxySelector; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.entity.EntityBuilder; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.ProxyAuthenticationStrategy; -import org.apache.http.util.EntityUtils; import org.kopi.ebics.interfaces.Configuration; import org.kopi.ebics.interfaces.ContentFactory; import org.kopi.ebics.io.ByteArrayContentFactory; @@ -49,71 +41,84 @@ */ public class HttpRequestSender { + private static final Duration TIMEOUT = Duration.ofSeconds(300); + private static final String CONTENT_TYPE = "text/xml; charset=ISO-8859-1"; + private final EbicsSession session; private ContentFactory response; + private final HttpClient httpClient; /** * Constructs a new HttpRequestSender with a given ebics * session. * - * @param session - * the ebics session + * @param session the ebics session */ public HttpRequestSender(EbicsSession session) { this.session = session; + this.httpClient = createClient(); } - /** - * Sends the request contained in the ContentFactory. The - * ContentFactory will deliver the request as an - * InputStream. - * - * @param request - * the ebics request - * @return the HTTP return code - */ - public final int send(ContentFactory request) throws IOException { - RequestConfig.Builder configBuilder = RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout( - 300_000).setConnectTimeout(300_000); - + private HttpClient createClient() { + HttpClient.Builder builder = HttpClient.newBuilder().connectTimeout(TIMEOUT); Configuration conf = session.getConfiguration(); String proxyHost = conf.getProperty("http.proxy.host"); - CredentialsProvider credsProvider = null; - if (proxyHost != null && !proxyHost.equals("")) { + if (proxyHost != null && !proxyHost.isEmpty()) { int proxyPort = Integer.parseInt(conf.getProperty("http.proxy.port").trim()); - HttpHost proxy = new HttpHost(proxyHost.trim(), proxyPort); - configBuilder.setProxy(proxy); + builder.proxy(ProxySelector.of(new InetSocketAddress(proxyHost.trim(), proxyPort))); String user = conf.getProperty("http.proxy.user"); - if (user != null && !user.equals("")) { - user = user.trim(); + if (user != null && !user.isEmpty()) { + String trimmedUser = user.trim(); String pwd = conf.getProperty("http.proxy.password").trim(); - credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(new AuthScope(proxyHost, proxyPort), - new UsernamePasswordCredentials(user, pwd)); + builder.authenticator(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + // Only answer proxy challenges — never leak proxy + // credentials to a server-side 401. + if (getRequestorType() != RequestorType.PROXY) { + return null; + } + return new PasswordAuthentication(trimmedUser, pwd.toCharArray()); + } + }); } } - HttpClientBuilder builder = HttpClientBuilder.create().setDefaultRequestConfig( - configBuilder.build()); - if (credsProvider != null) { - builder.setDefaultCredentialsProvider(credsProvider); - builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); - } - CloseableHttpClient httpClient = builder.build(); - - InputStream input = request.getContent(); - HttpPost method = new HttpPost(session.getUser().getPartner().getBank().getURL().toString()); + return builder.build(); + } - HttpEntity requestEntity = EntityBuilder.create().setStream(input).build(); - method.setEntity(requestEntity); - method.setHeader(HttpHeaders.CONTENT_TYPE, "text/xml; charset=ISO-8859-1"); + /** + * Sends the request contained in the ContentFactory. The + * ContentFactory will deliver the request as an + * InputStream. + * + * @param request the ebics request + * @return the HTTP return code + */ + public final int send(ContentFactory request) throws IOException { + URI uri = URI.create(session.getUser().getPartner().getBank().getURL().toString()); + HttpRequest httpRequest = HttpRequest.newBuilder(uri) + .timeout(TIMEOUT) + .header("Content-Type", CONTENT_TYPE) + .POST(HttpRequest.BodyPublishers.ofInputStream(() -> { + try { + return request.getContent(); + } catch (IOException e) { + throw new RuntimeException(e); + } + })) + .build(); - try (CloseableHttpResponse response = httpClient.execute(method)) { - this.response = new ByteArrayContentFactory( - EntityUtils.toByteArray(response.getEntity())); - return response.getStatusLine().getStatusCode(); + HttpResponse httpResponse; + try { + httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofByteArray()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IOException("HTTP request interrupted", e); } + this.response = new ByteArrayContentFactory(httpResponse.body()); + return httpResponse.statusCode(); } /** diff --git a/src/main/java/org/kopi/ebics/client/KeyManagement.java b/src/main/java/org/kopi/ebics/client/KeyManagement.java index cda99429..779a941f 100644 --- a/src/main/java/org/kopi/ebics/client/KeyManagement.java +++ b/src/main/java/org/kopi/ebics/client/KeyManagement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; @@ -23,14 +22,14 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.math.BigInteger; import java.security.GeneralSecurityException; -import java.security.interfaces.RSAPublicKey; import org.kopi.ebics.certificate.KeyStoreManager; import org.kopi.ebics.certificate.KeyUtil; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; +import org.kopi.ebics.interfaces.EbicsBank; +import org.kopi.ebics.interfaces.EbicsUser; import org.kopi.ebics.io.ByteArrayContentFactory; import org.kopi.ebics.session.EbicsSession; import org.kopi.ebics.utils.Utils; @@ -42,167 +41,146 @@ import org.kopi.ebics.xml.SPRRequestElement; import org.kopi.ebics.xml.SPRResponseElement; - /** * Everything that has to do with key handling. * If you have a totally new account use sendINI() and sendHIA() to send you newly created keys to the bank. * Then wait until the bank activated your keys. * If you are migrating from FTAM. Just send HPB, your EBICS account should be usable without delay. * - * @author Hachani * */ public class KeyManagement { - /** - * Constructs a new KeyManagement instance - * with a given ebics session - * @param session the ebics session - */ - public KeyManagement(EbicsSession session) { - this.session = session; - } - - /** - * Sends the user's signature key (A005) to the bank. - * After successful operation the user is in state "initialized". - * @param orderId the order ID. Let it null to generate a random one. - * @throws EbicsException server generated error message - * @throws IOException communication error - */ - public void sendINI(String orderId) throws EbicsException, IOException { - INIRequestElement request; - KeyManagementResponseElement response; - HttpRequestSender sender; - int httpCode; - - sender = new HttpRequestSender(session); - request = new INIRequestElement(session, orderId); - request.build(); - request.validate(); - session.getConfiguration().getTraceManager().trace(request); - httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); - Utils.checkHttpCode(httpCode); - response = new KeyManagementResponseElement(sender.getResponseBody(), "INIResponse"); - response.build(); - session.getConfiguration().getTraceManager().trace(response); - response.report(); - } - - /** - * Sends the public part of the protocol keys to the bank. - * @param orderId the order ID. Let it null to generate a random one. - * @throws IOException communication error - * @throws EbicsException server generated error message - */ - public void sendHIA(String orderId) throws IOException, EbicsException { - HIARequestElement request; - KeyManagementResponseElement response; - HttpRequestSender sender; - int httpCode; - - sender = new HttpRequestSender(session); - request = new HIARequestElement(session, orderId); - request.build(); - request.validate(); - session.getConfiguration().getTraceManager().trace(request); - httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); - Utils.checkHttpCode(httpCode); - response = new KeyManagementResponseElement(sender.getResponseBody(), "HIAResponse"); - response.build(); - session.getConfiguration().getTraceManager().trace(response); - response.report(); - } - - /** - * Sends encryption and authentication keys to the bank. - * This order is only allowed for a new user at the bank side that has been created by copying the A005 key. - * The keys will be activated immediately after successful completion of the transfer. - * @throws IOException communication error - * @throws GeneralSecurityException data decryption error - * @throws EbicsException server generated error message - */ - public void sendHPB() throws IOException, GeneralSecurityException, EbicsException { - HPBRequestElement request; - KeyManagementResponseElement response; - HttpRequestSender sender; - HPBResponseOrderDataElement orderData; - ContentFactory factory; - KeyStoreManager keystoreManager; - String path; - RSAPublicKey e002PubKey; - RSAPublicKey x002PubKey; - int httpCode; - - sender = new HttpRequestSender(session); - request = new HPBRequestElement(session); - request.build(); - request.validate(); - session.getConfiguration().getTraceManager().trace(request); - httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); - Utils.checkHttpCode(httpCode); - response = new KeyManagementResponseElement(sender.getResponseBody(), "HBPResponse"); - response.build(); - session.getConfiguration().getTraceManager().trace(response); - response.report(); - factory = new ByteArrayContentFactory(Utils.unzip(session.getUser().decrypt(response.getOrderData(), response.getTransactionKey()))); - orderData = new HPBResponseOrderDataElement(factory); - orderData.build(); - session.getConfiguration().getTraceManager().trace(orderData); - keystoreManager = new KeyStoreManager(); - path = session.getConfiguration().getKeystoreDirectory(session.getUser()); - keystoreManager.load("" , session.getUser().getPasswordCallback().getPassword()); + /** + * Constructs a new KeyManagement instance + * with a given ebics session + * + * @param session the ebics session + */ + public KeyManagement(EbicsSession session) { + this.session = session; + } - if (session.getUser().getPartner().getBank().useCertificate()) - { - e002PubKey = keystoreManager.getPublicKey(new ByteArrayInputStream(orderData.getBankE002Certificate())); - x002PubKey = keystoreManager.getPublicKey(new ByteArrayInputStream(orderData.getBankX002Certificate())); - session.getUser().getPartner().getBank().setBankKeys(e002PubKey, x002PubKey); - session.getUser().getPartner().getBank().setDigests(KeyUtil.getKeyDigest(e002PubKey), KeyUtil.getKeyDigest(x002PubKey)); - keystoreManager.setCertificateEntry(session.getBankID() + "-E002", new ByteArrayInputStream(orderData.getBankE002Certificate())); - keystoreManager.setCertificateEntry(session.getBankID() + "-X002", new ByteArrayInputStream(orderData.getBankX002Certificate())); - keystoreManager.save(new FileOutputStream(path + File.separator + session.getBankID() + ".p12")); + /** + * Sends the user's signature key (A005) to the bank. + * After successful operation the user is in state "initialized". + * + * @param orderId the order ID. Let it null to generate a random one. + * @throws EbicsException server generated error message + * @throws IOException communication error + */ + public void sendINI(String orderId) throws EbicsException, IOException { + var sender = new HttpRequestSender(session); + var request = new INIRequestElement(session, orderId); + request.build(); + request.validate(); + session.getConfiguration().getTraceManager().trace(request); + int httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); + Utils.checkHttpCode(httpCode); + var response = new KeyManagementResponseElement(sender.getResponseBody(), "INIResponse"); + response.build(); + session.getConfiguration().getTraceManager().trace(response); + response.report(); } - else - { - e002PubKey = keystoreManager.getPublicKey(new BigInteger(orderData.getBankE002PublicKeyExponent()), new BigInteger(orderData.getBankE002PublicKeyModulus())); - x002PubKey = keystoreManager.getPublicKey(new BigInteger(orderData.getBankX002PublicKeyExponent()), new BigInteger(orderData.getBankX002PublicKeyModulus())); - session.getUser().getPartner().getBank().setBankKeys(e002PubKey, x002PubKey); - session.getUser().getPartner().getBank().setDigests(KeyUtil.getKeyDigest(e002PubKey), KeyUtil.getKeyDigest(x002PubKey)); - //keystoreManager.setCertificateEntry(session.getBankID() + "-E002", new ByteArrayInputStream(orderData.getBankE002Certificate())); - //keystoreManager.setCertificateEntry(session.getBankID() + "-X002", new ByteArrayInputStream(orderData.getBankX002Certificate())); - keystoreManager.save(new FileOutputStream(path + File.separator + session.getBankID() + ".p12")); + + /** + * Sends the public part of the protocol keys to the bank. + * + * @param orderId the order ID. Let it null to generate a random one. + * @throws IOException communication error + * @throws EbicsException server generated error message + */ + public void sendHIA(String orderId) throws IOException, EbicsException { + HttpRequestSender sender = new HttpRequestSender(session); + HIARequestElement request = new HIARequestElement(session, orderId); + request.build(); + request.validate(); + session.getConfiguration().getTraceManager().trace(request); + int httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); + Utils.checkHttpCode(httpCode); + KeyManagementResponseElement response = new KeyManagementResponseElement( + sender.getResponseBody(), "HIAResponse"); + response.build(); + session.getConfiguration().getTraceManager().trace(response); + response.report(); } - } - /** - * Sends the SPR order to the bank. - * After that you have to start over with sending INI and HIA. - * @throws IOException Communication exception - * @throws EbicsException Error message generated by the bank. - */ - public void lockAccess() throws IOException, EbicsException { - HttpRequestSender sender; - SPRRequestElement request; - SPRResponseElement response; - int httpCode; + /** + * Sends encryption and authentication keys to the bank. + * This order is only allowed for a new user at the bank side that has been created by copying the A005 key. + * The keys will be activated immediately after successful completion of the transfer. + * + * @throws IOException communication error + * @throws GeneralSecurityException data decryption error + * @throws EbicsException server generated error message + */ + public void sendHPB() throws IOException, GeneralSecurityException, EbicsException { + HttpRequestSender sender = new HttpRequestSender(session); + HPBRequestElement request = new HPBRequestElement(session); + request.build(); + request.validate(); + session.getConfiguration().getTraceManager().trace(request); + int httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); + var body = sender.getResponseBody(); + Utils.checkHttpCode(httpCode); + KeyManagementResponseElement response = new KeyManagementResponseElement(body, + "HBPResponse"); + response.build(); + session.getConfiguration().getTraceManager().trace(response); + response.report(); + EbicsUser user = session.getUser(); + ContentFactory factory = new ByteArrayContentFactory( + Utils.unzip(user.decrypt(response.getOrderData(), response.getTransactionKey()))); + HPBResponseOrderDataElement orderData = new HPBResponseOrderDataElement(factory); + orderData.build(); + session.getConfiguration().getTraceManager().trace(orderData); + KeyStoreManager keystoreManager = new KeyStoreManager(); + var path = session.getConfiguration().getKeystoreDirectory(user); + keystoreManager.load(null, user.getPasswordCallback().getPassword()); + EbicsBank bank = user.getPartner().getBank(); + String bankID = session.getBankID(); + var e002PubKey = keystoreManager.getPublicKey( + new ByteArrayInputStream(orderData.getBankE002Certificate())); + var x002PubKey = keystoreManager.getPublicKey( + new ByteArrayInputStream(orderData.getBankX002Certificate())); + bank.setBankKeys(e002PubKey, x002PubKey); + bank.setDigests(KeyUtil.getKeyDigest(e002PubKey), KeyUtil.getKeyDigest(x002PubKey)); + keystoreManager.setCertificateEntry(bankID + "-E002", + new ByteArrayInputStream(orderData.getBankE002Certificate())); + keystoreManager.setCertificateEntry(bankID + "-X002", + new ByteArrayInputStream(orderData.getBankX002Certificate())); + keystoreManager.save(new FileOutputStream(new File(path, bankID + ".p12"))); + } - sender = new HttpRequestSender(session); - request = new SPRRequestElement(session); - request.build(); - request.validate(); - session.getConfiguration().getTraceManager().trace(request); - httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); - Utils.checkHttpCode(httpCode); - response = new SPRResponseElement(sender.getResponseBody()); - response.build(); - session.getConfiguration().getTraceManager().trace(response); - response.report(); - } + /** + * Sends the SPR order to the bank. + * After that you have to start over with sending INI and HIA. + * + * @throws IOException Communication exception + * @throws EbicsException Error message generated by the bank. + */ + public void lockAccess() throws IOException, EbicsException { + HttpRequestSender sender; + SPRRequestElement request; + SPRResponseElement response; + int httpCode; + + sender = new HttpRequestSender(session); + request = new SPRRequestElement(session); + request.build(); + request.validate(); + session.getConfiguration().getTraceManager().trace(request); + httpCode = sender.send(new ByteArrayContentFactory(request.prettyPrint())); + Utils.checkHttpCode(httpCode); + response = new SPRResponseElement(sender.getResponseBody()); + response.build(); + session.getConfiguration().getTraceManager().trace(response); + response.report(); + } - // -------------------------------------------------------------------- - // DATA MEMBERS - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- + // DATA MEMBERS + // -------------------------------------------------------------------- - private EbicsSession session; + private final EbicsSession session; } diff --git a/src/main/java/org/kopi/ebics/client/ParameterizedEbicsClientLauncher.java b/src/main/java/org/kopi/ebics/client/ParameterizedEbicsClientLauncher.java new file mode 100644 index 00000000..08d6918d --- /dev/null +++ b/src/main/java/org/kopi/ebics/client/ParameterizedEbicsClientLauncher.java @@ -0,0 +1,552 @@ +/* + * Copyright (c) 1990-2012 kopiLeft Development SARL, Bizerte, Tunisia + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package org.kopi.ebics.client; + +import java.io.File; +import java.net.URL; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeParseException; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.kopi.ebics.interfaces.EbicsBank; +import org.kopi.ebics.interfaces.EbicsOrderType; +import org.kopi.ebics.interfaces.EbicsPartner; +import org.kopi.ebics.interfaces.PasswordCallback; +import org.kopi.ebics.session.DefaultConfiguration; +import org.kopi.ebics.session.OrderType; +import org.kopi.ebics.session.Product; + +/** + * Parameter-based launcher that avoids relying on a persisted ebics.txt file in the workspace. + * It receives runtime parameters from environment variables. + */ +public final class ParameterizedEbicsClientLauncher { + private static final Set RESERVED_FLAGS = Set.of( + "--create", + "--ini", + "--hia", + "--hpb", + "--help", + "--btd" + ); + + /** + * EBICS 3.0 business transaction downloads always use the admin order type {@code BTD}; the + * business order is carried by the service parameters instead of the 3-letter code. + */ + private static final EbicsOrderType BTD_ORDER_TYPE = () -> "BTD"; + + private ParameterizedEbicsClientLauncher() { + } + + public static void main(String[] args) throws Exception { + ParsedArguments parsedArguments = ParsedArguments.parse(args); + if (parsedArguments.hasFlag("--help")) { + printUsage(); + return; + } + + // Every argument is checked before the first environment read, keystore access or bank + // call. INI is one-shot at most banks: aborting on a missing --container after the INI + // request has gone out would leave a half-initialised access behind. + validateArguments(parsedArguments); + + String passphrase = requiredEnv("EBICS_PASSWORD"); + String userId = requiredEnv("EBICS_USER_ID"); + String partnerId = requiredEnv("EBICS_PARTNER_ID"); + String hostId = requiredEnv("EBICS_HOST_ID"); + String bankUrl = requiredEnv("EBICS_BANK_URL"); + String languageCode = env("EBICS_LANGUAGE_CODE", "de"); + String countryCode = env("EBICS_COUNTRY_CODE", "DE").toUpperCase(Locale.ROOT); + + propagateOptionalSystemProperty( + "ebics.key.length", + normalize(System.getenv("EBICS_KEY_LENGTH")) + ); + propagateOptionalSystemProperty( + "ebics.cert.validity.years", + normalize(System.getenv("EBICS_CERT_VALIDITY_YEARS")) + ); + + Properties properties = buildConfigurationProperties(languageCode, countryCode); + File rootDirectory = rootDirectory(); + DefaultConfiguration configuration = createConfiguration( + rootDirectory, + properties, + languageCode, + countryCode + ); + EbicsClient client = new EbicsClient(configuration, null); + Product product = new Product( + env("EBICS_PRODUCT_NAME", "EBICS Java Client"), + languageCode, + null + ); + PasswordCallback passwordCallback = () -> passphrase.toCharArray(); + + User user; + if (parsedArguments.hasFlag("--create")) { + user = client.createUser( + new URL(bankUrl), + env("EBICS_BANK_NAME", hostId), + hostId, + partnerId, + userId, + env("EBICS_USER_NAME", userId), + env("EBICS_USER_EMAIL", userId + "@example.invalid"), + env("EBICS_USER_COUNTRY", countryCode), + env("EBICS_USER_ORGANIZATION", "EBICS"), + true, + passwordCallback + ); + } else { + user = client.loadUser(hostId, partnerId, userId, passwordCallback); + ensureLoadedUserMatchesConfiguredEndpoint(user, bankUrl, hostId); + } + + if (parsedArguments.hasFlag("--ini")) { + client.sendINIRequest(user, product); + } + if (parsedArguments.hasFlag("--hia")) { + client.sendHIARequest(user, product); + } + if (parsedArguments.hasFlag("--hpb")) { + client.sendHPBRequest(user, product); + } + + if (parsedArguments.hasFlag("--btd")) { + EbicsDownloadParams downloadParams = btdDownloadParams(parsedArguments); + client.fetchFile( + new File(requireOutputPath(parsedArguments)), + user, + product, + BTD_ORDER_TYPE, + downloadParams, + Boolean.parseBoolean(env("EBICS_TEST_MODE", "false")) + ); + client.quit(); + return; + } + + String orderFlag = parsedArguments.firstOrderFlag(); + if (orderFlag != null) { + OrderType orderType = OrderType.valueOf(orderFlag.substring(2).toUpperCase(Locale.ROOT)); + if (parsedArguments.inputPath() != null) { + client.sendFile( + new File(parsedArguments.inputPath()), + user, + product, + orderType, + defaultUploadParams(user, orderType) + ); + } else if (parsedArguments.outputPath() != null) { + client.fetchFile( + new File(parsedArguments.outputPath()), + user, + product, + orderType, + legacyDownloadParams(parsedArguments), + Boolean.parseBoolean(env("EBICS_TEST_MODE", "false")) + ); + } + } + + client.quit(); + } + + private static void printUsage() { + String usage = "Usage: ParameterizedEbicsClientLauncher [--create] [--ini] [--hia] [--hpb]" + + " [--] [-i inputFile] [-o outputFile] [-s start] [-e end]\n" + + "EBICS 3.0 download: --btd --service --scope --msg-name " + + " --msg-version --container " + + " [--option ] [-s YYYY-MM-DD] [-e YYYY-MM-DD] -o \n" + + " e.g. --btd --service EOP --scope CH --msg-name camt.053 --msg-version 08" + + " --container ZIP -o statement.zip\n" + + "Required environment variables: EBICS_PASSWORD, EBICS_USER_ID, EBICS_PARTNER_ID," + + " EBICS_HOST_ID, EBICS_BANK_URL"; + System.out.println(usage); + } + + /** + * Rejects every unusable argument combination before the program talks to anyone. Nothing here + * touches the network, the filesystem or the environment. + */ + static void validateArguments(ParsedArguments parsedArguments) { + if (parsedArguments.hasFlag("--btd")) { + btdDownloadParams(parsedArguments); + requireOutputPath(parsedArguments); + } else { + legacyDownloadParams(parsedArguments); + } + } + + /** + * Builds the EBICS 3.0 service parameters for {@code --btd}. Fails fast on a missing mandatory + * value, so a half-filled order is never sent to the bank. The date range pair itself is + * checked by {@link EbicsDownloadParams}, which covers every other caller too. + */ + static EbicsDownloadParams btdDownloadParams(ParsedArguments parsedArguments) { + return new EbicsDownloadParams( + upperCase(requireOption(parsedArguments.serviceName(), "--service")), + upperCase(requireOption(parsedArguments.scope(), "--scope")), + upperCase(parsedArguments.option()), + requireOption(parsedArguments.messageName(), "--msg-name"), + requireOption(parsedArguments.messageVersion(), "--msg-version"), + upperCase(requireOption(parsedArguments.containerType(), "--container")), + parseDate(parsedArguments.startDate(), "--start"), + parseDate(parsedArguments.endDate(), "--end") + ); + } + + /** + * Service code, scope, service option and container type are EBICS code list values and are + * always upper case. Message names like {@code camt.053} are not, and stay untouched. + */ + private static String upperCase(String value) { + return value == null ? null : value.toUpperCase(Locale.ROOT); + } + + /** + * Builds the date-range-only parameters of the legacy (EBICS 2.x) download path. + */ + static EbicsDownloadParams legacyDownloadParams(ParsedArguments parsedArguments) { + return EbicsDownloadParams.dateRangeOnly( + parseDate(parsedArguments.startDate(), "--start"), + parseDate(parsedArguments.endDate(), "--end") + ); + } + + static String requireOutputPath(ParsedArguments parsedArguments) { + return requireOption(parsedArguments.outputPath(), "-o"); + } + + private static String requireOption(String value, String option) { + String normalized = normalize(value); + if (normalized == null) { + throw new IllegalArgumentException("Missing required option " + option + " for --btd"); + } + return normalized; + } + + /** + * Parses a {@code YYYY-MM-DD} argument into a calendar day. No timezone is involved, so the + * day the user typed is the day that reaches the bank, wherever the job runs. + */ + private static LocalDate parseDate(String value, String option) { + String normalized = normalize(value); + if (normalized == null) { + return null; + } + try { + return LocalDate.parse(normalized); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException( + "Option " + option + " expects a date as YYYY-MM-DD but was: " + normalized); + } + } + + private static EbicsUploadParams defaultUploadParams(User user, OrderType orderType) { + if (orderType == OrderType.XE2) { + var orderParams = new EbicsUploadParams.OrderParams( + "MCT", + "CH", + null, + "pain.001", + "03", + true + ); + return new EbicsUploadParams(null, orderParams); + } + return new EbicsUploadParams(user.getPartner().nextOrderId(), null); + } + + private static File rootDirectory() { + String explicit = normalize(System.getenv("EBICS_ROOT_DIR")); + if (explicit != null) { + return new File(explicit); + } + String userHome = System.getProperty("user.home"); + if (userHome == null || userHome.isBlank()) { + throw new IllegalStateException("Missing user.home for EBICS workspace resolution."); + } + return new File(new File(userHome), "ebics/client"); + } + + private static DefaultConfiguration createConfiguration( + File rootDirectory, + Properties properties, + String languageCode, + String countryCode + ) { + Locale locale = new Locale( + languageCode.toLowerCase(Locale.ROOT), + countryCode.toUpperCase(Locale.ROOT) + ); + return new DefaultConfiguration(rootDirectory, properties) { + @Override + public Locale getLocale() { + return locale; + } + }; + } + + private static Properties buildConfigurationProperties( + String languageCode, + String countryCode + ) { + Properties properties = new Properties(); + properties.setProperty("conf.file.name", "ebics.properties"); + properties.setProperty("keystore.dir.name", "keystore"); + properties.setProperty("traces.dir.name", "traces"); + properties.setProperty("serialization.dir.name", "serialized"); + properties.setProperty("ssltruststore.dir.name", "ssl"); + properties.setProperty("sslkeystore.dir.name", "ssl"); + properties.setProperty("sslbankcert.dir.name", "ssl"); + properties.setProperty("users.dir.name", "users"); + properties.setProperty("letters.dir.name", "letters"); + properties.setProperty("signature.version", env("EBICS_SIGNATURE_VERSION", "A005")); + properties.setProperty("authentication.version", env("EBICS_AUTHENTICATION_VERSION", "X002")); + properties.setProperty("encryption.version", env("EBICS_ENCRYPTION_VERSION", "E002")); + properties.setProperty("ebics.version", env("EBICS_VERSION", "H003")); + properties.setProperty("languageCode", languageCode); + properties.setProperty("countryCode", countryCode); + return properties; + } + + private static void ensureLoadedUserMatchesConfiguredEndpoint( + User user, + String configuredBankUrl, + String configuredHostId + ) { + if (user == null) { + return; + } + + EbicsPartner partner = user.getPartner(); + EbicsBank bank = partner == null ? null : partner.getBank(); + if (bank == null) { + return; + } + + String expectedUrl = normalize(configuredBankUrl); + String loadedUrl = bank.getURL() == null ? null : normalize(bank.getURL().toString()); + if (expectedUrl != null && !expectedUrl.equals(loadedUrl)) { + throw new IllegalStateException( + "Loaded user endpoint does not match configured EBICS_BANK_URL. " + + "Run with --create or clean serialized state." + ); + } + + String expectedHostId = normalize(configuredHostId); + String loadedHostId = normalize(bank.getHostId()); + if ( + expectedHostId != null && + loadedHostId != null && + !expectedHostId.equals(loadedHostId) + ) { + throw new IllegalStateException( + "Loaded user host id does not match configured EBICS_HOST_ID. " + + "Run with --create or clean serialized state." + ); + } + } + + private static void propagateOptionalSystemProperty(String key, String value) { + if (value != null) { + System.setProperty(key, value); + } + } + + private static String requiredEnv(String key) { + String value = normalize(System.getenv(key)); + if (value == null) { + throw new IllegalArgumentException("Missing required environment variable: " + key); + } + return value; + } + + private static String env(String key, String fallback) { + String value = normalize(System.getenv(key)); + return value == null ? fallback : value; + } + + static String normalize(String value) { + if (value == null) { + return null; + } + String trimmed = value.trim(); + return trimmed.isEmpty() ? null : trimmed; + } + + static final class ParsedArguments { + private final Set flags = new LinkedHashSet<>(); + private final Map values; + private final String inputPath; + private final String outputPath; + private final String startDate; + private final String endDate; + + private ParsedArguments( + Set flags, + Map values, + String inputPath, + String outputPath, + String startDate, + String endDate + ) { + this.flags.addAll(flags); + this.values = Map.copyOf(values); + this.inputPath = inputPath; + this.outputPath = outputPath; + this.startDate = startDate; + this.endDate = endDate; + } + + /** Value options of the EBICS 3.0 service block; each consumes the following argument. */ + private static final Set VALUE_OPTIONS = Set.of( + "--service", + "--scope", + "--option", + "--msg-name", + "--msg-version", + "--container" + ); + + static ParsedArguments parse(String[] args) { + Set flags = new LinkedHashSet<>(); + Map values = new LinkedHashMap<>(); + String inputPath = null; + String outputPath = null; + String startDate = null; + String endDate = null; + if (args != null) { + for (int index = 0; index < args.length; index++) { + String arg = args[index]; + if (arg == null || arg.isBlank()) { + continue; + } + if ("-i".equals(arg) || "--input".equals(arg)) { + inputPath = requireValue(args, ++index, arg); + continue; + } + if ("-o".equals(arg) || "--output".equals(arg)) { + outputPath = requireValue(args, ++index, arg); + continue; + } + if ("-s".equals(arg) || "--start".equals(arg)) { + startDate = requireValue(args, ++index, arg); + continue; + } + if ("-e".equals(arg) || "--end".equals(arg)) { + endDate = requireValue(args, ++index, arg); + continue; + } + String lowered = arg.toLowerCase(Locale.ROOT); + if (VALUE_OPTIONS.contains(lowered)) { + values.put(lowered, requireValue(args, ++index, arg)); + continue; + } + if (arg.startsWith("--")) { + flags.add(lowered); + } + } + } + return new ParsedArguments(flags, values, inputPath, outputPath, startDate, endDate); + } + + private static String requireValue(String[] args, int index, String option) { + if (args == null || index >= args.length) { + throw new IllegalArgumentException("Missing value for option " + option); + } + String value = normalize(args[index]); + if (value == null) { + throw new IllegalArgumentException("Missing value for option " + option); + } + return value; + } + + boolean hasFlag(String flag) { + return flags.contains(flag.toLowerCase(Locale.ROOT)); + } + + String firstOrderFlag() { + for (String flag : flags) { + if (RESERVED_FLAGS.contains(flag)) { + continue; + } + String candidate = flag.startsWith("--") + ? flag.substring(2).toUpperCase(Locale.ROOT) + : flag.toUpperCase(Locale.ROOT); + try { + OrderType.valueOf(candidate); + return flag; + } catch (IllegalArgumentException ignored) { + // ignore unknown flags that are not EBICS order types + } + } + return null; + } + + String inputPath() { + return inputPath; + } + + String outputPath() { + return outputPath; + } + + String startDate() { + return startDate; + } + + String endDate() { + return endDate; + } + + String serviceName() { + return values.get("--service"); + } + + String scope() { + return values.get("--scope"); + } + + String option() { + return values.get("--option"); + } + + String messageName() { + return values.get("--msg-name"); + } + + String messageVersion() { + return values.get("--msg-version"); + } + + String containerType() { + return values.get("--container"); + } + } +} diff --git a/src/main/java/org/kopi/ebics/client/Partner.java b/src/main/java/org/kopi/ebics/client/Partner.java index 5f39589f..d54403ca 100644 --- a/src/main/java/org/kopi/ebics/client/Partner.java +++ b/src/main/java/org/kopi/ebics/client/Partner.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; @@ -33,7 +32,6 @@ * This object is not serializable, but it should be persisted every time it needs to be saved. * Persistence is achieved via save(ObjectOutputStream) and the matching constructor. * - * @author Hachani * */ public class Partner implements EbicsPartner, Savable { @@ -66,7 +64,7 @@ public Partner(EbicsBank bank, String partnerId) { * @return the next order ID */ public Integer getNextOrderId() { - return new Integer(orderId); + return Integer.valueOf(orderId); } /** @@ -144,9 +142,9 @@ public String getSaveName() { // DATA MEMBERS // -------------------------------------------------------------------- - private EbicsBank bank; + private final EbicsBank bank; private int orderId = 10*36*36*36; - private String partnerId; + private final String partnerId; private transient boolean needSave; private static final String ALPHA_NUM_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/src/main/java/org/kopi/ebics/client/TransferState.java b/src/main/java/org/kopi/ebics/client/TransferState.java index 185be23d..3fa8bd7f 100644 --- a/src/main/java/org/kopi/ebics/client/TransferState.java +++ b/src/main/java/org/kopi/ebics/client/TransferState.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; @@ -27,7 +26,6 @@ * FileTransfer.nextChunk(TransferState) * in this or a future session. * - * @author Hachani * */ public class TransferState implements Serializable { @@ -42,7 +40,7 @@ public TransferState(int numSegments, byte[] transactionId) { * @return the next segment number to be transferred. */ public int next() { - segmentNumber ++; + segmentNumber++; if (segmentNumber == numSegments) { lastSegment = true; @@ -79,7 +77,7 @@ public byte[] getTransactionId() { } /** - * @param transactionID the transactionID to set + * @param transactionId the transactionID to set */ public void setTransactionId(byte[] transactionId) { this.transactionId = transactionId; diff --git a/src/main/java/org/kopi/ebics/client/User.java b/src/main/java/org/kopi/ebics/client/User.java index 6ca53cc6..e1a37186 100644 --- a/src/main/java/org/kopi/ebics/client/User.java +++ b/src/main/java/org/kopi/ebics/client/User.java @@ -14,12 +14,12 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.client; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -32,7 +32,6 @@ import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; -import javax.xml.crypto.dsig.SignedInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.kopi.ebics.certificate.CertificateManager; @@ -42,6 +41,7 @@ import org.kopi.ebics.interfaces.PasswordCallback; import org.kopi.ebics.interfaces.Savable; import org.kopi.ebics.utils.Utils; +import org.kopi.ebics.xml.SignedInfo; import org.kopi.ebics.xml.UserSignature; /** @@ -49,7 +49,6 @@ * This object is not serializable, but it should be persisted every time it needs to be saved. * Persistence is achieved via save(ObjectOutputStream) and the matching constructor. * - * @author Hachani * */ public class User implements EbicsUser, Savable { @@ -131,7 +130,7 @@ public User(EbicsPartner partner, public User(EbicsPartner partner, String userId, String name, - String keystorePath, + File keystorePath, PasswordCallback passwordCallback) throws GeneralSecurityException, IOException { @@ -155,17 +154,15 @@ private void createUserCertificates() throws GeneralSecurityException, IOExcepti } /** - * Saves the user certificates in a given path - * @param path the certificates path - * @throws GeneralSecurityException - * @throws IOException + * Saves the user certificates in a given directory + * */ - public void saveUserCertificates(String path) throws GeneralSecurityException, IOException { + public void saveUserCertificates(File directory) throws GeneralSecurityException, IOException { if (manager == null) { throw new GeneralSecurityException("Cannot save user certificates"); } - manager.save(path, passwordCallback); + manager.save(directory, passwordCallback); } /** @@ -174,7 +171,7 @@ public void saveUserCertificates(String path) throws GeneralSecurityException, I * @throws GeneralSecurityException * @throws IOException */ - private void loadCertificates(String keyStorePath) + private void loadCertificates(File keyStorePath) throws GeneralSecurityException, IOException { manager = new CertificateManager(this); @@ -283,29 +280,25 @@ public static byte[] removeOSSpecificChars(byte[] buf) { * @param email the user email * @param country the user country * @param organization the user organization - * @return + * @return Distinguished Names */ private String makeDN(String name, String email, String country, String organization) { - StringBuffer buffer; - - buffer = new StringBuffer(); - - buffer.append("CN=" + name); + StringBuilder sb = new StringBuilder(); + sb.append("CN=").append(name); if (country != null) { - buffer.append(", " + "C=" + country.toUpperCase()); + sb.append(", " + "C=").append(country.toUpperCase()); } if (organization != null) { - buffer.append(", " + "O=" + organization); + sb.append(", " + "O=").append(organization); } if (email != null) { - buffer.append(", " + "E=" + email); + sb.append(", " + "E=").append(email); } - - return buffer.toString(); + return sb.toString(); } /** @@ -517,7 +510,7 @@ public byte[] authenticate(byte[] digest) throws GeneralSecurityException { * will be sent to the EBICS server. */ @Override - public byte[] sign(byte[] digest) throws IOException, GeneralSecurityException { + public byte[] sign(byte[] digest) throws GeneralSecurityException { Signature signature = Signature.getInstance("SHA256WithRSA", BouncyCastleProvider.PROVIDER_NAME); signature.initSign(a005PrivateKey); signature.update(removeOSSpecificChars(digest)); @@ -585,13 +578,13 @@ private byte[] decryptData(byte[] input, byte[] key) // DATA MEMBERS // -------------------------------------------------------------------- - private EbicsPartner partner; - private String userId; - private String name; - private String dn; + private final EbicsPartner partner; + private final String userId; + private final String name; + private final String dn; private boolean isInitializedHIA; private boolean isInitialized; - private PasswordCallback passwordCallback; + private final PasswordCallback passwordCallback; private transient boolean needSave; private CertificateManager manager; diff --git a/src/main/java/org/kopi/ebics/exception/EbicsException.java b/src/main/java/org/kopi/ebics/exception/EbicsException.java index f2d13e8e..22839d8e 100644 --- a/src/main/java/org/kopi/ebics/exception/EbicsException.java +++ b/src/main/java/org/kopi/ebics/exception/EbicsException.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.exception; @@ -22,7 +21,6 @@ /** * Common exception for all EBICS errors. * - * @author hachani * */ public class EbicsException extends Exception { @@ -30,7 +28,9 @@ public class EbicsException extends Exception { /** * A means to construct a server error. */ - public EbicsException() {} + public EbicsException(Throwable cause) { + super(cause); + } /** * A means to construct a server error with an additional message. @@ -39,11 +39,16 @@ public EbicsException() {} public EbicsException(String message) { super(message); } + + public EbicsException(String message, Throwable cause) { + super(message, cause); + } /** * A means to construct a server error with no additional message. * @param returnCode the ebics return code. */ public EbicsException(ReturnCode returnCode) { + super(returnCode.getText()); this.returnCode = returnCode; } diff --git a/src/main/java/org/kopi/ebics/exception/NoDownloadDataAvailableException.java b/src/main/java/org/kopi/ebics/exception/NoDownloadDataAvailableException.java index 20e262cc..bf392594 100644 --- a/src/main/java/org/kopi/ebics/exception/NoDownloadDataAvailableException.java +++ b/src/main/java/org/kopi/ebics/exception/NoDownloadDataAvailableException.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.exception; @@ -22,20 +21,16 @@ /** * Download operation failed due to lack of data. * - * @author hachani * */ public class NoDownloadDataAvailableException extends EbicsException { + public NoDownloadDataAvailableException() { + super(ReturnCode.EBICS_NO_DOWNLOAD_DATA_AVAILABLE); + } + public NoDownloadDataAvailableException(String message) { + super(ReturnCode.EBICS_NO_DOWNLOAD_DATA_AVAILABLE, message); + } - @Override - public ReturnCode getReturnCode() { - return ReturnCode.EBICS_NO_DOWNLOAD_DATA_AVAILABLE; - } - - @Override - public String getMessage() { - return getReturnCode().getText(); - } // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- diff --git a/src/main/java/org/kopi/ebics/exception/ReturnCode.java b/src/main/java/org/kopi/ebics/exception/ReturnCode.java index c35e17a1..42604e1f 100644 --- a/src/main/java/org/kopi/ebics/exception/ReturnCode.java +++ b/src/main/java/org/kopi/ebics/exception/ReturnCode.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.exception; @@ -22,20 +21,21 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import java.util.MissingResourceException; import org.kopi.ebics.messages.Messages; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Representation of EBICS return codes. * The return codes are described in chapter 13 * of EBICS specification. * - * @author hachani * */ public class ReturnCode implements Serializable { - + private static final Logger log = LoggerFactory.getLogger(ReturnCode.class); /** * Constructs a new ReturnCode with a given * standard code, symbolic name and text @@ -100,6 +100,7 @@ public static ReturnCode toReturnCode(String code, String text) { if (returnCode != null) { return returnCode; } + log.warn("Unknown return code: {}, text: {}", code, text); return new ReturnCode(code, text, text); } @@ -129,76 +130,53 @@ public String toString() { private final String code; private final String symbolicName; private final String text; - public static final ReturnCode EBICS_OK; - public static final ReturnCode EBICS_DOWNLOAD_POSTPROCESS_DONE; - public static final ReturnCode EBICS_DOWNLOAD_POSTPROCESS_SKIPPED; - public static final ReturnCode EBICS_TX_SEGMENT_NUMBER_UNDERRUN; - public static final ReturnCode EBICS_AUTHENTICATION_FAILED; - public static final ReturnCode EBICS_INVALID_REQUEST; - public static final ReturnCode EBICS_INTERNAL_ERROR; - public static final ReturnCode EBICS_TX_RECOVERY_SYNC; - public static final ReturnCode EBICS_INVALID_USER_OR_USER_STATE; - public static final ReturnCode EBICS_USER_UNKNOWN; - public static final ReturnCode EBICS_INVALID_USER_STATE; - public static final ReturnCode EBICS_INVALID_ORDER_TYPE; - public static final ReturnCode EBICS_UNSUPPORTED_ORDER_TYPE; - public static final ReturnCode EBICS_USER_AUTHENTICATION_REQUIRED; - public static final ReturnCode EBICS_BANK_PUBKEY_UPDATE_REQUIRED; - public static final ReturnCode EBICS_SEGMENT_SIZE_EXCEEDED; - public static final ReturnCode EBICS_TX_UNKNOWN_TXID; - public static final ReturnCode EBICS_TX_ABORT; - public static final ReturnCode EBICS_TX_MESSAGE_REPLAY; - public static final ReturnCode EBICS_TX_SEGMENT_NUMBER_EXCEEDED; - public static final ReturnCode EBICS_X509_CERTIFICATE_NOT_VALID_YET; - public static final ReturnCode EBICS_MAX_TRANSACTIONS_EXCEEDED; - public static final ReturnCode EBICS_SIGNATURE_VERIFICATION_FAILED; - public static final ReturnCode EBICS_NO_DOWNLOAD_DATA_AVAILABLE; - public static final ReturnCode EBICS_ORDERID_ALREADY_EXISTS; - private static final String BUNDLE_NAME = "org.kopi.ebics.exception.messages"; - private static final long serialVersionUID = -497883146384363199L; private static final Map returnCodes = new HashMap<>(); + private static final String BUNDLE_NAME = "org.kopi.ebics.exception.messages"; private static final Messages messages = new Messages(BUNDLE_NAME); - static { - EBICS_OK = create("000000", "EBICS_OK"); - EBICS_DOWNLOAD_POSTPROCESS_DONE = create("011000", "EBICS_DOWNLOAD_POSTPROCESS_DONE"); - EBICS_DOWNLOAD_POSTPROCESS_SKIPPED = create("011001", "EBICS_DOWNLOAD_POSTPROCESS_SKIPPED"); - EBICS_TX_SEGMENT_NUMBER_UNDERRUN = create("011101", "EBICS_TX_SEGMENT_NUMBER_UNDERRUN"); - EBICS_AUTHENTICATION_FAILED = create("061001", "EBICS_AUTHENTICATION_FAILED"); - EBICS_INVALID_REQUEST = create("061002", "EBICS_INVALID_REQUEST"); - EBICS_INTERNAL_ERROR = create("061099", "EBICS_INTERNAL_ERROR"); - EBICS_TX_RECOVERY_SYNC = create("061101", "EBICS_TX_RECOVERY_SYNC"); - - EBICS_NO_DOWNLOAD_DATA_AVAILABLE = create("090005", "EBICS_NO_DOWNLOAD_DATA_AVAILABLE"); - EBICS_INVALID_USER_OR_USER_STATE = create("091002", "EBICS_INVALID_USER_OR_USER_STATE"); - EBICS_USER_UNKNOWN = create("091003", "EBICS_USER_UNKNOWN"); - EBICS_INVALID_USER_STATE = create("091004", "EBICS_INVALID_USER_STATE"); - EBICS_INVALID_ORDER_TYPE = create("091005", "EBICS_INVALID_ORDER_TYPE"); - EBICS_UNSUPPORTED_ORDER_TYPE = create("091006", "EBICS_UNSUPPORTED_ORDER_TYPE"); - EBICS_USER_AUTHENTICATION_REQUIRED = create("091007", "EBICS_USER_AUTHENTICATION_REQUIRED"); - EBICS_BANK_PUBKEY_UPDATE_REQUIRED = create("091008", "EBICS_BANK_PUBKEY_UPDATE_REQUIRED"); - EBICS_SEGMENT_SIZE_EXCEEDED = create("091009", "EBICS_SEGMENT_SIZE_EXCEEDED"); - EBICS_TX_UNKNOWN_TXID = create("091101", "EBICS_TX_UNKNOWN_TXID"); - EBICS_TX_ABORT = create("091102", "EBICS_TX_ABORT"); - EBICS_TX_MESSAGE_REPLAY = create("091103", "EBICS_TX_MESSAGE_REPLAY"); - EBICS_TX_SEGMENT_NUMBER_EXCEEDED = create("091104", "EBICS_TX_SEGMENT_NUMBER_EXCEEDED"); - EBICS_ORDERID_ALREADY_EXISTS = create("091115", "EBICS_ORDERID_ALREADY_EXISTS"); - EBICS_MAX_TRANSACTIONS_EXCEEDED = create("091119", "EBICS_MAX_TRANSACTIONS_EXCEEDED"); - EBICS_X509_CERTIFICATE_NOT_VALID_YET = create("091209", "EBICS_X509_CERTIFICATE_NOT_VALID_YET"); - EBICS_SIGNATURE_VERIFICATION_FAILED = create("091301", "EBICS_SIGNATURE_VERIFICATION_FAILED"); - } + public static final ReturnCode EBICS_OK = create("000000", "EBICS_OK"); + public static final ReturnCode EBICS_DOWNLOAD_POSTPROCESS_DONE = create("011000", "EBICS_DOWNLOAD_POSTPROCESS_DONE"); + public static final ReturnCode EBICS_DOWNLOAD_POSTPROCESS_SKIPPED = create("011001", "EBICS_DOWNLOAD_POSTPROCESS_SKIPPED"); + public static final ReturnCode EBICS_TX_SEGMENT_NUMBER_UNDERRUN = create("011101", "EBICS_TX_SEGMENT_NUMBER_UNDERRUN"); + public static final ReturnCode EBICS_AUTHENTICATION_FAILED = create("061001", "EBICS_AUTHENTICATION_FAILED"); + public static final ReturnCode EBICS_INVALID_REQUEST = create("061002", "EBICS_INVALID_REQUEST"); + public static final ReturnCode EBICS_INTERNAL_ERROR = create("061099", "EBICS_INTERNAL_ERROR"); + public static final ReturnCode EBICS_TX_RECOVERY_SYNC = create("061101", "EBICS_TX_RECOVERY_SYNC"); + public static final ReturnCode EBICS_INVALID_USER_OR_USER_STATE = create("091002", "EBICS_INVALID_USER_OR_USER_STATE"); + public static final ReturnCode EBICS_USER_UNKNOWN = create("091003", "EBICS_USER_UNKNOWN"); + public static final ReturnCode EBICS_INVALID_USER_STATE = create("091004", "EBICS_INVALID_USER_STATE"); + public static final ReturnCode EBICS_INVALID_ORDER_TYPE = create("091005", "EBICS_INVALID_ORDER_TYPE"); + public static final ReturnCode EBICS_UNSUPPORTED_ORDER_TYPE = create("091006", "EBICS_UNSUPPORTED_ORDER_TYPE"); + public static final ReturnCode EBICS_USER_AUTHENTICATION_REQUIRED = create("091007", "EBICS_USER_AUTHENTICATION_REQUIRED"); + public static final ReturnCode EBICS_BANK_PUBKEY_UPDATE_REQUIRED = create("091008", "EBICS_BANK_PUBKEY_UPDATE_REQUIRED"); + public static final ReturnCode EBICS_SEGMENT_SIZE_EXCEEDED = create("091009", "EBICS_SEGMENT_SIZE_EXCEEDED"); + public static final ReturnCode EBICS_TX_UNKNOWN_TXID = create("091101", "EBICS_TX_UNKNOWN_TXID"); + public static final ReturnCode EBICS_TX_ABORT = create("091102", "EBICS_TX_ABORT"); + public static final ReturnCode EBICS_TX_MESSAGE_REPLAY = create("091103", "EBICS_TX_MESSAGE_REPLAY"); + public static final ReturnCode EBICS_TX_SEGMENT_NUMBER_EXCEEDED = create("091104", "EBICS_TX_SEGMENT_NUMBER_EXCEEDED"); + public static final ReturnCode EBICS_X509_CERTIFICATE_NOT_VALID_YET = create("091209", "EBICS_X509_CERTIFICATE_NOT_VALID_YET"); + public static final ReturnCode EBICS_MAX_TRANSACTIONS_EXCEEDED = create("091119", "EBICS_MAX_TRANSACTIONS_EXCEEDED"); + public static final ReturnCode EBICS_SIGNATURE_VERIFICATION_FAILED = create("091301", "EBICS_SIGNATURE_VERIFICATION_FAILED"); + public static final ReturnCode EBICS_INVALID_ORDER_DATA_FORMAT = create("090004", "EBICS_INVALID_ORDER_DATA_FORMAT"); + public static final ReturnCode EBICS_NO_DOWNLOAD_DATA_AVAILABLE = create("090005", "EBICS_NO_DOWNLOAD_DATA_AVAILABLE"); + public static final ReturnCode EBICS_ORDERID_ALREADY_EXISTS = create("091115", "EBICS_ORDERID_ALREADY_EXISTS"); + public static final ReturnCode EBICS_AUTHORISATION_ORDER_TYPE_FAILED = create("090003", "EBICS_AUTHORISATION_ORDER_TYPE_FAILED"); + private static final long serialVersionUID = -497883146384363199L; - private static ReturnCode create(String code, String symbolicName) { - String text = messages.getString(code); - if (text == null) { - throw new NullPointerException("No text for code: " + code); - } - ReturnCode returnCode = new ReturnCode(code, symbolicName, text); - ReturnCode prev = returnCodes.put(code, returnCode); - if (prev != null) { - throw new IllegalStateException("Duplicated code: " + code); + + private static ReturnCode create(String code, String symbolicName) { + String text; + try { + text = messages.getString(code); + } catch (MissingResourceException e) { + text = symbolicName; + } + ReturnCode returnCode = new ReturnCode(code, symbolicName, text); + ReturnCode prev = returnCodes.put(code, returnCode); + if (prev != null) { + throw new IllegalStateException("Duplicated code: " + code); + } + return returnCode; } - return returnCode; - } } diff --git a/src/main/java/org/kopi/ebics/interfaces/Configuration.java b/src/main/java/org/kopi/ebics/interfaces/Configuration.java index 2c2698f3..b0ea90a2 100644 --- a/src/main/java/org/kopi/ebics/interfaces/Configuration.java +++ b/src/main/java/org/kopi/ebics/interfaces/Configuration.java @@ -14,18 +14,17 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; +import java.io.File; import java.util.Locale; /** * EBICS client application configuration. * - * @author hachani * */ public interface Configuration { @@ -34,25 +33,13 @@ public interface Configuration { * Returns the root directory of the client application. * @return the root directory of the client application. */ - public String getRootDirectory(); - - /** - * Returns the default log directory of the application. - * @return the default log directory - */ - public String getLogDirectory(); - - /** - * Returns the default log file name of the application - * @return the default log file name - */ - public String getLogFileName(); + File getRootDirectory(); /** * Returns the EBICS configuration file. * @return the EBICS configuration file. */ - public String getConfigurationFile(); + File getConfigurationFile(); /** * Returns the property value of a given key from @@ -60,15 +47,15 @@ public interface Configuration { * @param key the given key * @return the property value */ - public String getProperty(String key); + String getProperty(String key); /** * Returns the directory path of the key store that contains * bank and user certificates. - * @param the ebics user. + * @param user the ebics user. * @return the key store directory of a given user. */ - public String getKeystoreDirectory(EbicsUser user); + File getKeystoreDirectory(EbicsUser user); /** * Returns the directory path that contains the traces @@ -76,104 +63,97 @@ public interface Configuration { * @param user the ebics user * @return the transfer trace directory */ - public String getTransferTraceDirectory(EbicsUser user); + File getTransferTraceDirectory(EbicsUser user); /** * Returns the object serialization directory. - * @param user the ebics user * @return the object serialization directory. */ - public String getSerializationDirectory(); + File getSerializationDirectory(); /** * Returns the SSL trusted store directory. * @return the SSL trusted store directory. */ - public String getSSLTrustedStoreDirectory(); + File getSSLTrustedStoreDirectory(); /** * Return the SSL key store directory * @return the SSL key store directory */ - public String getSSLKeyStoreDirectory(); + File getSSLKeyStoreDirectory(); /** * Returns the SSL bank server certificates. * @return the SSL bank server certificates. */ - public String getSSLBankCertificates(); + File getSSLBankCertificates(); /** * Returns the users directory. * @return the users directory. */ - public String getUsersDirectory(); + File getUsersDirectory(); /** * Returns the Ebics client serialization manager. * @return the Ebics client serialization manager. */ - public SerializationManager getSerializationManager(); + SerializationManager getSerializationManager(); /** * Returns the Ebics client trace manager. * @return the Ebics client trace manager. */ - public TraceManager getTraceManager(); + TraceManager getTraceManager(); /** * Returns the letter manager. * @return the letter manager. */ - public LetterManager getLetterManager(); + LetterManager getLetterManager(); /** * Returns the initializations letters directory. * @return the initializations letters directory. */ - public String getLettersDirectory(EbicsUser user); + File getLettersDirectory(EbicsUser user); /** * Returns the users directory. * @return the users directory. */ - public String getUserDirectory(EbicsUser user); - - /** - * Returns the client application logger. - * @return the client application logger. - */ - public EbicsLogger getLogger(); + File getUserDirectory(EbicsUser user); /** * Configuration initialization. * Creates the necessary directories for the ebics configuration. */ - public void init(); + void init(); /** * Returns the application locale. * @return the application locale. */ - public Locale getLocale(); + Locale getLocale(); /** * Returns the client application signature version * @return the signature version */ - public String getSignatureVersion(); + String getSignatureVersion(); /** * Returns the client application authentication version * @return the authentication version */ - public String getAuthenticationVersion(); + String getAuthenticationVersion(); /** * Returns the client application encryption version * @return the encryption version */ - public String getEncryptionVersion(); + String getEncryptionVersion(); /** * Tells if the client application should keep XML transfer @@ -181,7 +161,7 @@ public interface Configuration { * @return True if the client application should not delete * the XML transfer files */ - public boolean isTraceEnabled(); + boolean isTraceEnabled(); /** * Returns if the files to be transferred should be @@ -191,17 +171,17 @@ public interface Configuration { * * @return true if the file compression is enabled */ - public boolean isCompressionEnabled(); + boolean isCompressionEnabled(); /** * Returns the default revision of sent XML. * @return the default revision of sent XML. */ - public int getRevision(); + int getRevision(); /** * Returns the version of the EBICS protocol used by the client. * @return the version of the EBICS protocol. */ - public String getVersion(); + String getVersion(); } diff --git a/src/main/java/org/kopi/ebics/interfaces/ContentFactory.java b/src/main/java/org/kopi/ebics/interfaces/ContentFactory.java index e8e2e53d..2ef467b2 100644 --- a/src/main/java/org/kopi/ebics/interfaces/ContentFactory.java +++ b/src/main/java/org/kopi/ebics/interfaces/ContentFactory.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -29,9 +28,9 @@ public interface ContentFactory extends Serializable { * Returns a new data source of the data to be sent. * The instance must ensure that the returned stream will * deliver the identical data during the lifetime of this instance. - * Nevertheless how often the method will be called. + * Nevertheless, how often the method will be called. * @return a new data source of the data to be sent. * @throws IOException */ - public InputStream getContent() throws IOException; + InputStream getContent() throws IOException; } diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsBank.java b/src/main/java/org/kopi/ebics/interfaces/EbicsBank.java index 638f47ae..b35b2a38 100644 --- a/src/main/java/org/kopi/ebics/interfaces/EbicsBank.java +++ b/src/main/java/org/kopi/ebics/interfaces/EbicsBank.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -26,7 +25,6 @@ /** * Details about EBICS communication with a given bank. * - * @author Hachani * */ public interface EbicsBank extends Serializable { @@ -35,55 +33,45 @@ public interface EbicsBank extends Serializable { * Returns the URL needed for communication to the bank. * @return the URL needed for communication to the bank. */ - public URL getURL(); + URL getURL(); - /** - * - */ - public boolean useCertificate(); - - /** - * - */ - public void setUseCertificate(boolean useCertificate); - /** * Returns the encryption key digest you have obtained from the bank. * Ensure that nobody was able to modify the digest on its way from the bank to you. * @return the encryption key digest you have obtained from the bank. */ - public byte[] getE002Digest(); + byte[] getE002Digest(); /** * Returns the authentication key digest you have obtained from the bank. * Ensure that nobody was able to modify the digest on its way from the bank to you. * @return the authentication key digest you have obtained from the bank. */ - public byte[] getX002Digest(); + byte[] getX002Digest(); /** * Returns the banks encryption key. * @return the banks encryption key. */ - public RSAPublicKey getE002Key(); + RSAPublicKey getE002Key(); /** * Returns the banks authentication key. * @return the banks authentication key. */ - public RSAPublicKey getX002Key(); + RSAPublicKey getX002Key(); /** * Returns the bank's id. * @return the bank's id. */ - public String getHostId(); + String getHostId(); /** * Returns the bank's name. * @return the bank's name. */ - public String getName(); + String getName(); /** * Keys have been fetched from the bank. @@ -93,12 +81,12 @@ public interface EbicsBank extends Serializable { * @param e002Key the banks encryption key. * @param x002Key the banks authentication key. */ - public void setBankKeys(RSAPublicKey e002Key, RSAPublicKey x002Key); + void setBankKeys(RSAPublicKey e002Key, RSAPublicKey x002Key); /** * Sets the bank digests. * @param e002Digest encryption digest * @param x002Digest authentication digest */ - public void setDigests(byte[] e002Digest, byte[] x002Digest); + void setDigests(byte[] e002Digest, byte[] x002Digest); } diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsElement.java b/src/main/java/org/kopi/ebics/interfaces/EbicsElement.java index 47d9fde9..b47f7452 100644 --- a/src/main/java/org/kopi/ebics/interfaces/EbicsElement.java +++ b/src/main/java/org/kopi/ebics/interfaces/EbicsElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -31,19 +30,19 @@ public interface EbicsElement extends Serializable { * Returns the name of this EbicsElement * @return the name of the element */ - public String getName(); + String getName(); /** * Builds the EbicsElement XML fragment * @throws EbicsException */ - public void build() throws EbicsException; + void build() throws EbicsException; /** * Prints the EbicsElement into * the given stream. * @param stream the print stream */ - public void print(PrintStream stream); + void print(PrintStream stream); } diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsLogger.java b/src/main/java/org/kopi/ebics/interfaces/EbicsLogger.java deleted file mode 100644 index 456a15c3..00000000 --- a/src/main/java/org/kopi/ebics/interfaces/EbicsLogger.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 1990-2012 kopiLeft Development SARL, Bizerte, Tunisia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -package org.kopi.ebics.interfaces; - -import org.kopi.ebics.exception.ReturnCode; - -/** - * A mean to log all ebics client operations. The log process - * ensures four functions: - *

    - *
  1. info: inform the user about an operation
  2. - *
  3. warn: warn the user about a risk that may affect the transfer or the key activation process
  4. - *
  5. error: report an error to the user with its details and causes
  6. - *
  7. report: reports an EBICS return code to the user
  8. - *
- * - * @author hachani - * - */ -public interface EbicsLogger { - - /** - * Informs a given message to the client application user. - * @param message the message to be informed. - */ - public void info(String message); - - /** - * Warns a given message to the client application user. - * @param message the given message. - */ - public void warn(String message); - - /** - * Warns a given message and its causes to the client application user. - * @param message the given message. - * @param throwable message causes. - */ - public void warn(String message, Throwable throwable); - - /** - * Reports an error to the client application user. - * @param message the error message - */ - public void error(String message); - - /** - * Reports an error and its causes to the client application user. - * @param message the error message. - * @param throwable the error causes. - */ - public void error(String message, Throwable throwable); - - /** - * Reports an ebics return code to the client application user. - * @param returnCode the return code to report. - */ - public void report(ReturnCode returnCode); - - /** - * Sets the logger log file - * @param logFile the log file - */ - public void setLogFile(String logFile); -} diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsOrderType.java b/src/main/java/org/kopi/ebics/interfaces/EbicsOrderType.java new file mode 100644 index 00000000..f5f0b411 --- /dev/null +++ b/src/main/java/org/kopi/ebics/interfaces/EbicsOrderType.java @@ -0,0 +1,7 @@ +package org.kopi.ebics.interfaces; + +public interface EbicsOrderType { + + String getCode(); + +} diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsPartner.java b/src/main/java/org/kopi/ebics/interfaces/EbicsPartner.java index 586ff1af..7621222b 100644 --- a/src/main/java/org/kopi/ebics/interfaces/EbicsPartner.java +++ b/src/main/java/org/kopi/ebics/interfaces/EbicsPartner.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -22,7 +21,6 @@ /** * Information about an EBICS customer. * - * @author Hachani * */ public interface EbicsPartner { @@ -31,17 +29,17 @@ public interface EbicsPartner { * Returns the bank we are customer of. * @return the bank we are customer of */ - public EbicsBank getBank(); + EbicsBank getBank(); /** * Returns the customers id at the bank. * @return the customers id at the bank. */ - public String getPartnerId(); + String getPartnerId(); /** * Creates the next order number. * @return the next order number. */ - public String nextOrderId(); + String nextOrderId(); } diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsRootElement.java b/src/main/java/org/kopi/ebics/interfaces/EbicsRootElement.java index 32bdfcb8..bd7183fe 100644 --- a/src/main/java/org/kopi/ebics/interfaces/EbicsRootElement.java +++ b/src/main/java/org/kopi/ebics/interfaces/EbicsRootElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -27,7 +26,6 @@ /** * An Ebics root element knows its name. * - * @author hachani * */ public interface EbicsRootElement extends EbicsElement { @@ -36,26 +34,26 @@ public interface EbicsRootElement extends EbicsElement { * Converts the EbicsElement to a byte array * @return the equivalent byte array of this EbicsElement */ - public byte[] toByteArray(); + byte[] toByteArray(); /** * Validates the request element according to the * EBICS XML schema specification * @throws EbicsException throws an EbicsException when validation fails */ - public void validate() throws EbicsException; + void validate() throws EbicsException; /** * Adds a namespace declaration for the EbicsRootElement * @param prefix namespace prefix * @param uri namespace uri */ - public void addNamespaceDecl(String prefix, String uri); + void addNamespaceDecl(String prefix, String uri); /** * Saves the EbicsElement into a given output stream. * @param out the output stream * @throws EbicsException the save operation fails */ - public void save(OutputStream out) throws EbicsException; + void save(OutputStream out) throws EbicsException; } diff --git a/src/main/java/org/kopi/ebics/interfaces/EbicsUser.java b/src/main/java/org/kopi/ebics/interfaces/EbicsUser.java index c18338ae..d6649fec 100644 --- a/src/main/java/org/kopi/ebics/interfaces/EbicsUser.java +++ b/src/main/java/org/kopi/ebics/interfaces/EbicsUser.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -31,7 +30,6 @@ /** * Things an EBICS user must be able to perform. * - * @author Hachani * */ public interface EbicsUser { @@ -40,112 +38,112 @@ public interface EbicsUser { * Returns the public part of the signature key. * @return the public part of the signature key. */ - public RSAPublicKey getA005PublicKey(); + RSAPublicKey getA005PublicKey(); /** * Returns the public part of the encryption key. * @return the public part of the encryption key. */ - public RSAPublicKey getE002PublicKey(); + RSAPublicKey getE002PublicKey(); /** * Return the public part of the transport authentication key. * @return the public part of the transport authentication key. */ - public RSAPublicKey getX002PublicKey(); + RSAPublicKey getX002PublicKey(); /** * Returns the signature certificate. * @return the encryption certificate. * @throws EbicsException */ - public byte[] getA005Certificate() throws EbicsException; + byte[] getA005Certificate() throws EbicsException; /** * Returns the authentication certificate. * @return the encryption certificate. * @throws EbicsException */ - public byte[] getX002Certificate() throws EbicsException; + byte[] getX002Certificate() throws EbicsException; /** * Returns the encryption certificate. * @return the encryption certificate. * @throws EbicsException */ - public byte[] getE002Certificate() throws EbicsException; + byte[] getE002Certificate() throws EbicsException; /** * Sets the signature certificate. * @param a005certificate the signature certificate. */ - public void setA005Certificate(X509Certificate a005certificate); + void setA005Certificate(X509Certificate a005certificate); /** * Sets the authentication certificate. - * @param a005certificate the authentication certificate. + * @param x002certificate the authentication certificate. */ - public void setX002Certificate(X509Certificate x002certificate); + void setX002Certificate(X509Certificate x002certificate); /** * Sets the encryption certificate. - * @param a005certificate the encryption certificate. + * @param e002certificate the encryption certificate. */ - public void setE002Certificate(X509Certificate e002certificate); + void setE002Certificate(X509Certificate e002certificate); /** * Sets the signature private key * @param a005Key the signature private key */ - public void setA005PrivateKey(PrivateKey a005Key); + void setA005PrivateKey(PrivateKey a005Key); /** * Sets the authentication private key - * @param a005Key the authentication private key + * @param x002Key the authentication private key */ - public void setX002PrivateKey(PrivateKey x002Key); + void setX002PrivateKey(PrivateKey x002Key); /** * Sets the encryption private key - * @param a005Key the encryption private key + * @param e002Key the encryption private key */ - public void setE002PrivateKey(PrivateKey e002Key); + void setE002PrivateKey(PrivateKey e002Key); /** * Returns the type to security medium used to store the A005 key. * @return the type to security medium used to store the A005 key. */ - public String getSecurityMedium(); + String getSecurityMedium(); /** * Returns the customer in whose name we operate. * @return the customer in whose name we operate. */ - public EbicsPartner getPartner(); + EbicsPartner getPartner(); /** * Returns the (bank provided) user id. * @return the (bank provided) user id. */ - public String getUserId(); + String getUserId(); /** * Returns the user name. * @return the user name. */ - public String getName(); + String getName(); /** * Returns the distinguished name * @return the distinguished name */ - public String getDN(); + String getDN(); /** * Returns the password callback handler for the current user. * @return the password callback handler. */ - public PasswordCallback getPasswordCallback(); + PasswordCallback getPasswordCallback(); /** * Signs the given digest with the private X002 key. @@ -153,7 +151,7 @@ public interface EbicsUser { * @return the signature. * @throws GeneralSecurityException */ - public byte[] authenticate(byte[] digest) throws GeneralSecurityException; + byte[] authenticate(byte[] digest) throws GeneralSecurityException; /** * Signs the given digest with the private A005 key. @@ -162,7 +160,7 @@ public interface EbicsUser { * @throws IOException * @throws GeneralSecurityException */ - public byte[] sign(byte[] digest) throws IOException, GeneralSecurityException; + byte[] sign(byte[] digest) throws IOException, GeneralSecurityException; /** * Uses the E001 key to decrypt the given secret key. @@ -173,6 +171,6 @@ public interface EbicsUser { * @throws IOException * @throws EbicsException */ - public byte[] decrypt(byte[] encryptedKey, byte[] transactionKey) + byte[] decrypt(byte[] encryptedKey, byte[] transactionKey) throws GeneralSecurityException, IOException, EbicsException; } diff --git a/src/main/java/org/kopi/ebics/interfaces/InitLetter.java b/src/main/java/org/kopi/ebics/interfaces/InitLetter.java index 79c88263..8c84ad1b 100644 --- a/src/main/java/org/kopi/ebics/interfaces/InitLetter.java +++ b/src/main/java/org/kopi/ebics/interfaces/InitLetter.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -31,7 +30,6 @@ * letter. The INI, HIA and HPB letters should be an implementation * of the InitLetter * - * @author Hachani * */ public interface InitLetter { diff --git a/src/main/java/org/kopi/ebics/interfaces/LetterManager.java b/src/main/java/org/kopi/ebics/interfaces/LetterManager.java index 88e096b8..374ce13d 100644 --- a/src/main/java/org/kopi/ebics/interfaces/LetterManager.java +++ b/src/main/java/org/kopi/ebics/interfaces/LetterManager.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -29,7 +28,6 @@ * Initialization letters manager. * Manages the INI, HIA and the HPB letters. * - * @author Hachani * */ public interface LetterManager { @@ -44,7 +42,7 @@ public interface LetterManager { * @throws IOException * @throws GeneralSecurityException */ - public InitLetter createA005Letter(EbicsUser user) + InitLetter createA005Letter(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException; /** @@ -57,7 +55,7 @@ public InitLetter createA005Letter(EbicsUser user) * @throws IOException * @throws GeneralSecurityException */ - public InitLetter createE002Letter(EbicsUser user) + InitLetter createE002Letter(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException; /** @@ -70,6 +68,6 @@ public InitLetter createE002Letter(EbicsUser user) * @throws IOException * @throws GeneralSecurityException */ - public InitLetter createX002Letter(EbicsUser user) + InitLetter createX002Letter(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException; } diff --git a/src/main/java/org/kopi/ebics/interfaces/PasswordCallback.java b/src/main/java/org/kopi/ebics/interfaces/PasswordCallback.java index 47a8b54f..4fe7e5dc 100644 --- a/src/main/java/org/kopi/ebics/interfaces/PasswordCallback.java +++ b/src/main/java/org/kopi/ebics/interfaces/PasswordCallback.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -22,7 +21,6 @@ /** * A way to obtain a password. * - * @author Hachani * */ public interface PasswordCallback { @@ -32,5 +30,5 @@ public interface PasswordCallback { * This may be done via user interaction or by passing a stored password. * @return the password */ - public char[] getPassword(); + char[] getPassword(); } diff --git a/src/main/java/org/kopi/ebics/interfaces/Savable.java b/src/main/java/org/kopi/ebics/interfaces/Savable.java index 57e8a467..a0b8b6b6 100644 --- a/src/main/java/org/kopi/ebics/interfaces/Savable.java +++ b/src/main/java/org/kopi/ebics/interfaces/Savable.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; @@ -27,7 +26,6 @@ * files or databases. The save process can be launched via the method * {@linkplain Savable#save(ObjectOutputStream)} * - * @author hachani * */ public interface Savable { @@ -37,11 +35,11 @@ public interface Savable { * @param oos the given stream. * @throws IOException save process failed */ - public void save(ObjectOutputStream oos) throws IOException; + void save(ObjectOutputStream oos) throws IOException; /** * Returns the save name of this savable object. * @return the save name */ - public String getSaveName(); + String getSaveName(); } diff --git a/src/main/java/org/kopi/ebics/interfaces/SerializationManager.java b/src/main/java/org/kopi/ebics/interfaces/SerializationManager.java index 242842bd..0cfd39a3 100644 --- a/src/main/java/org/kopi/ebics/interfaces/SerializationManager.java +++ b/src/main/java/org/kopi/ebics/interfaces/SerializationManager.java @@ -14,11 +14,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; +import java.io.File; import java.io.ObjectInputStream; import org.kopi.ebics.exception.EbicsException; @@ -29,7 +29,6 @@ * The manager should ensure serialization and deserialization * operations * - * @author hachani * */ public interface SerializationManager { @@ -39,7 +38,7 @@ public interface SerializationManager { * @param object the Savable object$ * @throws EbicsException serialization fails */ - public void serialize(Savable object) throws EbicsException; + void serialize(Savable object) throws EbicsException; /** * Deserializes the given object input stream. @@ -47,11 +46,11 @@ public interface SerializationManager { * @return the corresponding object input stream * @throws EbicsException deserialization fails */ - public ObjectInputStream deserialize(String name) throws EbicsException; + ObjectInputStream deserialize(String name) throws EbicsException; /** * Sets the serialization directory * @param serializationDir the serialization directory */ - public void setSerializationDirectory(String serializationDir); + void setSerializationDirectory(File serializationDir); } diff --git a/src/main/java/org/kopi/ebics/interfaces/TraceManager.java b/src/main/java/org/kopi/ebics/interfaces/TraceManager.java index 3fb36ec6..f7c5974f 100644 --- a/src/main/java/org/kopi/ebics/interfaces/TraceManager.java +++ b/src/main/java/org/kopi/ebics/interfaces/TraceManager.java @@ -14,11 +14,12 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.interfaces; +import java.io.File; + import org.kopi.ebics.exception.EbicsException; /** @@ -26,7 +27,6 @@ * requests and responses from the EBICS bank server. * This can be done using the trace(EbicsRootElement) * - * @author hachani * */ public interface TraceManager { @@ -58,7 +58,7 @@ public interface TraceManager { /** * Sets the trace directory */ - void setTraceDirectory(String traceDir); + void setTraceDirectory(File traceDir); /** * Enables or disables the trace feature diff --git a/src/main/java/org/kopi/ebics/io/ByteArrayContentFactory.java b/src/main/java/org/kopi/ebics/io/ByteArrayContentFactory.java index 56bf3a32..f9629467 100644 --- a/src/main/java/org/kopi/ebics/io/ByteArrayContentFactory.java +++ b/src/main/java/org/kopi/ebics/io/ByteArrayContentFactory.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -22,6 +21,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import org.kopi.ebics.interfaces.ContentFactory; @@ -31,7 +31,6 @@ * as a ByteArrayInputStream. This object is * serializable in a way to recover interrupted file transfers. * - * @author hachani * */ public class ByteArrayContentFactory implements ContentFactory { @@ -50,10 +49,16 @@ public InputStream getContent() throws IOException { return new ByteArrayInputStream(content); } + + @Override + public String toString() { + return new String(content, StandardCharsets.UTF_8); + } + // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- - private byte[] content; + private final byte[] content; private static final long serialVersionUID = 4708928447888655116L; } diff --git a/src/main/java/org/kopi/ebics/io/FileCache.java b/src/main/java/org/kopi/ebics/io/FileCache.java index 7cff900f..b26a6652 100644 --- a/src/main/java/org/kopi/ebics/io/FileCache.java +++ b/src/main/java/org/kopi/ebics/io/FileCache.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -26,7 +25,6 @@ /** * A simple mean to cache created files. * - * @author hachani * */ public class FileCache { @@ -37,7 +35,7 @@ public class FileCache { */ public FileCache(boolean isTraceEnabled) { this.isTraceEnabled = isTraceEnabled; - cache = new Hashtable(); + cache = new Hashtable<>(); } /** @@ -95,6 +93,6 @@ public void setTraceEnabled(boolean enabled) { // DATA MEMBERS // -------------------------------------------------------------------- - private Map cache; + private final Map cache; private boolean isTraceEnabled; } diff --git a/src/main/java/org/kopi/ebics/io/FileContentFactory.java b/src/main/java/org/kopi/ebics/io/FileContentFactory.java index 8db13fa7..0743df88 100644 --- a/src/main/java/org/kopi/ebics/io/FileContentFactory.java +++ b/src/main/java/org/kopi/ebics/io/FileContentFactory.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -32,7 +31,6 @@ * as a FileInputStream. This object is * serializable in a way to recover interrupted file transfers. * - * @author hachani * */ public class FileContentFactory implements ContentFactory { @@ -55,6 +53,6 @@ public InputStream getContent() throws IOException { // DATA MEMBERS // -------------------------------------------------------------------- - private File input; + private final File input; private static final long serialVersionUID = -7041705645994170039L; } diff --git a/src/main/java/org/kopi/ebics/io/IOUtils.java b/src/main/java/org/kopi/ebics/io/IOUtils.java index eb8269a8..324e150f 100644 --- a/src/main/java/org/kopi/ebics/io/IOUtils.java +++ b/src/main/java/org/kopi/ebics/io/IOUtils.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -33,83 +32,17 @@ * Some IO utilities for EBICS files management. * EBICS server * - * @author hachani * */ -public class IOUtils { +public final class IOUtils { /** - * Creates a directory from a root one - * @param parent the parent directory - * @param child the directory name - * @return The created directory - */ - public static File createDirectory(File parent, String child) { - File directory; - - directory = new File(parent, child); - directory.mkdir(); - - return directory; - } - - /** - * Creates a directory from a root one - * @param parent the parent directory - * @param child the directory name - * @return The created directory - */ - public static File createDirectory(String parent, String child) { - File directory; - - directory = new File(parent, child); - directory.mkdir(); - - return directory; - } - - /** - * Creates a directory from a directory name - * @param name the absolute directory name - * @return The created directory - */ - public static File createDirectory(String name) { - File directory; - - directory = new File(name); - directory.mkdir(); - - return directory; - } - - /** - * Creates many directories from a given full path. + * Creates directories from a given full path. * Path should use default separator like '/' for UNIX * systems - * @param fullName the full absolute path of the directories - * @return The created directory */ - public static File createDirectories(String fullName) { - File directory; - - directory = new File(fullName); + public static void createDirectories(File directory) { directory.mkdirs(); - - return directory; - } - - /** - * Creates a new java.io.File from a given root. - * @param parent the parent of the file. - * @param name the file name. - * @return the created file. - */ - public static File createFile(File parent, String name) { - File file; - - file = new File(parent, name); - - return file; } @@ -121,9 +54,9 @@ public static File createFile(File parent, String name) { */ public static byte[] getFileContent(File file) throws EbicsException { try { - try(FileInputStream input = new FileInputStream(file)) { - return inputStreamToBytes(input); - } + try (FileInputStream input = new FileInputStream(file)) { + return inputStreamToBytes(input); + } } catch (IOException e) { throw new EbicsException(e.getMessage()); } @@ -132,7 +65,7 @@ public static byte[] getFileContent(File file) throws EbicsException { /** * Returns the content of a ContentFactory as a byte array * @param content - * @return + * @return content of a ContentFactory as a byte[] * @throws EbicsException */ public static byte[] getFactoryContent(ContentFactory content) throws EbicsException { @@ -153,4 +86,7 @@ private static byte[] inputStreamToBytes(InputStream in) throws IOException { out.close(); return out.toByteArray(); } + + private IOUtils() { + } } diff --git a/src/main/java/org/kopi/ebics/io/InputStreamContentFactory.java b/src/main/java/org/kopi/ebics/io/InputStreamContentFactory.java index 0aaedec9..c2900f53 100644 --- a/src/main/java/org/kopi/ebics/io/InputStreamContentFactory.java +++ b/src/main/java/org/kopi/ebics/io/InputStreamContentFactory.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -31,7 +30,6 @@ * This object is serializable in a way to recover interrupted * file transfers. * - * @author hachani * */ public class InputStreamContentFactory implements ContentFactory { @@ -53,6 +51,6 @@ public InputStream getContent() throws IOException { // DATA MEMBERS // -------------------------------------------------------------------- - private InputStream input; + private final InputStream input; private static final long serialVersionUID = 2357104115203917168L; } diff --git a/src/main/java/org/kopi/ebics/io/Joiner.java b/src/main/java/org/kopi/ebics/io/Joiner.java index 538313d7..0ee7d4cc 100644 --- a/src/main/java/org/kopi/ebics/io/Joiner.java +++ b/src/main/java/org/kopi/ebics/io/Joiner.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -32,7 +31,6 @@ * A simple mean to join downloaded segments from the * bank ebics server. * - * @author Hachani * */ public class Joiner { @@ -70,9 +68,7 @@ public void writeTo(OutputStream output, byte[] transactionKey) buffer.close(); decrypted = user.decrypt(buffer.toByteArray(), transactionKey); output.write(Utils.unzip(decrypted)); - } catch (GeneralSecurityException e) { - throw new EbicsException(e.getMessage()); - } catch (IOException e) { + } catch (GeneralSecurityException | IOException e) { throw new EbicsException(e.getMessage()); } } @@ -81,6 +77,6 @@ public void writeTo(OutputStream output, byte[] transactionKey) // DATA MEMBERS // -------------------------------------------------------------------- - private EbicsUser user; - private ByteArrayOutputStream buffer; + private final EbicsUser user; + private final ByteArrayOutputStream buffer; } diff --git a/src/main/java/org/kopi/ebics/io/Splitter.java b/src/main/java/org/kopi/ebics/io/Splitter.java index d0de40ed..1e815e6e 100644 --- a/src/main/java/org/kopi/ebics/io/Splitter.java +++ b/src/main/java/org/kopi/ebics/io/Splitter.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.io; @@ -113,7 +112,7 @@ private void segmentation() { * a given segment number. * * @param segmentNumber the segment number - * @return + * @return content of a data segment */ public ContentFactory getContent(int segmentNumber) { byte[] segment; diff --git a/src/main/java/org/kopi/ebics/letter/A005Letter.java b/src/main/java/org/kopi/ebics/letter/A005Letter.java index e7da92dd..5e878b3b 100644 --- a/src/main/java/org/kopi/ebics/letter/A005Letter.java +++ b/src/main/java/org/kopi/ebics/letter/A005Letter.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.letter; @@ -23,7 +22,6 @@ import java.security.GeneralSecurityException; import java.util.Locale; -import org.apache.commons.codec.binary.Base64; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.EbicsUser; @@ -32,7 +30,6 @@ * The A005Letter is the initialization letter * for the signature certificate * - * @author Hachani * */ public class A005Letter extends AbstractInitLetter { @@ -47,29 +44,19 @@ public A005Letter(Locale locale) { @Override public void create(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException { - if (user.getPartner().getBank().useCertificate()) { - build(user.getPartner().getBank().getHostId(), - user.getPartner().getBank().getName(), - user.getUserId(), - user.getName(), - user.getPartner().getPartnerId(), - getString("INILetter.version"), - getString("INILetter.certificate"), - Base64.encodeBase64(user.getA005Certificate(), true), - getString("INILetter.digest"), - getHash(user.getA005Certificate())); - } else { - build(user.getPartner().getBank().getHostId(), - user.getPartner().getBank().getName(), - user.getUserId(), - user.getName(), - user.getPartner().getPartnerId(), - getString("INILetter.version"), - getString("INILetter.certificate"), - null, - getString("INILetter.digest"), - getHash(user.getA005PublicKey())); - } + // EBICS 3.0 (H005): the INI letter must carry the SHA-256 hash of the + // DER-encoded signature certificate (spec ch. 4.4.1.2.3), matching the + // X.509 certificate transmitted in the INI request. + build(user.getPartner().getBank().getHostId(), + user.getPartner().getBank().getName(), + user.getUserId(), + user.getName(), + user.getPartner().getPartnerId(), + getString("INILetter.version"), + getString("INILetter.certificate"), + chunkedBase64(user.getA005Certificate()), + getString("INILetter.digest"), + getHash(user.getA005Certificate())); } @Override diff --git a/src/main/java/org/kopi/ebics/letter/AbstractInitLetter.java b/src/main/java/org/kopi/ebics/letter/AbstractInitLetter.java index a3e216a7..1905f26c 100644 --- a/src/main/java/org/kopi/ebics/letter/AbstractInitLetter.java +++ b/src/main/java/org/kopi/ebics/letter/AbstractInitLetter.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.letter; @@ -23,17 +22,15 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.GeneralSecurityException; import java.security.MessageDigest; -import java.security.interfaces.RSAPublicKey; import java.text.SimpleDateFormat; +import java.util.Base64; import java.util.Date; +import java.util.HexFormat; import java.util.Locale; -import org.apache.commons.codec.binary.Hex; -import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.InitLetter; import org.kopi.ebics.messages.Messages; @@ -44,7 +41,7 @@ public abstract class AbstractInitLetter implements InitLetter { * Constructs a new initialization letter. * @param locale the application locale */ - public AbstractInitLetter(Locale locale) { + protected AbstractInitLetter(Locale locale) { this.locale = locale; this.messages = new Messages(BUNDLE_NAME, locale); } @@ -101,45 +98,34 @@ protected String getString(String key) { } /** - * Returns the certificate hash - * @param certificate the certificate + * Returns the SHA-256 hash of the DER-encoded certificate. + * @param certificate the DER-encoded certificate * @return the certificate hash * @throws GeneralSecurityException */ protected byte[] getHash(byte[] certificate) throws GeneralSecurityException { - String hash256 = new String( - Hex.encodeHex(MessageDigest.getInstance("SHA-256").digest(certificate), false)); + String hash256 = HexFormat.of().withUpperCase().formatHex( + MessageDigest.getInstance("SHA-256").digest(certificate)); return format(hash256).getBytes(); } - protected byte[] getHash(RSAPublicKey publicKey) throws EbicsException { - String modulus; - String exponent; - String hash; - byte[] digest; - - exponent = Hex.encodeHexString(publicKey.getPublicExponent().toByteArray()); - modulus = Hex.encodeHexString(removeFirstByte(publicKey.getModulus().toByteArray())); - hash = exponent + " " + modulus; - - if (hash.charAt(0) == '0') { - hash = hash.substring(1); - } - - try { - digest = MessageDigest.getInstance("SHA-256", "BC").digest(hash.getBytes("US-ASCII")); - } catch (GeneralSecurityException | UnsupportedEncodingException e) { - throw new EbicsException(e.getMessage()); - } - - return format(new String(Hex.encodeHex(digest, false))).getBytes(); - } - - private static byte[] removeFirstByte(byte[] byteArray) { - byte[] b = new byte[byteArray.length - 1]; - System.arraycopy(byteArray, 1, b, 0, b.length); - return b; + /** + * Encodes {@code data} as MIME Base64 (76-character lines separated by CRLF) + * with a trailing CRLF, matching the historical commons-codec + * {@code Base64.encodeBase64(data, true)} byte-for-byte so PEM-style blocks + * in the letter keep the {@code -----END CERTIFICATE-----} marker on its own line. + */ + protected static byte[] chunkedBase64(byte[] data) { + byte[] encoded = Base64.getMimeEncoder().encode(data); + if (encoded.length == 0) { + return encoded; } + byte[] result = new byte[encoded.length + 2]; + System.arraycopy(encoded, 0, result, 0, encoded.length); + result[encoded.length] = '\r'; + result[encoded.length + 1] = '\n'; + return result; + } /** * Formats a hash 256 input. @@ -147,13 +133,13 @@ private static byte[] removeFirstByte(byte[] byteArray) { * @return the formatted hash */ private String format(String hash256) { - StringBuffer buffer = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < hash256.length(); i += 2) { - buffer.append(hash256.charAt(i)); - buffer.append(hash256.charAt(i + 1)); - buffer.append(' '); + sb.append(hash256.charAt(i)); + sb.append(hash256.charAt(i + 1)); + sb.append(' '); } - return buffer.substring(0, 48) + LINE_SEPARATOR + buffer.substring(48) + LINE_SEPARATOR; + return sb.substring(0, 48) + LINE_SEPARATOR + sb.substring(48) + LINE_SEPARATOR; } // -------------------------------------------------------------------- @@ -164,7 +150,6 @@ private String format(String hash256) { * The Letter object is the common template * for all initialization letter. * - * @author Hachani * */ class Letter { @@ -217,8 +202,9 @@ public void build(String certTitle, writer = new PrintWriter(out, true); buildTitle(); buildHeader(); - if (certificate != null) - buildCertificate(certTitle, certificate); + if (certificate != null) { + buildCertificate(certTitle, certificate); + } buildHash(hashTitle, hash); buildFooter(); writer.close(); @@ -370,7 +356,7 @@ public String formatTime(Date time) { /** * Returns the letter content - * @return + * @return letter content as a byte[] */ public byte[] getLetter() { return out.toByteArray(); diff --git a/src/main/java/org/kopi/ebics/letter/DefaultLetterManager.java b/src/main/java/org/kopi/ebics/letter/DefaultLetterManager.java index 37b75f60..b5368d58 100644 --- a/src/main/java/org/kopi/ebics/letter/DefaultLetterManager.java +++ b/src/main/java/org/kopi/ebics/letter/DefaultLetterManager.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.letter; @@ -33,7 +32,6 @@ * The DefaultLetterManager is a simple way * to manage initialization letters. * - * @author Hachani * */ public class DefaultLetterManager implements LetterManager { @@ -83,5 +81,5 @@ public InitLetter createX002Letter(EbicsUser user) // DATA MEMBERS // -------------------------------------------------------------------- - private Locale locale; + private final Locale locale; } diff --git a/src/main/java/org/kopi/ebics/letter/E002Letter.java b/src/main/java/org/kopi/ebics/letter/E002Letter.java index c6a5812f..fea9d125 100644 --- a/src/main/java/org/kopi/ebics/letter/E002Letter.java +++ b/src/main/java/org/kopi/ebics/letter/E002Letter.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.letter; @@ -23,7 +22,6 @@ import java.security.GeneralSecurityException; import java.util.Locale; -import org.apache.commons.codec.binary.Base64; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.EbicsUser; @@ -32,7 +30,6 @@ * The E002Letter is the initialization letter * for the encryption certificate. * - * @author Hachani * */ public class E002Letter extends AbstractInitLetter { @@ -47,29 +44,19 @@ public E002Letter(Locale locale) { @Override public void create(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException { - if (user.getPartner().getBank().useCertificate()) { - build(user.getPartner().getBank().getHostId(), - user.getPartner().getBank().getName(), - user.getUserId(), - user.getName(), - user.getPartner().getPartnerId(), - getString("HIALetter.e002.version"), - getString("HIALetter.e002.certificate"), - Base64.encodeBase64(user.getE002Certificate(), true), - getString("HIALetter.e002.digest"), - getHash(user.getE002Certificate())); - } else { - build(user.getPartner().getBank().getHostId(), - user.getPartner().getBank().getName(), - user.getUserId(), - user.getName(), - user.getPartner().getPartnerId(), - getString("HIALetter.e002.version"), - getString("HIALetter.e002.certificate"), - null, - getString("HIALetter.e002.digest"), - getHash(user.getE002PublicKey())); - } + // EBICS 3.0 (H005): the HIA letter must carry the SHA-256 hash of the + // DER-encoded encryption certificate (spec ch. 4.4.1.2.3), matching the + // X.509 certificate transmitted in the HIA request. + build(user.getPartner().getBank().getHostId(), + user.getPartner().getBank().getName(), + user.getUserId(), + user.getName(), + user.getPartner().getPartnerId(), + getString("HIALetter.e002.version"), + getString("HIALetter.e002.certificate"), + chunkedBase64(user.getE002Certificate()), + getString("HIALetter.e002.digest"), + getHash(user.getE002Certificate())); } @Override diff --git a/src/main/java/org/kopi/ebics/letter/X002Letter.java b/src/main/java/org/kopi/ebics/letter/X002Letter.java index b5abbc7c..f51fbe60 100644 --- a/src/main/java/org/kopi/ebics/letter/X002Letter.java +++ b/src/main/java/org/kopi/ebics/letter/X002Letter.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.letter; @@ -23,7 +22,6 @@ import java.security.GeneralSecurityException; import java.util.Locale; -import org.apache.commons.codec.binary.Base64; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.EbicsUser; @@ -32,7 +30,6 @@ * The X002Letter is the initialization letter * for the authentication certificate. * - * @author Hachani * */ public class X002Letter extends AbstractInitLetter { @@ -47,29 +44,19 @@ public X002Letter(Locale locale) { @Override public void create(EbicsUser user) throws GeneralSecurityException, IOException, EbicsException { - if (user.getPartner().getBank().useCertificate()) { - build(user.getPartner().getBank().getHostId(), - user.getPartner().getBank().getName(), - user.getUserId(), - user.getName(), - user.getPartner().getPartnerId(), - getString("HIALetter.x002.version"), - getString("HIALetter.x002.certificate"), - Base64.encodeBase64(user.getX002Certificate(), true), - getString("HIALetter.x002.digest"), - getHash(user.getX002Certificate())); - } else { - build(user.getPartner().getBank().getHostId(), - user.getPartner().getBank().getName(), - user.getUserId(), - user.getName(), - user.getPartner().getPartnerId(), - getString("HIALetter.x002.version"), - getString("HIALetter.x002.certificate"), - null, - getString("HIALetter.x002.digest"), - getHash(user.getX002PublicKey())); - } + // EBICS 3.0 (H005): the HIA letter must carry the SHA-256 hash of the + // DER-encoded authentication certificate (spec ch. 4.4.1.2.3), matching + // the X.509 certificate transmitted in the HIA request. + build(user.getPartner().getBank().getHostId(), + user.getPartner().getBank().getName(), + user.getUserId(), + user.getName(), + user.getPartner().getPartnerId(), + getString("HIALetter.x002.version"), + getString("HIALetter.x002.certificate"), + chunkedBase64(user.getX002Certificate()), + getString("HIALetter.x002.digest"), + getHash(user.getX002Certificate())); } @Override diff --git a/src/main/java/org/kopi/ebics/messages/Messages.java b/src/main/java/org/kopi/ebics/messages/Messages.java index dbedf918..7e886cb3 100644 --- a/src/main/java/org/kopi/ebics/messages/Messages.java +++ b/src/main/java/org/kopi/ebics/messages/Messages.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.messages; @@ -65,11 +64,7 @@ public String getString(String key, Object ... arguments) { * @return the corresponding key value */ public String getString(String key) { - try { return resourceBundle.getString(key); - } catch (MissingResourceException e) { - throw new RuntimeException(e); - } } private static ResourceBundle getBundle(String bundleName, Locale locale) { diff --git a/src/main/java/org/kopi/ebics/security/EbicsSocketFactory.java b/src/main/java/org/kopi/ebics/security/EbicsSocketFactory.java index 2e2ddaab..fd254435 100644 --- a/src/main/java/org/kopi/ebics/security/EbicsSocketFactory.java +++ b/src/main/java/org/kopi/ebics/security/EbicsSocketFactory.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.security; @@ -23,20 +22,19 @@ import java.io.IOException; import java.net.InetAddress; import java.net.Socket; -import java.net.UnknownHostException; import java.security.GeneralSecurityException; import java.security.KeyStore; -import java.security.SecureRandom; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; +import org.kopi.ebics.utils.Utils; + /** * A simple SSL socket factory for EBICS client. * - * @author hachani * */ public class EbicsSocketFactory extends SSLSocketFactory { @@ -54,7 +52,7 @@ public EbicsSocketFactory(SSLContext context) { * key store and trust store information * @param keystore the key store * @param keystoreType the key store type - * @param keystrorePass the key store password + * @param keystorePass the key store password * @param truststore the trust store * @param truststoreType the trust store type * @param truststorePass the trust store password @@ -63,7 +61,7 @@ public EbicsSocketFactory(SSLContext context) { */ public EbicsSocketFactory(byte[] keystore, String keystoreType, - char[] keystrorePass, + char[] keystorePass, byte[] truststore, String truststoreType, char[] truststorePass) @@ -71,7 +69,7 @@ public EbicsSocketFactory(byte[] keystore, { this.context = getSSLContext(keystore, keystoreType, - keystrorePass, + keystorePass, truststore, truststoreType, truststorePass); @@ -81,7 +79,7 @@ public EbicsSocketFactory(byte[] keystore, * Returns the SSLContext from key store information. * @param keystore the key store * @param keystoreType the key store type - * @param keystrorePass the key store password + * @param keystorePass the key store password * @param truststore the trust store * @param truststoreType the trust store type * @param truststorePass the trust store password @@ -91,7 +89,7 @@ public EbicsSocketFactory(byte[] keystore, */ public SSLContext getSSLContext(byte[] keystore, String keystoreType, - char[] keystrorePass, + char[] keystorePass, byte[] truststore, String truststoreType, char[] truststorePass) @@ -103,15 +101,15 @@ public SSLContext getSSLContext(byte[] keystore, TrustManagerFactory tmf; SSLContext context; - kstore = initKeyStore(keystore, keystrorePass, keystoreType); + kstore = initKeyStore(keystore, keystorePass, keystoreType); kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(kstore, keystrorePass); + kmf.init(kstore, keystorePass); tstore = initKeyStore(truststore, truststorePass, truststoreType); tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(tstore); context = SSLContext.getInstance("TLS"); - context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); + context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), Utils.secureRandom); return context; } @@ -135,8 +133,7 @@ protected KeyStore initKeyStore(byte[] keystore, char[] password, String type) } catch (IOException e) { throw e; } catch (Exception e) { - e.printStackTrace(); - throw new IOException("Exception trying to load keystore " + type + ": " + e.toString()); + throw new IOException("Exception trying to load keystore " + type + ": " + e, e); } } @@ -158,7 +155,7 @@ public String[] getSupportedCipherSuites() { } @Override - public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + public Socket createSocket(String host, int port) throws IOException { return context.getSocketFactory().createSocket(host, port); } @@ -169,8 +166,7 @@ public Socket createSocket(InetAddress host, int port) throws IOException { @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) - throws IOException, UnknownHostException - { + throws IOException { return context.getSocketFactory().createSocket(host, port, localHost, localPort); } @@ -181,5 +177,5 @@ public Socket createSocket(InetAddress address, int port, InetAddress localAddre return context.getSocketFactory().createSocket(address, port, localAddress, localPort); } - private SSLContext context; + private final SSLContext context; } diff --git a/src/main/java/org/kopi/ebics/security/UserPasswordHandler.java b/src/main/java/org/kopi/ebics/security/UserPasswordHandler.java index 7970ff95..9fb89ab0 100644 --- a/src/main/java/org/kopi/ebics/security/UserPasswordHandler.java +++ b/src/main/java/org/kopi/ebics/security/UserPasswordHandler.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.security; @@ -25,7 +24,6 @@ * A simple user password handler that creates a password * from the user id and a simple suffix. * - * @author hachani * */ public class UserPasswordHandler implements PasswordCallback { @@ -53,6 +51,6 @@ public char[] getPassword() { // DATA MEMBERS // -------------------------------------------------------------------- - private String userId; - private String suffix; + private final String userId; + private final String suffix; } diff --git a/src/main/java/org/kopi/ebics/session/DefaultConfiguration.java b/src/main/java/org/kopi/ebics/session/DefaultConfiguration.java index 7e66fbcf..897c4658 100644 --- a/src/main/java/org/kopi/ebics/session/DefaultConfiguration.java +++ b/src/main/java/org/kopi/ebics/session/DefaultConfiguration.java @@ -14,22 +14,17 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.session; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.util.Locale; import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; -import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.Configuration; -import org.kopi.ebics.interfaces.EbicsLogger; import org.kopi.ebics.interfaces.EbicsUser; import org.kopi.ebics.interfaces.LetterManager; import org.kopi.ebics.interfaces.SerializationManager; @@ -41,7 +36,6 @@ /** * A simple client application configuration. * - * @author hachani * */ public class DefaultConfiguration implements Configuration { @@ -50,11 +44,10 @@ public class DefaultConfiguration implements Configuration { * Creates a new application configuration. * @param rootDir the root directory */ - public DefaultConfiguration(String rootDir, Properties properties) { + public DefaultConfiguration(File rootDir, Properties properties) { this.rootDir = rootDir; bundle = ResourceBundle.getBundle(RESOURCE_DIR); this.properties = properties; - logger = new DefaultEbicsLogger(); serializationManager = new DefaultSerializationManager(); traceManager = new DefaultTraceManager(); } @@ -73,7 +66,7 @@ private String getString(String key) { } @Override - public String getRootDirectory() { + public File getRootDirectory() { return rootDir; } @@ -81,8 +74,6 @@ public String getRootDirectory() { public void init() { //Create the root directory IOUtils.createDirectories(getRootDirectory()); - //Create the logs directory - IOUtils.createDirectories(getLogDirectory()); //Create the serialization directory IOUtils.createDirectories(getSerializationDirectory()); //create the SSL trusted stores directories @@ -94,9 +85,6 @@ public void init() { //Create users directory IOUtils.createDirectories(getUsersDirectory()); - logger.setLogFile(getLogDirectory() + File.separator + getLogFileName()); - ((DefaultEbicsLogger)logger).setFileLoggingEnabled(true); - ((DefaultEbicsLogger)logger).setLevel(DefaultEbicsLogger.ALL_LEVEL); serializationManager.setSerializationDirectory(getSerializationDirectory()); traceManager.setTraceEnabled(isTraceEnabled()); letterManager = new DefaultLetterManager(getLocale()); @@ -108,18 +96,8 @@ public Locale getLocale() { } @Override - public String getLogDirectory() { - return rootDir + File.separator + getString("log.dir.name"); - } - - @Override - public String getLogFileName() { - return getString("log.file.name"); - } - - @Override - public String getConfigurationFile() { - return rootDir + File.separator + getString("conf.file.name"); + public File getConfigurationFile() { + return rootDir(getString("conf.file.name")); } @Override @@ -128,38 +106,42 @@ public String getProperty(String key) { } @Override - public String getKeystoreDirectory(EbicsUser user) { - return getUserDirectory(user) + File.separator + getString("keystore.dir.name"); + public File getKeystoreDirectory(EbicsUser user) { + return new File(getUserDirectory(user), getString("keystore.dir.name")); } @Override - public String getTransferTraceDirectory(EbicsUser user) { - return getUserDirectory(user) + File.separator + getString("traces.dir.name"); + public File getTransferTraceDirectory(EbicsUser user) { + return new File(getUserDirectory(user), getString("traces.dir.name")); } @Override - public String getSerializationDirectory() { - return rootDir + File.separator + getString("serialization.dir.name"); + public File getSerializationDirectory() { + return rootDir(getString("serialization.dir.name")); } @Override - public String getSSLTrustedStoreDirectory() { - return rootDir + File.separator + getString("ssltruststore.dir.name"); + public File getSSLTrustedStoreDirectory() { + return rootDir(getString("ssltruststore.dir.name")); } @Override - public String getSSLKeyStoreDirectory() { - return rootDir + File.separator + getString("sslkeystore.dir.name"); + public File getSSLKeyStoreDirectory() { + return rootDir(getString("sslkeystore.dir.name")); } @Override - public String getSSLBankCertificates() { - return rootDir + File.separator + getString("sslbankcert.dir.name"); + public File getSSLBankCertificates() { + return rootDir(getString("sslbankcert.dir.name")); } @Override - public String getUsersDirectory() { - return rootDir + File.separator + getString("users.dir.name"); + public File getUsersDirectory() { + return rootDir(getString("users.dir.name")); + } + + private File rootDir(String name) { + return new File(rootDir, name); } @Override @@ -178,18 +160,13 @@ public LetterManager getLetterManager() { } @Override - public String getLettersDirectory(EbicsUser user) { - return getUserDirectory(user) + File.separator + getString("letters.dir.name"); - } - - @Override - public String getUserDirectory(EbicsUser user) { - return getUsersDirectory() + File.separator + user.getUserId(); + public File getLettersDirectory(EbicsUser user) { + return new File(getUserDirectory(user), getString("letters.dir.name")); } @Override - public EbicsLogger getLogger() { - return logger; + public File getUserDirectory(EbicsUser user) { + return new File(getUsersDirectory(), user.getUserId()); } @Override @@ -231,10 +208,9 @@ public String getVersion() { // DATA MEMBERS // -------------------------------------------------------------------- - private final String rootDir; + private final File rootDir; private final ResourceBundle bundle; private final Properties properties; - private final EbicsLogger logger; private final SerializationManager serializationManager; private final TraceManager traceManager; private LetterManager letterManager; diff --git a/src/main/java/org/kopi/ebics/session/DefaultEbicsLogger.java b/src/main/java/org/kopi/ebics/session/DefaultEbicsLogger.java deleted file mode 100644 index 56219a33..00000000 --- a/src/main/java/org/kopi/ebics/session/DefaultEbicsLogger.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 1990-2012 kopiLeft Development SARL, Bizerte, Tunisia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -package org.kopi.ebics.session; - -import java.io.File; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.RollingFileAppender; -import org.kopi.ebics.exception.ReturnCode; -import org.kopi.ebics.interfaces.EbicsLogger; - - -/** - * A simple EBICS transfers logger base on log4j framework. - * - * @author hacheni - * - */ -public class DefaultEbicsLogger implements EbicsLogger { - - /** - * Constructs a new ebics logger - */ - public DefaultEbicsLogger() { - this(null); - } - - /** - * Constructs a new ebics logger with a given file - * @param logFile the log file - */ - public DefaultEbicsLogger(File logFile) { - this.logFile = logFile; - logger = Logger.getLogger(DefaultEbicsLogger.class); - consoleAppender = new ConsoleAppender(); - fileAppender = new RollingFileAppender(); - } - - /** - * Enables or disable the console log - * @param enabled the console log state - */ - public void setConsoleLoggingEnabled(boolean enabled) { - if (enabled) { - if (!logger.isAttached(consoleAppender)) { - addConsoleAppender(); - } - } else { - removeConsoleAppender(); - } - } - - /** - * Enables or disable the file logging - * @param enabled the file log state - */ - public void setFileLoggingEnabled(boolean enabled) { - if (enabled) { - if (!logger.isAttached(fileAppender)) { - if (logFile != null) { - addFileAppender(); - } - } - } else { - removeFileAppender(); - } - } - - /** - * Adds the console appender to the current logger. - */ - private void addConsoleAppender() { - PatternLayout layout; - - layout = new PatternLayout(); - layout.setConversionPattern("%d %5p - %m%n"); - consoleAppender.setLayout(layout); - consoleAppender.setTarget("System.out"); - consoleAppender.activateOptions(); - logger.addAppender(consoleAppender); - } - - /** - * Removes the console appender from the current logger. - */ - private void removeConsoleAppender() { - if (logger.isAttached(consoleAppender)) { - logger.removeAppender(consoleAppender); - } - } - - /** - * Adds the file appender to the current logger. - */ - private void addFileAppender() { - PatternLayout layout; - - layout = new PatternLayout(); - layout.setConversionPattern("%d %5p - %m%n"); - fileAppender.setLayout(layout); - fileAppender.setAppend(true); - fileAppender.setFile(logFile.getAbsolutePath()); - fileAppender.setImmediateFlush(true); - fileAppender.setMaxFileSize("5MB"); - fileAppender.setMaxBackupIndex(1); - fileAppender.activateOptions(); - logger.addAppender(fileAppender); - } - - /** - * Removes the file appender from the current logger. - */ - private void removeFileAppender() { - if (logger.isAttached(fileAppender)) { - logger.removeAppender(fileAppender); - } - } - - /** - * Disables the log process - */ - @Deprecated - public void disable() { - Logger.shutdown(); - } - - /** - * Sets the logger level. - * @param level the level to set - */ - public void setLevel(int level) { - logger.setLevel(Level.toLevel(level)); - } - - @Override - public void info(String message) { - logger.info(message); - } - - @Override - public void warn(String message) { - logger.warn(message); - } - - @Override - public void warn(String message, Throwable throwable) { - logger.warn(message, throwable); - } - - @Override - public void error(String message) { - logger.error(message); - } - - @Override - public void error(String message, Throwable throwable) { - logger.error(message, throwable); - } - - @Override - public void report(ReturnCode returnCode) { - if (returnCode.isOk()) { - info(returnCode.getText()); - } else { - error(returnCode.getText()); - } - } - - @Override - public void setLogFile(String logFile) { - this.logFile = new File(logFile); - } - - // -------------------------------------------------------------------- - // DATA MEMBERS - // -------------------------------------------------------------------- - - private Logger logger; - private ConsoleAppender consoleAppender; - private RollingFileAppender fileAppender; - private File logFile; - - public static final int ALL_LEVEL = Level.ALL_INT; - public static final int INFO_LEVEL = Level.INFO_INT; - public static final int WARN_LEVEL = Level.WARN_INT; - public static final int ERROR_LEVEL = Level.ERROR_INT; -} diff --git a/src/main/java/org/kopi/ebics/session/DefaultSerializationManager.java b/src/main/java/org/kopi/ebics/session/DefaultSerializationManager.java index f3cf552c..f98f6d75 100644 --- a/src/main/java/org/kopi/ebics/session/DefaultSerializationManager.java +++ b/src/main/java/org/kopi/ebics/session/DefaultSerializationManager.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.session; @@ -29,7 +28,6 @@ import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.Savable; import org.kopi.ebics.interfaces.SerializationManager; -import org.kopi.ebics.io.IOUtils; /** @@ -37,7 +35,6 @@ * The serialization process aims to save object on the user disk * using a separated file for each object to serialize. * - * @author hachani * */ public class DefaultSerializationManager implements SerializationManager { @@ -60,9 +57,7 @@ public DefaultSerializationManager() { @Override public void serialize(Savable object) throws EbicsException { try { - ObjectOutputStream out; - - out = new ObjectOutputStream(new FileOutputStream(IOUtils.createFile(serializationDir, object.getSaveName()))); + var out = new ObjectOutputStream(new FileOutputStream(new File(serializationDir, object.getSaveName()))); object.save(out); } catch (IOException e) { throw new EbicsException(e.getMessage()); @@ -72,18 +67,15 @@ public void serialize(Savable object) throws EbicsException { @Override public ObjectInputStream deserialize(String name) throws EbicsException { try { - ObjectInputStream input; - - input = new ObjectInputStream(new FileInputStream(IOUtils.createFile(serializationDir, name + ".cer"))); - return input; + return new ObjectInputStream(new FileInputStream(new File(serializationDir, name + ".cer"))); } catch (IOException e) { throw new EbicsException(e.getMessage()); } } @Override - public void setSerializationDirectory(String serializationDir) { - this.serializationDir = new File(serializationDir); + public void setSerializationDirectory(File serializationDir) { + this.serializationDir = serializationDir; } // -------------------------------------------------------------------- diff --git a/src/main/java/org/kopi/ebics/session/DefaultTraceManager.java b/src/main/java/org/kopi/ebics/session/DefaultTraceManager.java index 5b7a0390..d3122783 100644 --- a/src/main/java/org/kopi/ebics/session/DefaultTraceManager.java +++ b/src/main/java/org/kopi/ebics/session/DefaultTraceManager.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.session; @@ -28,7 +27,6 @@ import org.kopi.ebics.interfaces.EbicsRootElement; import org.kopi.ebics.interfaces.TraceManager; import org.kopi.ebics.io.FileCache; -import org.kopi.ebics.io.IOUtils; /** @@ -39,7 +37,6 @@ * not offer tracing support. * see {@link Configuration#isTraceEnabled() isTraceEnabled()} * - * @author hachani * */ public class DefaultTraceManager implements TraceManager { @@ -72,11 +69,8 @@ public DefaultTraceManager() { @Override public void trace(EbicsRootElement element) throws EbicsException { try { - FileOutputStream out; - File file; - - file = IOUtils.createFile(traceDir, element.getName()); - out = new FileOutputStream(file); + var file = new File(traceDir, element.getName()); + var out = new FileOutputStream(file); element.save(out); cache.add(file); } catch (IOException e) { @@ -95,8 +89,8 @@ public void clear() { } @Override - public void setTraceDirectory(String traceDir) { - this.traceDir = new File(traceDir); + public void setTraceDirectory(File traceDir) { + this.traceDir = traceDir; } @Override @@ -109,5 +103,5 @@ public void setTraceEnabled(boolean enabled) { // -------------------------------------------------------------------- private File traceDir; - private FileCache cache; + private final FileCache cache; } diff --git a/src/main/java/org/kopi/ebics/session/EbicsSession.java b/src/main/java/org/kopi/ebics/session/EbicsSession.java index 997b5030..78af75d1 100644 --- a/src/main/java/org/kopi/ebics/session/EbicsSession.java +++ b/src/main/java/org/kopi/ebics/session/EbicsSession.java @@ -14,12 +14,10 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.session; -import java.io.IOException; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; @@ -32,7 +30,6 @@ /** * Communication hub for EBICS. * - * @author Hachani * */ public class EbicsSession { @@ -45,17 +42,15 @@ public class EbicsSession { public EbicsSession(EbicsUser user, Configuration configuration) { this.user = user; this.configuration = configuration; - parameters = new HashMap(); + parameters = new HashMap<>(); } /** * Returns the banks encryption key. * The key will be fetched automatically form the bank if needed. * @return the banks encryption key. - * @throws IOException Communication error during key retrieval. - * @throws EbicsException Server error message generated during key retrieval. */ - public RSAPublicKey getBankE002Key() throws IOException, EbicsException { + public RSAPublicKey getBankE002Key() { return user.getPartner().getBank().getE002Key(); } @@ -63,17 +58,14 @@ public RSAPublicKey getBankE002Key() throws IOException, EbicsException { * Returns the banks authentication key. * The key will be fetched automatically form the bank if needed. * @return the banks authentication key. - * @throws IOException Communication error during key retrieval. - * @throws EbicsException Server error message generated during key retrieval. */ - public RSAPublicKey getBankX002Key() throws IOException, EbicsException { + public RSAPublicKey getBankX002Key() { return user.getPartner().getBank().getX002Key(); } /** * Returns the bank id. * @return the bank id. - * @throws EbicsException */ public String getBankID() throws EbicsException { return user.getPartner().getBank().getHostId(); @@ -136,8 +128,8 @@ public String getSessionParam(String key) { // DATA MEMBERS // -------------------------------------------------------------------- - private EbicsUser user; - private Configuration configuration; + private final EbicsUser user; + private final Configuration configuration; private Product product; - private Map parameters; + private final Map parameters; } diff --git a/src/main/java/org/kopi/ebics/session/OrderType.java b/src/main/java/org/kopi/ebics/session/OrderType.java index d3ef244c..1f107607 100644 --- a/src/main/java/org/kopi/ebics/session/OrderType.java +++ b/src/main/java/org/kopi/ebics/session/OrderType.java @@ -14,18 +14,18 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.session; +import org.kopi.ebics.interfaces.EbicsOrderType; + /** * A BCS order type. * - * @author Pierre Ducroquet * */ -public enum OrderType { +public enum OrderType implements EbicsOrderType { HIA, HAA, HKD, @@ -59,5 +59,11 @@ public enum OrderType { XCT, C52, C53, - C54 + C54; + + @Override + public String getCode() { + return name(); + } + } diff --git a/src/main/java/org/kopi/ebics/session/Product.java b/src/main/java/org/kopi/ebics/session/Product.java index cfcf1751..32aff752 100644 --- a/src/main/java/org/kopi/ebics/session/Product.java +++ b/src/main/java/org/kopi/ebics/session/Product.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.session; @@ -24,7 +23,6 @@ /** * Optional information about the client product. * - * @author Hachani * */ public class Product implements Serializable { diff --git a/src/main/java/org/kopi/ebics/utils/Constants.java b/src/main/java/org/kopi/ebics/utils/Constants.java index f4553aa5..d670bf2e 100644 --- a/src/main/java/org/kopi/ebics/utils/Constants.java +++ b/src/main/java/org/kopi/ebics/utils/Constants.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.utils; @@ -24,7 +23,6 @@ /** * Application constants. * - * @author hachani * */ public interface Constants { diff --git a/src/main/java/org/kopi/ebics/utils/Utils.java b/src/main/java/org/kopi/ebics/utils/Utils.java index 13a7e0b4..bb3ea44e 100644 --- a/src/main/java/org/kopi/ebics/utils/Utils.java +++ b/src/main/java/org/kopi/ebics/utils/Utils.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.utils; @@ -23,7 +22,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; -import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.text.ParseException; import java.util.Date; @@ -34,18 +32,17 @@ import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import org.apache.xml.security.c14n.Canonicalizer; import org.apache.xml.security.utils.IgnoreAllErrorHandler; -import org.apache.xpath.XPathAPI; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.messages.Messages; -import org.w3c.dom.Document; import org.w3c.dom.Node; -import org.w3c.dom.traversal.NodeIterator; +import org.w3c.dom.NodeList; /** @@ -60,6 +57,8 @@ public final class Utils { org.apache.xml.security.Init.init(); } + public static final SecureRandom secureRandom = new SecureRandom(); + private Utils() { } @@ -72,7 +71,7 @@ private Utils() { * * @param toZip the input to be compressed * @return the compressed input data - * @throws IOException compression failed + * @throws EbicsException compression failed */ public static byte[] zip(byte[] toZip) throws EbicsException { @@ -119,23 +118,25 @@ public static byte[] zip(byte[] toZip) throws EbicsException { * be at least 100 bits. * * @return a random nonce. - * @throws EbicsException nonce generation fails. */ - public static byte[] generateNonce() throws EbicsException { - SecureRandom secureRandom; + public static byte[] generateNonce() { + return nextRandomBytes(16); + } - try { - secureRandom = SecureRandom.getInstance("SHA1PRNG"); - return secureRandom.generateSeed(16); - } catch (NoSuchAlgorithmException e) { - throw new EbicsException(e.getMessage()); - } + public static byte[] generateKey() { + return nextRandomBytes(16); + } + + private static byte[] nextRandomBytes(int n) { + byte[] data = new byte[n]; + secureRandom.nextBytes(data); + return data; } /** * Uncompresses a given byte array input. * - *

The Decompression is ensured via Universal compression + * The Decompression is ensured via Universal compression * algorithm (RFC 1950, RFC 1951) As specified in the EBICS * specification (16 Appendix: Standards and references) * @@ -143,35 +144,35 @@ public static byte[] generateNonce() throws EbicsException { * @return the uncompressed data. */ public static byte[] unzip(byte[] zip) throws EbicsException { - Inflater decompressor; - ByteArrayOutputStream output; - byte[] buf; - - decompressor = new Inflater(); - output = new ByteArrayOutputStream(zip.length); - decompressor.setInput(zip); - buf = new byte[1024]; - - while (!decompressor.finished()) { - int count; + Inflater decompressor; + ByteArrayOutputStream output; + byte[] buf; + + decompressor = new Inflater(); + output = new ByteArrayOutputStream(zip.length); + decompressor.setInput(zip); + buf = new byte[1024]; + + while (!decompressor.finished()) { + int count; + + try { + count = decompressor.inflate(buf); + } catch (DataFormatException e) { + throw new EbicsException(e.getMessage()); + } + output.write(buf, 0, count); + } try { - count = decompressor.inflate(buf); - } catch (DataFormatException e) { - throw new EbicsException(e.getMessage()); + output.close(); + } catch (IOException e) { + throw new EbicsException(e.getMessage()); } - output.write(buf, 0, count); - } - - try { - output.close(); - } catch (IOException e) { - throw new EbicsException(e.getMessage()); - } - decompressor.end(); + decompressor.end(); - return output.toByteArray(); + return output.toByteArray(); } /** @@ -186,41 +187,34 @@ public static byte[] unzip(byte[] zip) throws EbicsException { * need to be signed. * *

Thus, All the Elements with the attribute authenticate = true and their - * sub elements are considered for the canonization process. This is performed - * via the {@link XPathAPI#selectNodeIterator(Node, String) selectNodeIterator(Node, String)}. + * sub elements are considered for the canonization process. * * @param input the byte array XML input. * @return the canonized form of the given XML * @throws EbicsException */ public static byte[] canonize(byte[] input) throws EbicsException { - DocumentBuilderFactory factory; - DocumentBuilder builder; - Document document; - NodeIterator iter; - ByteArrayOutputStream output; - Node node; - - try { - factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setValidating(true); - builder = factory.newDocumentBuilder(); - builder.setErrorHandler(new IgnoreAllErrorHandler()); - document = builder.parse(new ByteArrayInputStream(input)); - iter = XPathAPI.selectNodeIterator(document, "//*[@authenticate='true']"); - output = new ByteArrayOutputStream(); - while ((node = iter.nextNode()) != null) { - Canonicalizer canonicalizer; - - canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); - output.write(canonicalizer.canonicalizeSubtree(node)); + try { + var factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(true); + var builder = factory.newDocumentBuilder(); + builder.setErrorHandler(new IgnoreAllErrorHandler()); + var document = builder.parse(new ByteArrayInputStream(input)); + + var output = new ByteArrayOutputStream(); + var nodeList = (NodeList) XPathFactory.newInstance().newXPath() + .evaluate("//*[@authenticate='true']", document, XPathConstants.NODESET); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + var canonicalizer = Canonicalizer.getInstance( + Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); + canonicalizer.canonicalizeSubtree(node, output); + } + return output.toByteArray(); + } catch (Exception e) { + throw new EbicsException(e.getMessage()); } - - return output.toByteArray(); - } catch (Exception e) { - throw new EbicsException(e.getMessage()); - } } /** diff --git a/src/main/java/org/kopi/ebics/xml/DefaultEbicsRootElement.java b/src/main/java/org/kopi/ebics/xml/DefaultEbicsRootElement.java index 83c3a37e..42d69500 100644 --- a/src/main/java/org/kopi/ebics/xml/DefaultEbicsRootElement.java +++ b/src/main/java/org/kopi/ebics/xml/DefaultEbicsRootElement.java @@ -14,40 +14,34 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.math.BigInteger; -import java.security.SecureRandom; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import javax.xml.namespace.QName; +import org.apache.xml.security.c14n.Canonicalizer; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlError; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; -import org.jdom2.Document; -import org.jdom2.JDOMException; -import org.jdom2.input.SAXBuilder; -import org.jdom2.output.Format; -import org.jdom2.output.XMLOutputter; import org.kopi.ebics.exception.EbicsException; +import org.kopi.ebics.interfaces.EbicsOrderType; import org.kopi.ebics.interfaces.EbicsRootElement; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; - +import org.kopi.ebics.utils.Utils; public abstract class DefaultEbicsRootElement implements EbicsRootElement { @@ -55,15 +49,15 @@ public abstract class DefaultEbicsRootElement implements EbicsRootElement { * Constructs a new default EbicsRootElement * @param session the current ebics session */ - public DefaultEbicsRootElement(EbicsSession session) { + protected DefaultEbicsRootElement(EbicsSession session) { this.session = session; - suggestedPrefixes = new HashMap(); + suggestedPrefixes = new HashMap<>(); } /** * Constructs a new default EbicsRootElement */ - public DefaultEbicsRootElement() { + protected DefaultEbicsRootElement() { this(null); } @@ -72,37 +66,29 @@ public DefaultEbicsRootElement() { * @param uri the namespace URI * @param prefix the namespace URI prefix */ - protected static void setSaveSuggestedPrefixes(String uri, String prefix) { + protected void setSaveSuggestedPrefixes(String uri, String prefix) { suggestedPrefixes.put(uri, prefix); } /** - * Prints a pretty XML document using jdom framework. - * @return the pretty XML document. - * @throws EbicsException pretty print fails + * Prints a pretty XML document in Canonical XML. + * @return the canonical XML document. */ - public byte[] prettyPrint() throws EbicsException { - Document document; - XMLOutputter xmlOutputter; - SAXBuilder sxb; - ByteArrayOutputStream output; - - sxb = new SAXBuilder(); - output = new ByteArrayOutputStream(); - xmlOutputter = new XMLOutputter(Format.getPrettyFormat()); - - try { - document = sxb.build(new InputStreamReader(new ByteArrayInputStream(toByteArray()), "UTF-8")); - xmlOutputter.output(document, output); - } catch (JDOMException e) { - throw new EbicsException(e.getMessage()); - } catch (IOException e) { - throw new EbicsException(e.getMessage()); - } - - return output.toByteArray(); + public byte[] prettyPrint() { + try { + Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); + var bos = new ByteArrayOutputStream(); + canon.canonicalize(toByteArray(), bos, true); + return bos.toByteArray(); + } catch (Exception e) { + throw new RuntimeException("Failed to canonicalize XML", e); + } } + public String toPrettyString() { + return new String(prettyPrint(), StandardCharsets.UTF_8); + } + /** * Inserts a schema location to the current ebics root element. * @param namespaceURI the name space URI @@ -115,18 +101,19 @@ public void insertSchemaLocation(String namespaceURI, String prefix, String value) { - XmlCursor cursor; - - cursor = document.newCursor(); - while (cursor.hasNextToken()) { - if (cursor.isStart()) { - cursor.toNextToken(); - cursor.insertAttributeWithValue(new QName(namespaceURI, localPart, prefix), value); - break; - } else { - cursor.toNextToken(); + + try (XmlCursor cursor = document.newCursor()) { + while (cursor.hasNextToken()) { + if (cursor.isStart()) { + cursor.toNextToken(); + cursor.insertAttributeWithValue(new QName(namespaceURI, localPart, prefix), + value); + break; + } else { + cursor.toNextToken(); + } + } } - } } /** @@ -134,8 +121,8 @@ public void insertSchemaLocation(String namespaceURI, * @param type the order type. * @return the generated file name. */ - public static String generateName(OrderType type) { - return type.toString() + new BigInteger(130, new SecureRandom()).toString(32); + public static String generateName(EbicsOrderType type) { + return type.getCode() + new BigInteger(130, Utils.secureRandom).toString(32); } /** @@ -144,7 +131,7 @@ public static String generateName(OrderType type) { * @return the generated file name. */ public static String generateName(String prefix) { - return prefix + new BigInteger(130, new SecureRandom()).toString(32); + return prefix + new BigInteger(130, Utils.secureRandom).toString(32); } @Override @@ -164,51 +151,49 @@ public byte[] toByteArray() { @Override public void addNamespaceDecl(String prefix, String uri) { - XmlCursor cursor; - - cursor = document.newCursor(); - while (cursor.hasNextToken()) { - if (cursor.isStart()) { - cursor.toNextToken(); - cursor.insertNamespace(prefix, uri); - break; - } else { - cursor.toNextToken(); + try (XmlCursor cursor = document.newCursor()) { + while (cursor.hasNextToken()) { + if (cursor.isStart()) { + cursor.toNextToken(); + cursor.insertNamespace(prefix, uri); + break; + } else { + cursor.toNextToken(); + } + } } - } } @Override public void validate() throws EbicsException { - ArrayList validationMessages = new ArrayList(); + List validationMessages = new ArrayList<>(); boolean isValid = document.validate(new XmlOptions().setErrorListener(validationMessages)); if (!isValid) { Iterator iter = validationMessages.iterator(); StringBuilder message = new StringBuilder(); while (iter.hasNext()) { - if (!message.toString().equals("")) { + if (!message.toString().isEmpty()) { message.append(";"); } message.append(iter.next().getMessage()); } - throw new EbicsException(message.toString()); + throw new EbicsException( + "Invalid " + this.getClass().getSimpleName() + ": " + message); } } @Override public void save(OutputStream out) throws EbicsException { - try { - byte[] element; - - element = prettyPrint(); - out.write(element); - out.flush(); - out.close(); - } catch (IOException e) { - throw new EbicsException(e.getMessage()); - } + try { + byte[] element = prettyPrint(); + out.write(element); + out.flush(); + out.close(); + } catch (IOException e) { + throw new EbicsException(e.getMessage()); + } } @Override @@ -222,6 +207,6 @@ public void print(PrintStream stream) { protected XmlObject document; protected EbicsSession session; - private static Map suggestedPrefixes; + private final Map suggestedPrefixes; private static final long serialVersionUID = -3928957097145095177L; } diff --git a/src/main/java/org/kopi/ebics/xml/DefaultResponseElement.java b/src/main/java/org/kopi/ebics/xml/DefaultResponseElement.java index dec95b38..e27bd444 100644 --- a/src/main/java/org/kopi/ebics/xml/DefaultResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/DefaultResponseElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -23,6 +22,7 @@ import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.schema.DocumentFactory; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; @@ -32,7 +32,6 @@ * The DefaultResponseElement is the common element for * all ebics server responses. * - * @author Hachani * */ public abstract class DefaultResponseElement extends DefaultEbicsRootElement { @@ -42,26 +41,28 @@ public abstract class DefaultResponseElement extends DefaultEbicsRootElement { * @param factory the content factory containing the response. * @param name the element name */ - public DefaultResponseElement(ContentFactory factory, String name) { + protected DefaultResponseElement(ContentFactory factory, String name) { this.factory = factory; this.name = name; } /** * Parses the content of a ContentFactory + * * @param factory the content factory + * @return the parsed document * @throws EbicsException parse error */ - protected void parse(ContentFactory factory) throws EbicsException { - try { - document = XmlObject.Factory.parse(factory.getContent()); - } catch (XmlException e) { - throw new EbicsException(e.getMessage()); - } catch (IOException e) { - throw new EbicsException(e.getMessage()); - } + protected T parse(ContentFactory factory, + DocumentFactory documentFactory) throws EbicsException { + try { + var doc = documentFactory.parse(factory.getContent()); + this.document = doc; + return doc; + } catch (XmlException | IOException e) { + throw new EbicsException(e.getMessage()); + } } - /** * Reports the return code to the user. * @throws EbicsException request fails. @@ -85,7 +86,7 @@ public String getName() { // DATA MEMBERS // -------------------------------------------------------------------- - private String name; + private final String name; protected ContentFactory factory; protected ReturnCode returnCode; private static final long serialVersionUID = 4014595046719645090L; diff --git a/src/main/java/org/kopi/ebics/xml/DownloadInitializationRequestElement.java b/src/main/java/org/kopi/ebics/xml/DownloadInitializationRequestElement.java index 78eae9d1..2c102ee8 100644 --- a/src/main/java/org/kopi/ebics/xml/DownloadInitializationRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/DownloadInitializationRequestElement.java @@ -14,33 +14,30 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import java.util.Calendar; -import java.util.Date; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.kopi.ebics.client.EbicsDownloadParams; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header; -import org.kopi.ebics.schema.h003.FDLOrderParamsType; -import org.kopi.ebics.schema.h003.FDLOrderParamsType.DateRange; -import org.kopi.ebics.schema.h003.FileFormatType; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.OrderAttributeType; -import org.kopi.ebics.schema.h003.ParameterDocument.Parameter; -import org.kopi.ebics.schema.h003.ParameterDocument.Parameter.Value; -import org.kopi.ebics.schema.h003.StandardOrderParamsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType.OrderType; -import org.kopi.ebics.schema.h003.StaticHeaderType; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Authentication; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Encryption; -import org.kopi.ebics.schema.h003.StaticHeaderType.Product; +import org.kopi.ebics.interfaces.EbicsOrderType; +import org.kopi.ebics.schema.h005.BTDOrderParamsDocument; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.StandardOrderParamsDocument; +import org.kopi.ebics.schema.h005.StandardOrderParamsType; +import org.kopi.ebics.schema.h005.StaticHeaderOrderDetailsType; +import org.kopi.ebics.schema.h005.StaticHeaderType; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Authentication; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Encryption; +import org.kopi.ebics.schema.h005.StaticHeaderType.Product; import org.kopi.ebics.session.EbicsSession; @@ -48,7 +45,6 @@ * The DInitializationRequestElement is the common initialization * for all ebics downloads. * - * @author Hachani * */ public class DownloadInitializationRequestElement extends InitializationRequestElement { @@ -57,19 +53,24 @@ public class DownloadInitializationRequestElement extends InitializationRequestE * Constructs a new DInitializationRequestElement for downloads initializations. * @param session the current ebics session * @param type the download order type (FDL, HTD, HPD) - * @param startRange the start range download - * @param endRange the end range download - * @throws EbicsException */ public DownloadInitializationRequestElement(EbicsSession session, - org.kopi.ebics.session.OrderType type, - Date startRange, - Date endRange) - throws EbicsException - { + EbicsOrderType type) { + this(session, type, null); + } + + /** + * Constructs a new DInitializationRequestElement for downloads initializations. + * @param session the current ebics session + * @param type the download order type (FDL, HTD, HPD) + * @param downloadParams optional service parameters; with a service name set the request is + * sent as an EBICS 3.0 BTD order, otherwise the legacy order type is kept + */ + public DownloadInitializationRequestElement(EbicsSession session, + EbicsOrderType type, + EbicsDownloadParams downloadParams) { super(session, type, generateName(type)); - this.startRange = startRange; - this.endRange = endRange; + this.downloadParams = downloadParams; } @Override @@ -83,7 +84,6 @@ public void buildInitialization() throws EbicsException { BankPubKeyDigests bankPubKeyDigests; Authentication authentication; Encryption encryption; - OrderType orderType; StaticHeaderOrderDetailsType orderDetails; mutable = EbicsXmlFactory.createMutableHeaderType("Initialisation", null); @@ -95,44 +95,41 @@ public void buildInitialization() throws EbicsException { "http://www.w3.org/2001/04/xmlenc#sha256", decodeHex(session.getUser().getPartner().getBank().getE002Digest())); bankPubKeyDigests = EbicsXmlFactory.createBankPubKeyDigests(authentication, encryption); - orderType = EbicsXmlFactory.createOrderType(type.toString()); - if (type.equals(org.kopi.ebics.session.OrderType.FDL)) { - FDLOrderParamsType fDLOrderParamsType; - FileFormatType fileFormat; - fileFormat = EbicsXmlFactory.createFileFormatType(session.getConfiguration().getLocale().getCountry().toUpperCase(), - session.getSessionParam("FORMAT")); - fDLOrderParamsType = EbicsXmlFactory.createFDLOrderParamsType(fileFormat); - - if (startRange != null && endRange != null) { - DateRange range; - - range = EbicsXmlFactory.createDateRange(startRange, endRange); - fDLOrderParamsType.setDateRange(range); + var type = StaticHeaderOrderDetailsType.AdminOrderType.Factory.newInstance(); + + XmlObject orderParamsType; + SchemaType orderParamsSchema; + + if (downloadParams != null && downloadParams.isBtd()) { + // EBICS 3.0: the business transaction goes into the service block, the admin order + // type is always BTD. + type.setStringValue("BTD"); + orderParamsType = EbicsXmlFactory.createBTDParams( + downloadParams.serviceName(), downloadParams.scope(), downloadParams.option(), + downloadParams.messageName(), downloadParams.messageVersion(), + downloadParams.containerType(), downloadParams.startDate(), + downloadParams.endDate()); + orderParamsSchema = BTDOrderParamsDocument.type; + } else { + type.setStringValue(this.getType()); + StandardOrderParamsType standardOrderParamsType = + EbicsXmlFactory.createStandardOrderParamsType(); + // EbicsDownloadParams guarantees the range is either absent or complete. + if (downloadParams != null && downloadParams.startDate() != null) { + standardOrderParamsType.setDateRange(EbicsXmlFactory.createDateRange( + downloadParams.startDate(), downloadParams.endDate())); + } + orderParamsType = standardOrderParamsType; + orderParamsSchema = StandardOrderParamsDocument.type; } - if (Boolean.getBoolean(session.getSessionParam("TEST"))) { - Parameter parameter; - Value value; - - value = EbicsXmlFactory.createValue("String", "TRUE"); - parameter = EbicsXmlFactory.createParameter("TEST", value); - fDLOrderParamsType.setParameterArray(new Parameter[] {parameter}); - } - orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(session.getUser().getPartner().nextOrderId(), - OrderAttributeType.DZHNN, - orderType, - fDLOrderParamsType); - } else { - StandardOrderParamsType standardOrderParamsType; - - standardOrderParamsType = EbicsXmlFactory.createStandardOrderParamsType(); //FIXME Some banks cannot handle OrderID element in download process. Add parameter in configuration!!! orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(null,//session.getUser().getPartner().nextOrderId(), - OrderAttributeType.DZHNN, - orderType, - standardOrderParamsType); - } + type, + orderParamsType, + orderParamsSchema); + xstatic = EbicsXmlFactory.createStaticHeaderType(session.getBankID(), nonce, session.getUser().getPartner().getPartnerId(), @@ -151,11 +148,6 @@ public void buildInitialization() throws EbicsException { document = EbicsXmlFactory.createEbicsRequestDocument(request); } - // -------------------------------------------------------------------- - // DATA MEMBERS - // -------------------------------------------------------------------- - - private Date startRange; - private Date endRange; + private final EbicsDownloadParams downloadParams; private static final long serialVersionUID = 3776072549761880272L; } diff --git a/src/main/java/org/kopi/ebics/xml/DownloadInitializationResponseElement.java b/src/main/java/org/kopi/ebics/xml/DownloadInitializationResponseElement.java index 00d411a9..6aca018c 100644 --- a/src/main/java/org/kopi/ebics/xml/DownloadInitializationResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/DownloadInitializationResponseElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -23,13 +22,12 @@ import org.kopi.ebics.exception.NoDownloadDataAvailableException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.session.OrderType; +import org.kopi.ebics.interfaces.EbicsOrderType; /** * The DInitializationResponseElement is the response element * for ebics downloads initializations. * - * @author Hachani * */ public class DownloadInitializationResponseElement extends InitializationResponseElement { @@ -41,7 +39,7 @@ public class DownloadInitializationResponseElement extends InitializationRespons * @param name the element name */ public DownloadInitializationResponseElement(ContentFactory factory, - OrderType orderType, + EbicsOrderType orderType, String name) { super(factory, orderType, name); diff --git a/src/main/java/org/kopi/ebics/xml/DownloadTransferRequestElement.java b/src/main/java/org/kopi/ebics/xml/DownloadTransferRequestElement.java index 3c3b9866..eaeaf826 100644 --- a/src/main/java/org/kopi/ebics/xml/DownloadTransferRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/DownloadTransferRequestElement.java @@ -14,26 +14,24 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.StaticHeaderType; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header; -import org.kopi.ebics.schema.h003.MutableHeaderType.SegmentNumber; +import org.kopi.ebics.interfaces.EbicsOrderType; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.StaticHeaderType; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header; +import org.kopi.ebics.schema.h005.MutableHeaderType.SegmentNumber; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; /** * The DTransferRequestElement is the common elements * for all ebics downloads. * - * @author Hachani * */ public class DownloadTransferRequestElement extends TransferRequestElement { @@ -47,7 +45,7 @@ public class DownloadTransferRequestElement extends TransferRequestElement { * @param transactionId the transaction ID */ public DownloadTransferRequestElement(EbicsSession session, - OrderType type, + EbicsOrderType type, int segmentNumber, boolean lastSegment, byte[] transactionId) diff --git a/src/main/java/org/kopi/ebics/xml/DownloadTransferResponseElement.java b/src/main/java/org/kopi/ebics/xml/DownloadTransferResponseElement.java index a98f2567..ed5d8461 100644 --- a/src/main/java/org/kopi/ebics/xml/DownloadTransferResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/DownloadTransferResponseElement.java @@ -14,20 +14,18 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.session.OrderType; +import org.kopi.ebics.interfaces.EbicsOrderType; /** * The DTransferResponseElement is the response element * for all ebics downloads transfers. * - * @author Hachani * */ public class DownloadTransferResponseElement extends TransferResponseElement { @@ -39,7 +37,7 @@ public class DownloadTransferResponseElement extends TransferResponseElement { * @param name the element name. */ public DownloadTransferResponseElement(ContentFactory factory, - OrderType orderType, + EbicsOrderType orderType, String name) { super(factory, name); diff --git a/src/main/java/org/kopi/ebics/xml/EbicsXmlFactory.java b/src/main/java/org/kopi/ebics/xml/EbicsXmlFactory.java index 2cbab508..0e479f99 100644 --- a/src/main/java/org/kopi/ebics/xml/EbicsXmlFactory.java +++ b/src/main/java/org/kopi/ebics/xml/EbicsXmlFactory.java @@ -14,11 +14,12 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.Calendar; import java.util.Date; @@ -27,60 +28,60 @@ import org.apache.xmlbeans.SchemaType; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; -import org.kopi.ebics.schema.h003.AuthenticationPubKeyInfoType; -import org.kopi.ebics.schema.h003.DataEncryptionInfoType.EncryptionPubKeyDigest; -import org.kopi.ebics.schema.h003.DataTransferRequestType; -import org.kopi.ebics.schema.h003.DataTransferRequestType.DataEncryptionInfo; -import org.kopi.ebics.schema.h003.DataTransferRequestType.SignatureData; -import org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument; -import org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body.TransferReceipt; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer.OrderData; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Header; -import org.kopi.ebics.schema.h003.EmptyMutableHeaderType; -import org.kopi.ebics.schema.h003.EncryptionPubKeyInfoType; -import org.kopi.ebics.schema.h003.FDLOrderParamsDocument; -import org.kopi.ebics.schema.h003.FDLOrderParamsType; -import org.kopi.ebics.schema.h003.FDLOrderParamsType.DateRange; -import org.kopi.ebics.schema.h003.FULOrderParamsDocument; -import org.kopi.ebics.schema.h003.FULOrderParamsType; -import org.kopi.ebics.schema.h003.FileFormatType; -import org.kopi.ebics.schema.h003.HIARequestOrderDataDocument; -import org.kopi.ebics.schema.h003.HIARequestOrderDataType; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.MutableHeaderType.SegmentNumber; -import org.kopi.ebics.schema.h003.NoPubKeyDigestsRequestStaticHeaderType; -import org.kopi.ebics.schema.h003.OrderAttributeType; -import org.kopi.ebics.schema.h003.OrderDetailsType; -import org.kopi.ebics.schema.h003.ParameterDocument.Parameter; -import org.kopi.ebics.schema.h003.ParameterDocument.Parameter.Value; -import org.kopi.ebics.schema.h003.ProductElementType; -import org.kopi.ebics.schema.h003.StandardOrderParamsDocument; -import org.kopi.ebics.schema.h003.StandardOrderParamsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType.OrderType; -import org.kopi.ebics.schema.h003.StaticHeaderType; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Authentication; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Encryption; -import org.kopi.ebics.schema.h003.StaticHeaderType.Product; -import org.kopi.ebics.schema.h003.TransactionPhaseType.Enum; -import org.kopi.ebics.schema.h003.UnsecuredRequestStaticHeaderType; -import org.kopi.ebics.schema.s001.OrderSignatureDataType; -import org.kopi.ebics.schema.s001.PubKeyValueType; -import org.kopi.ebics.schema.s001.SignaturePubKeyInfoType; -import org.kopi.ebics.schema.s001.SignaturePubKeyOrderDataDocument; -import org.kopi.ebics.schema.s001.SignaturePubKeyOrderDataType; -import org.kopi.ebics.schema.s001.UserSignatureDataDocument; -import org.kopi.ebics.schema.s001.UserSignatureDataSigBookType; +import org.ebics.s002.OrderSignatureDataType; +import org.ebics.s002.SignaturePubKeyInfoType; +import org.ebics.s002.SignaturePubKeyOrderDataDocument; +import org.ebics.s002.SignaturePubKeyOrderDataType; +import org.ebics.s002.UserSignatureDataDocument; +import org.ebics.s002.UserSignatureDataSigBookType; +import org.kopi.ebics.schema.h005.AuthenticationPubKeyInfoType; +import org.kopi.ebics.schema.h005.BTDParamsType; +import org.kopi.ebics.schema.h005.BTUOrderParamsDocument; +import org.kopi.ebics.schema.h005.BTUParamsType; +import org.kopi.ebics.schema.h005.ContainerStringType; +import org.kopi.ebics.schema.h005.DateType; +import org.kopi.ebics.schema.h005.DataDigestType; +import org.kopi.ebics.schema.h005.DataEncryptionInfoType.EncryptionPubKeyDigest; +import org.kopi.ebics.schema.h005.DataTransferRequestType; +import org.kopi.ebics.schema.h005.DataTransferRequestType.DataEncryptionInfo; +import org.kopi.ebics.schema.h005.DataTransferRequestType.SignatureData; +import org.kopi.ebics.schema.h005.EbicsNoPubKeyDigestsRequestDocument; +import org.kopi.ebics.schema.h005.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body.TransferReceipt; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer.OrderData; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Header; +import org.kopi.ebics.schema.h005.EmptyMutableHeaderType; +import org.kopi.ebics.schema.h005.EncryptionPubKeyInfoType; +import org.kopi.ebics.schema.h005.HIARequestOrderDataDocument; +import org.kopi.ebics.schema.h005.HIARequestOrderDataType; +import org.kopi.ebics.schema.h005.MessageType; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.MutableHeaderType.SegmentNumber; +import org.kopi.ebics.schema.h005.NoPubKeyDigestsRequestStaticHeaderType; +import org.kopi.ebics.schema.h005.OrderDetailsType; +import org.kopi.ebics.schema.h005.ParameterDocument.Parameter; +import org.kopi.ebics.schema.h005.ParameterDocument.Parameter.Value; +import org.kopi.ebics.schema.h005.ProductElementType; +import org.kopi.ebics.schema.h005.PubKeyInfoType; +import org.kopi.ebics.schema.h005.SignatureFlagType; +import org.kopi.ebics.schema.h005.StandardOrderParamsDocument; +import org.kopi.ebics.schema.h005.StandardOrderParamsType; +import org.kopi.ebics.schema.h005.StaticHeaderOrderDetailsType; +import org.kopi.ebics.schema.h005.StaticHeaderType; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Authentication; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Encryption; +import org.kopi.ebics.schema.h005.StaticHeaderType.Product; +import org.kopi.ebics.schema.h005.TransactionPhaseType; +import org.kopi.ebics.schema.h005.UnsecuredRequestStaticHeaderType; import org.kopi.ebics.schema.xmldsig.CanonicalizationMethodType; import org.kopi.ebics.schema.xmldsig.DigestMethodType; +import org.kopi.ebics.schema.xmldsig.KeyValueType; import org.kopi.ebics.schema.xmldsig.RSAKeyValueType; import org.kopi.ebics.schema.xmldsig.ReferenceType; import org.kopi.ebics.schema.xmldsig.SignatureMethodType; @@ -92,1255 +93,1362 @@ import org.kopi.ebics.schema.xmldsig.TransformsType; import org.kopi.ebics.schema.xmldsig.X509DataType; - /** * A factory to produce XML object for EBICS requests. * This factory is based on xmlbeans object generated * from EBICS XML schemas. * * @see XmlObject - * @author hachani * */ -public class EbicsXmlFactory { - - /** - * Creates a new SignedInfoDocument XML object - * @param signedInfo the SignedInfoType element - * @return the SignedInfoDocument XML object - */ - public static SignedInfoDocument createSignedInfoDocument(SignedInfoType signedInfo) { - SignedInfoDocument newSignedInfoDocument = SignedInfoDocument.Factory.newInstance(); - newSignedInfoDocument.setSignedInfo(signedInfo); - - return newSignedInfoDocument; - } - - /** - * Creates a new SignatureType XML object - * @param signedInfo the SignedInfoType element - * @return the SignatureType XML object - */ - public static SignatureType createSignatureType(SignedInfoType signedInfo) { - SignatureType newSignatureType = SignatureType.Factory.newInstance(); - newSignatureType.setSignedInfo(signedInfo); - - return newSignatureType; - } - - /** - * Creates a new SignedInfoType XML object - * @param canonicalizationMethod the CanonicalizationMethod element - * @param signatureMethod the SignatureMethod element - * @param referenceArray the ReferenceType array element - * @return the SignedInfoType XML object - */ - public static SignedInfoType createSignedInfoType(CanonicalizationMethodType canonicalizationMethod, - SignatureMethodType signatureMethod, - ReferenceType[] referenceArray) - { - SignedInfoType newSignedInfoType = SignedInfoType.Factory.newInstance(); - newSignedInfoType.setSignatureMethod(signatureMethod); - newSignedInfoType.setCanonicalizationMethod(canonicalizationMethod); - newSignedInfoType.setReferenceArray(referenceArray); - - return newSignedInfoType; - } - - /** - * Creates a new SignatureValueType XML object - * @param signatureValue the SignatureMethod element - * @return the SignatureValueType XML object - */ - public static SignatureValueType createSignatureValueType(byte[] signatureValue) { - SignatureValueType newSignatureValueType = SignatureValueType.Factory.newInstance(); - newSignatureValueType.setByteArrayValue(signatureValue); - - return newSignatureValueType; - } - - /** - * Creates a new SignatureValueType XML object - * @param algorithm the signature algorithm - * @return the SignatureValueType XML object - */ - public static SignatureMethodType createSignatureMethodType(String algorithm) { - SignatureMethodType newSignatureMethodType = SignatureMethodType.Factory.newInstance(); - newSignatureMethodType.setAlgorithm(algorithm); - - return newSignatureMethodType; - } - - /** - * Creates a new CanonicalizationMethodType XML object - * @param algorithm the canonicalization algorithm - * @return the CanonicalizationMethodType XML object - */ - public static CanonicalizationMethodType createCanonicalizationMethodType(String algorithm) { - CanonicalizationMethodType newCanonicalizationMethodType = CanonicalizationMethodType.Factory.newInstance(); - newCanonicalizationMethodType.setAlgorithm(algorithm); - - return newCanonicalizationMethodType; - } - - /** - * Creates a new ReferenceType XML object - * @param uri the reference uri - * @param transforms the TransformsType element - * @param digestMethod the DigestMethodType element - * @param digestValue the digest value - * @return the ReferenceType XML object - */ - public static ReferenceType createReferenceType(String uri, - TransformsType transforms, - DigestMethodType digestMethod, - byte[] digestValue) - { - ReferenceType newReferenceType = ReferenceType.Factory.newInstance(); - newReferenceType.setURI(uri); - newReferenceType.setTransforms(transforms); - newReferenceType.setDigestMethod(digestMethod); - newReferenceType.setDigestValue(digestValue); - - return newReferenceType; - } - - /** - * Creates a new TransformsType XML object - * @param transformArray the TransformsType array element - * @return the TransformsType XML object - */ - public static TransformsType createTransformsType(TransformType[] transformArray) { - TransformsType newTransformsType = TransformsType.Factory.newInstance(); - newTransformsType.setTransformArray(transformArray); - - return newTransformsType; - } - - /** - * Creates a new TransformType XML object - * @param algorithm the transformation algorithm - * @return the TransformType XML object - */ - public static TransformType createTransformType(String algorithm) { - TransformType newTransformType = TransformType.Factory.newInstance(); - newTransformType.setAlgorithm(algorithm); - - return newTransformType; - } - - /** - * Creates a new DigestMethodType XML object - * @param algorithm the digest method algorithm - * @return the DigestMethodType XML object - */ - public static DigestMethodType createDigestMethodType(String algorithm) { - DigestMethodType newDigestMethodType = DigestMethodType.Factory.newInstance(); - newDigestMethodType.setAlgorithm(algorithm); - - return newDigestMethodType; - } - - //----------------------------------------------------------------------------------------------------------------------------------------------- - - /** - * Creates a new UserSignatureDataDocument XML object - * @param userSignatureData the UserSignatureDataSigBookType element - * @return the UserSignatureDataDocument XML object - */ - public static UserSignatureDataDocument createUserSignatureDataDocument(UserSignatureDataSigBookType userSignatureData) { - UserSignatureDataDocument newUserSignatureDataDocument = UserSignatureDataDocument.Factory.newInstance(); - newUserSignatureDataDocument.setUserSignatureData(userSignatureData); +public final class EbicsXmlFactory { + + /** + * Creates a new SignedInfoDocument XML object + * + * @param signedInfo the SignedInfoType element + * @return the SignedInfoDocument XML object + */ + public static SignedInfoDocument createSignedInfoDocument(SignedInfoType signedInfo) { + SignedInfoDocument newSignedInfoDocument = SignedInfoDocument.Factory.newInstance(); + newSignedInfoDocument.setSignedInfo(signedInfo); + + return newSignedInfoDocument; + } - return newUserSignatureDataDocument; - } + /** + * Creates a new SignatureType XML object + * + * @param signedInfo the SignedInfoType element + * @return the SignatureType XML object + */ + public static SignatureType createSignatureType(SignedInfoType signedInfo) { + SignatureType newSignatureType = SignatureType.Factory.newInstance(); + newSignatureType.setSignedInfo(signedInfo); + + return newSignatureType; + } - /** - * Creates a new UserSignatureDataSigBookType XML object - * @param orderSignatureDataArray the OrderSignatureDataType array element - * @return the UserSignatureDataSigBookType XML object - */ - public static UserSignatureDataSigBookType createUserSignatureDataSigBookType(OrderSignatureDataType[] orderSignatureDataArray) { - UserSignatureDataSigBookType newUserSignatureDataSigBookType = UserSignatureDataSigBookType.Factory.newInstance(); - newUserSignatureDataSigBookType.setOrderSignatureDataArray(orderSignatureDataArray); + /** + * Creates a new SignedInfoType XML object + * + * @param canonicalizationMethod the CanonicalizationMethod element + * @param signatureMethod the SignatureMethod element + * @param referenceArray the ReferenceType array element + * @return the SignedInfoType XML object + */ + public static SignedInfoType createSignedInfoType( + CanonicalizationMethodType canonicalizationMethod, SignatureMethodType signatureMethod, + ReferenceType[] referenceArray) { + SignedInfoType newSignedInfoType = SignedInfoType.Factory.newInstance(); + newSignedInfoType.setSignatureMethod(signatureMethod); + newSignedInfoType.setCanonicalizationMethod(canonicalizationMethod); + newSignedInfoType.setReferenceArray(referenceArray); + + return newSignedInfoType; + } - return newUserSignatureDataSigBookType; - } + /** + * Creates a new SignatureValueType XML object + * + * @param signatureValue the SignatureMethod element + * @return the SignatureValueType XML object + */ + public static SignatureValueType createSignatureValueType(byte[] signatureValue) { + SignatureValueType newSignatureValueType = SignatureValueType.Factory.newInstance(); + newSignatureValueType.setByteArrayValue(signatureValue); + + return newSignatureValueType; + } - /** - * Creates a new OrderSignatureDataType XML object - * @param signatureVersion the signature version - * @param partnerID the partner id - * @param userID the user id - * @param signatureValue the signature value - * @return the OrderSignatureDataType XML object - */ - public static OrderSignatureDataType createOrderSignatureDataType(String signatureVersion, - String partnerID, - String userID, - byte[] signatureValue) - { - OrderSignatureDataType newOrderSignatureDataType = OrderSignatureDataType.Factory.newInstance(); - newOrderSignatureDataType.setSignatureVersion(signatureVersion); - newOrderSignatureDataType.setPartnerID(partnerID); - newOrderSignatureDataType.setUserID(userID); - newOrderSignatureDataType.setSignatureValue(signatureValue); - - return newOrderSignatureDataType; - } + /** + * Creates a new SignatureValueType XML object + * + * @param algorithm the signature algorithm + * @return the SignatureValueType XML object + */ + public static SignatureMethodType createSignatureMethodType(String algorithm) { + SignatureMethodType newSignatureMethodType = SignatureMethodType.Factory.newInstance(); + newSignatureMethodType.setAlgorithm(algorithm); + + return newSignatureMethodType; + } - //----------------------------------------------------------------------------------------------------------------------------------------------- + /** + * Creates a new CanonicalizationMethodType XML object + * + * @param algorithm the canonicalization algorithm + * @return the CanonicalizationMethodType XML object + */ + public static CanonicalizationMethodType createCanonicalizationMethodType(String algorithm) { + CanonicalizationMethodType newCanonicalizationMethodType = CanonicalizationMethodType.Factory.newInstance(); + newCanonicalizationMethodType.setAlgorithm(algorithm); + + return newCanonicalizationMethodType; + } - /** - * Creates a new SignaturePubKeyOrderDataDocument XML object - * @param signaturePubKeyOrderData the SignaturePubKeyOrderDataType element - * @return - */ - public static SignaturePubKeyOrderDataDocument createSignaturePubKeyOrderDataDocument(SignaturePubKeyOrderDataType signaturePubKeyOrderData) { - SignaturePubKeyOrderDataDocument newSignaturePubKeyOrderDataDocument = SignaturePubKeyOrderDataDocument.Factory.newInstance(); - newSignaturePubKeyOrderDataDocument.setSignaturePubKeyOrderData(signaturePubKeyOrderData); + /** + * Creates a new ReferenceType XML object + * + * @param uri the reference uri + * @param transforms the TransformsType element + * @param digestMethod the DigestMethodType element + * @param digestValue the digest value + * @return the ReferenceType XML object + */ + public static ReferenceType createReferenceType(String uri, TransformsType transforms, + DigestMethodType digestMethod, byte[] digestValue) { + ReferenceType newReferenceType = ReferenceType.Factory.newInstance(); + newReferenceType.setURI(uri); + newReferenceType.setTransforms(transforms); + newReferenceType.setDigestMethod(digestMethod); + newReferenceType.setDigestValue(digestValue); + + return newReferenceType; + } - return newSignaturePubKeyOrderDataDocument; - } + /** + * Creates a new TransformsType XML object + * + * @param transformArray the TransformsType array element + * @return the TransformsType XML object + */ + public static TransformsType createTransformsType(TransformType[] transformArray) { + TransformsType newTransformsType = TransformsType.Factory.newInstance(); + newTransformsType.setTransformArray(transformArray); + + return newTransformsType; + } - /** - * Creates a new SignaturePubKeyOrderDataType XML object - * @param signaturePubKeyInfo the SignaturePubKeyInfoType element - * @param partnerId the partner ID - * @param userId the user ID - * @return the SignaturePubKeyOrderDataType XML object - */ - public static SignaturePubKeyOrderDataType createSignaturePubKeyOrderData(SignaturePubKeyInfoType signaturePubKeyInfo, - String partnerId, - String userId) - { - SignaturePubKeyOrderDataType newSignaturePubKeyOrderDataType = SignaturePubKeyOrderDataType.Factory.newInstance(); - newSignaturePubKeyOrderDataType.setSignaturePubKeyInfo(signaturePubKeyInfo); - newSignaturePubKeyOrderDataType.setPartnerID(partnerId); - newSignaturePubKeyOrderDataType.setUserID(userId); - - return newSignaturePubKeyOrderDataType; - } + /** + * Creates a new TransformType XML object + * + * @param algorithm the transformation algorithm + * @return the TransformType XML object + */ + public static TransformType createTransformType(String algorithm) { + TransformType newTransformType = TransformType.Factory.newInstance(); + newTransformType.setAlgorithm(algorithm); + + return newTransformType; + } - /** - * Creates a new SignaturePubKeyInfoType XML object - * @param x509Data the X509DataType element - * @param pubKeyValue PubKeyValueType element - * @param signatureVersion the signature version - * @return the SignaturePubKeyInfoType XML object - */ - public static SignaturePubKeyInfoType createSignaturePubKeyInfoType(X509DataType x509Data, - PubKeyValueType pubKeyValue, - String signatureVersion) - { - SignaturePubKeyInfoType newSignaturePubKeyInfoType = SignaturePubKeyInfoType.Factory.newInstance(); - if (x509Data != null) - newSignaturePubKeyInfoType.setX509Data(x509Data); - newSignaturePubKeyInfoType.setPubKeyValue(pubKeyValue); - newSignaturePubKeyInfoType.setSignatureVersion(signatureVersion); - - return newSignaturePubKeyInfoType; - } + /** + * Creates a new DigestMethodType XML object + * + * @param algorithm the digest method algorithm + * @return the DigestMethodType XML object + */ + public static DigestMethodType createDigestMethodType(String algorithm) { + DigestMethodType newDigestMethodType = DigestMethodType.Factory.newInstance(); + newDigestMethodType.setAlgorithm(algorithm); + + return newDigestMethodType; + } - /** - * Creates a new X509DataType XML object - * @param x509SubjectName the subject name - * @param x509Certificate the certificate - * @return the X509DataType XML object - */ - public static X509DataType createX509DataType(String x509SubjectName, byte[] x509Certificate) { - X509DataType newX509DataType = X509DataType.Factory.newInstance(); - newX509DataType.setX509SubjectNameArray(new String [] {x509SubjectName}); - newX509DataType.setX509CertificateArray(new byte[][] {x509Certificate}); - - return newX509DataType; - } + //----------------------------------------------------------------------------------------------------------------------------------------------- - /** - * Creates a new PubKeyValueType XML object - * @param rsaKeyValue the rsaKeyValue element - * @param timeStamp the current time stamp - * @return the PubKeyValueType XML object - */ - public static PubKeyValueType createPubKeyValueType(RSAKeyValueType rsaKeyValue, Calendar timeStamp) { - PubKeyValueType newPubKeyValueType = PubKeyValueType.Factory.newInstance(); - newPubKeyValueType.setRSAKeyValue(rsaKeyValue); - newPubKeyValueType.setTimeStamp(timeStamp); - - return newPubKeyValueType; - } + /** + * Creates a new UserSignatureDataDocument XML object + * + * @param userSignatureData the UserSignatureDataSigBookType element + * @return the UserSignatureDataDocument XML object + */ + public static UserSignatureDataDocument createUserSignatureDataDocument( + UserSignatureDataSigBookType userSignatureData) { + UserSignatureDataDocument newUserSignatureDataDocument = UserSignatureDataDocument.Factory.newInstance(); + newUserSignatureDataDocument.setUserSignatureData(userSignatureData); - /** - * Creates a new RSAKeyValueType XML object - * @param exponent the public exponent of the public key - * @param modulus the modulus of the public key - * @return the RSAKeyValueType XML object - */ - public static RSAKeyValueType createRSAKeyValueType(byte[] exponent, byte[] modulus) { - RSAKeyValueType newRSAKeyValueType = RSAKeyValueType.Factory.newInstance(); - newRSAKeyValueType.setExponent(exponent); - newRSAKeyValueType.setModulus(modulus); - - return newRSAKeyValueType; - } + return newUserSignatureDataDocument; + } - //----------------------------------------------------------------------------------------------------------------------------------------------- + /** + * Creates a new UserSignatureDataSigBookType XML object + * + * @param orderSignatureDataArray the OrderSignatureDataType array element + * @return the UserSignatureDataSigBookType XML object + */ + public static UserSignatureDataSigBookType createUserSignatureDataSigBookType( + OrderSignatureDataType[] orderSignatureDataArray) { + UserSignatureDataSigBookType newUserSignatureDataSigBookType = UserSignatureDataSigBookType.Factory.newInstance(); + newUserSignatureDataSigBookType.setOrderSignatureDataArray(orderSignatureDataArray); + + return newUserSignatureDataSigBookType; + } - /** - * Creates a new EbicsUnsecuredRequestDocument XML object - * @param ebicsUnsecuredRequest the EbicsUnsecuredRequest element - * @return the EbicsUnsecuredRequestDocument XML object - */ - public static EbicsUnsecuredRequestDocument createEbicsUnsecuredRequestDocument(EbicsUnsecuredRequest ebicsUnsecuredRequest) { - EbicsUnsecuredRequestDocument newEbicsUnsecuredRequestDocument = EbicsUnsecuredRequestDocument.Factory.newInstance(); - newEbicsUnsecuredRequestDocument.setEbicsUnsecuredRequest(ebicsUnsecuredRequest); + /** + * Creates a new OrderSignatureDataType XML object + * + * @param signatureVersion the signature version + * @param partnerID the partner id + * @param userID the user id + * @param signatureValue the signature value + * @return the OrderSignatureDataType XML object + */ + public static OrderSignatureDataType createOrderSignatureDataType(String signatureVersion, + String partnerID, String userID, byte[] signatureValue) { + OrderSignatureDataType newOrderSignatureDataType = OrderSignatureDataType.Factory.newInstance(); + newOrderSignatureDataType.setSignatureVersion(signatureVersion); + newOrderSignatureDataType.setPartnerID(partnerID); + newOrderSignatureDataType.setUserID(userID); + newOrderSignatureDataType.setSignatureValue(signatureValue); + + return newOrderSignatureDataType; + } - return newEbicsUnsecuredRequestDocument; - } + //----------------------------------------------------------------------------------------------------------------------------------------------- - /** - * Creates a new EbicsUnsecuredRequest XML object - * @param header the Header element - * @param body the Body element - * @param revision the current revision - * @param version the current version - * @return the EbicsUnsecuredRequest XML object - */ - public static EbicsUnsecuredRequest createEbicsUnsecuredRequest(Header header, - Body body, - int revision, - String version) - { - EbicsUnsecuredRequest newEbicsUnsecuredRequest = EbicsUnsecuredRequest.Factory.newInstance(); - newEbicsUnsecuredRequest.setHeader(header); - newEbicsUnsecuredRequest.setBody(body); - newEbicsUnsecuredRequest.setRevision(revision); - newEbicsUnsecuredRequest.setVersion(version); - - return newEbicsUnsecuredRequest; - } + /** + * Creates a new SignaturePubKeyOrderDataDocument XML object + * + * @param signaturePubKeyOrderData the SignaturePubKeyOrderDataType element + * @return the SignaturePubKeyOrderDataDocument XML object + */ + public static SignaturePubKeyOrderDataDocument createSignaturePubKeyOrderDataDocument( + SignaturePubKeyOrderDataType signaturePubKeyOrderData) { + SignaturePubKeyOrderDataDocument newSignaturePubKeyOrderDataDocument = SignaturePubKeyOrderDataDocument.Factory.newInstance(); + newSignaturePubKeyOrderDataDocument.setSignaturePubKeyOrderData(signaturePubKeyOrderData); - /** - * Creates a new Header XML object - * @param authenticate should authenticate? - * @param mutable the EmptyMutableHeaderType element - * @param xstatic the UnsecuredRequestStaticHeaderType element - * @return the Header XML object - */ - public static Header createHeader(boolean authenticate, - EmptyMutableHeaderType mutable, - UnsecuredRequestStaticHeaderType xstatic) - { - Header newHeader = Header.Factory.newInstance(); - newHeader.setAuthenticate(authenticate); - newHeader.setMutable(mutable); - newHeader.setStatic(xstatic); - - return newHeader; - } + return newSignaturePubKeyOrderDataDocument; + } - /** - * Creates a new EmptyMutableHeaderType XML object - * @return the EmptyMutableHeaderType XML object - */ - public static EmptyMutableHeaderType createEmptyMutableHeaderType() { - EmptyMutableHeaderType newEmptyMutableHeaderType = EmptyMutableHeaderType.Factory.newInstance(); + /** + * Creates a new SignaturePubKeyOrderDataType XML object + * + * @param signaturePubKeyInfo the SignaturePubKeyInfoType element + * @param partnerId the partner ID + * @param userId the user ID + * @return the SignaturePubKeyOrderDataType XML object + */ + public static SignaturePubKeyOrderDataType createSignaturePubKeyOrderData( + SignaturePubKeyInfoType signaturePubKeyInfo, String partnerId, String userId) { + SignaturePubKeyOrderDataType newSignaturePubKeyOrderDataType = SignaturePubKeyOrderDataType.Factory.newInstance(); + newSignaturePubKeyOrderDataType.setSignaturePubKeyInfo(signaturePubKeyInfo); + newSignaturePubKeyOrderDataType.setPartnerID(partnerId); + newSignaturePubKeyOrderDataType.setUserID(userId); + + return newSignaturePubKeyOrderDataType; + } - return newEmptyMutableHeaderType; - } + /** + * Creates a new SignaturePubKeyInfoType XML object + * + * @param x509Data the X509DataType element + * @param pubKeyValue PubKeyValueType element + * @param signatureVersion the signature version + * @return the SignaturePubKeyInfoType XML object + */ + public static SignaturePubKeyInfoType createSignaturePubKeyInfoType(X509DataType x509Data, + KeyValueType keyValueType, + String signatureVersion) { + SignaturePubKeyInfoType newSignaturePubKeyInfoType = SignaturePubKeyInfoType.Factory.newInstance(); + if (x509Data != null) { + newSignaturePubKeyInfoType.setX509Data(x509Data); + } + //newSignaturePubKeyInfoType.setPubKeyValue(pubKeyValue); + newSignaturePubKeyInfoType.setSignatureVersion(signatureVersion); - /** - * Creates a new EmptyMutableHeaderType XML object - * @param hostId the host ID - * @param partnerId the partner ID - * @param userId the user ID - * @param product the ProductElementType element - * @param orderDetails the OrderDetailsType element - * @param securityMedium the security medium - * @return the EmptyMutableHeaderType XML object - */ - public static UnsecuredRequestStaticHeaderType createUnsecuredRequestStaticHeaderType(String hostId, - String partnerId, - String userId, - ProductElementType product, - OrderDetailsType orderDetails, - String securityMedium) - { - UnsecuredRequestStaticHeaderType newUnsecuredRequestStaticHeaderType = UnsecuredRequestStaticHeaderType.Factory.newInstance(); - newUnsecuredRequestStaticHeaderType.setHostID(hostId); - newUnsecuredRequestStaticHeaderType.setPartnerID(partnerId); - newUnsecuredRequestStaticHeaderType.setUserID(userId); - newUnsecuredRequestStaticHeaderType.setProduct(product); - newUnsecuredRequestStaticHeaderType.setOrderDetails(orderDetails); - newUnsecuredRequestStaticHeaderType.setSecurityMedium(securityMedium); - - return newUnsecuredRequestStaticHeaderType; - } + return newSignaturePubKeyInfoType; + } - /** - * Creates a new ProductElementType XML object - * @param language the language - * @param product the product name - * @return the ProductElementType XML object - */ - public static ProductElementType creatProductElementType(String language, String product) { - ProductElementType newProductElementType = ProductElementType.Factory.newInstance(); - newProductElementType.setLanguage(language); - newProductElementType.setStringValue(product); - - return newProductElementType; - } + /** + * Creates a new X509DataType XML object + * + * @param x509SubjectName the subject name + * @param x509Certificate the certificate + * @return the X509DataType XML object + */ + public static X509DataType createX509DataType(String x509SubjectName, byte[] x509Certificate) { + X509DataType newX509DataType = X509DataType.Factory.newInstance(); + newX509DataType.setX509SubjectNameArray(new String[] { x509SubjectName }); + newX509DataType.setX509CertificateArray(new byte[][] { x509Certificate }); + + return newX509DataType; + } - /** - * Creates a new OrderDetailsType XML object - * @param orderAttribute the order attribute - * @param orderId the order ID - * @param orderType the order type - * @return the OrderDetailsType XML object - */ - @SuppressWarnings("deprecation") - public static OrderDetailsType createOrderDetailsType(String orderAttribute, String orderId, String orderType) { - OrderDetailsType newOrderDetailsType = OrderDetailsType.Factory.newInstance(); - newOrderDetailsType.setOrderAttribute(orderAttribute); - if (orderId != null) { - newOrderDetailsType.setOrderID(orderId); - } - newOrderDetailsType.setOrderType(orderType); - - return newOrderDetailsType; - } + /** + * Creates a new RSAKeyValueType XML object + * + * @param exponent the public exponent of the public key + * @param modulus the modulus of the public key + * @return the RSAKeyValueType XML object + */ + public static RSAKeyValueType createRSAKeyValueType(byte[] exponent, byte[] modulus) { + RSAKeyValueType newRSAKeyValueType = RSAKeyValueType.Factory.newInstance(); + newRSAKeyValueType.setExponent(exponent); + newRSAKeyValueType.setModulus(modulus); + + return newRSAKeyValueType; + } - /** - * Creates a new Body XML object - * @param dataTransfer the DataTransfer element - * @return the Body XML object - */ - public static Body createBody(DataTransfer dataTransfer) { - Body newBody = Body.Factory.newInstance(); - newBody.setDataTransfer(dataTransfer); + //----------------------------------------------------------------------------------------------------------------------------------------------- - return newBody; - } + /** + * Creates a new EbicsUnsecuredRequestDocument XML object + * + * @param ebicsUnsecuredRequest the EbicsUnsecuredRequest element + * @return the EbicsUnsecuredRequestDocument XML object + */ + public static EbicsUnsecuredRequestDocument createEbicsUnsecuredRequestDocument( + EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest ebicsUnsecuredRequest) { + EbicsUnsecuredRequestDocument newEbicsUnsecuredRequestDocument = EbicsUnsecuredRequestDocument.Factory.newInstance(); + newEbicsUnsecuredRequestDocument.setEbicsUnsecuredRequest(ebicsUnsecuredRequest); - /** - * Creates a new DataTransfer XML object - * @param orderData the OrderData element - * @return the DataTransfer XML object - */ - public static DataTransfer createDataTransfer(OrderData orderData) { - DataTransfer newDataTransfer = DataTransfer.Factory.newInstance(); - newDataTransfer.setOrderData(orderData); + return newEbicsUnsecuredRequestDocument; + } - return newDataTransfer; - } + /** + * Creates a new EbicsUnsecuredRequest XML object + * + * @param header the Header element + * @param body the Body element + * @param revision the current revision + * @param version the current version + * @return the EbicsUnsecuredRequest XML object + */ + public static EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest createEbicsUnsecuredRequest( + EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Header header, + EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body body, int revision, + String version) { + EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest newEbicsUnsecuredRequest = EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Factory.newInstance(); + newEbicsUnsecuredRequest.setHeader(header); + newEbicsUnsecuredRequest.setBody(body); + newEbicsUnsecuredRequest.setRevision(revision); + newEbicsUnsecuredRequest.setVersion(version); + + return newEbicsUnsecuredRequest; + } - /** - * Creates a new OrderData XML object - * @param orderData the order data as byte array - * @return the OrderData XML object - */ - public static OrderData createOrderData(byte[] orderData) { - OrderData newOrderData = OrderData.Factory.newInstance(); - newOrderData.setByteArrayValue(orderData); + /** + * Creates a new Header XML object + * + * @param authenticate should authenticate? + * @param mutable the EmptyMutableHeaderType element + * @param xstatic the UnsecuredRequestStaticHeaderType element + * @return the Header XML object + */ + public static Header createHeader(boolean authenticate, EmptyMutableHeaderType mutable, + UnsecuredRequestStaticHeaderType xstatic) { + Header newHeader = Header.Factory.newInstance(); + newHeader.setAuthenticate(authenticate); + newHeader.setMutable(mutable); + newHeader.setStatic(xstatic); + + return newHeader; + } - return newOrderData; - } + /** + * Creates a new EmptyMutableHeaderType XML object + * + * @return the EmptyMutableHeaderType XML object + */ + public static EmptyMutableHeaderType createEmptyMutableHeaderType() { + return EmptyMutableHeaderType.Factory.newInstance(); + } - //----------------------------------------------------------------------------------------------------------------------------------------------- + /** + * Creates a new EmptyMutableHeaderType XML object + * + * @param hostId the host ID + * @param partnerId the partner ID + * @param userId the user ID + * @param product the ProductElementType element + * @param orderDetails the OrderDetailsType element + * @param securityMedium the security medium + * @return the EmptyMutableHeaderType XML object + */ + public static UnsecuredRequestStaticHeaderType createUnsecuredRequestStaticHeaderType( + String hostId, String partnerId, String userId, ProductElementType product, + OrderDetailsType orderDetails, String securityMedium) { + UnsecuredRequestStaticHeaderType newUnsecuredRequestStaticHeaderType = UnsecuredRequestStaticHeaderType.Factory.newInstance(); + newUnsecuredRequestStaticHeaderType.setHostID(hostId); + newUnsecuredRequestStaticHeaderType.setPartnerID(partnerId); + newUnsecuredRequestStaticHeaderType.setUserID(userId); + newUnsecuredRequestStaticHeaderType.setProduct(product); + newUnsecuredRequestStaticHeaderType.setOrderDetails(orderDetails); + newUnsecuredRequestStaticHeaderType.setSecurityMedium(securityMedium); + + return newUnsecuredRequestStaticHeaderType; + } - /** - * Creates a new HIARequestOrderDataDocument XML object - * @param hiaRequestOrderData the HIARequestOrderDataType element - * @return the HIARequestOrderDataDocument XML object - */ - public static HIARequestOrderDataDocument createHIARequestOrderDataDocument(HIARequestOrderDataType hiaRequestOrderData) { - HIARequestOrderDataDocument newHIARequestOrderDataDocument = HIARequestOrderDataDocument.Factory.newInstance(); - newHIARequestOrderDataDocument.setHIARequestOrderData(hiaRequestOrderData); + /** + * Creates a new ProductElementType XML object + * + * @param language the language + * @param product the product name + * @return the ProductElementType XML object + */ + public static ProductElementType creatProductElementType(String language, String product) { + ProductElementType newProductElementType = ProductElementType.Factory.newInstance(); + newProductElementType.setLanguage(language); + newProductElementType.setStringValue(product); + + return newProductElementType; + } - return newHIARequestOrderDataDocument; - } + /** + * Creates a new OrderDetailsType XML object + * + * @param orderType the order type + * @return the OrderDetailsType XML object + */ + + public static OrderDetailsType createOrderDetailsType(String orderType) { + OrderDetailsType newOrderDetailsType = OrderDetailsType.Factory.newInstance(); + newOrderDetailsType.setAdminOrderType(orderType); + return newOrderDetailsType; + } - /** - * Creates a new HIARequestOrderDataType XML object - * @param authenticationPubKeyInfo the AuthenticationPubKeyInfoType element - * @param encryptionPubKeyInfo the EncryptionPubKeyInfoType element - * @param partnerId the partner ID - * @param userId the user ID - * @return the HIARequestOrderDataType XML object - */ - public static HIARequestOrderDataType createHIARequestOrderDataType(AuthenticationPubKeyInfoType authenticationPubKeyInfo, - EncryptionPubKeyInfoType encryptionPubKeyInfo, - String partnerId, - String userId) - { - HIARequestOrderDataType newHIARequestOrderDataType = HIARequestOrderDataType.Factory.newInstance(); - newHIARequestOrderDataType.setAuthenticationPubKeyInfo(authenticationPubKeyInfo); - newHIARequestOrderDataType.setEncryptionPubKeyInfo(encryptionPubKeyInfo); - newHIARequestOrderDataType.setPartnerID(partnerId); - newHIARequestOrderDataType.setUserID(userId); - - return newHIARequestOrderDataType; - } + /** + * Creates a new Body XML object + * + * @param dataTransfer the DataTransfer element + * @return the Body XML object + */ + public static Body createBody(DataTransfer dataTransfer) { + Body newBody = Body.Factory.newInstance(); + newBody.setDataTransfer(dataTransfer); + + return newBody; + } - /** - * Creates a new AuthenticationPubKeyInfoType XML object - * @param authenticationVersion the authentication version - * @param pubKeyValue the org.kopi.ebics.schema.h003.PubKeyValueType element - * @param x509Data the X509DataType element - * @return the AuthenticationPubKeyInfoType XML object - */ - public static AuthenticationPubKeyInfoType createAuthenticationPubKeyInfoType(String authenticationVersion, - org.kopi.ebics.schema.h003.PubKeyValueType pubKeyValue, - X509DataType x509Data) - { - AuthenticationPubKeyInfoType newAuthenticationPubKeyInfoType = AuthenticationPubKeyInfoType.Factory.newInstance(); - newAuthenticationPubKeyInfoType.setAuthenticationVersion(authenticationVersion); - newAuthenticationPubKeyInfoType.setPubKeyValue(pubKeyValue); - if (x509Data != null) - newAuthenticationPubKeyInfoType.setX509Data(x509Data); - - return newAuthenticationPubKeyInfoType; - } + /** + * Creates a new DataTransfer XML object + * + * @param orderData the OrderData element + * @return the DataTransfer XML object + */ + public static DataTransfer createDataTransfer(OrderData orderData) { + DataTransfer newDataTransfer = DataTransfer.Factory.newInstance(); + newDataTransfer.setOrderData(orderData); + + return newDataTransfer; + } - /** - * Creates a new EncryptionPubKeyInfoType XML object - * @param encryptionVersion the encryption version - * @param pubKeyValue the org.kopi.ebics.schema.h003.PubKeyValueType element - * @param x509Data the X509DataType element - * @return the EncryptionPubKeyInfoType XML object - */ - public static EncryptionPubKeyInfoType createEncryptionPubKeyInfoType(String encryptionVersion, - org.kopi.ebics.schema.h003.PubKeyValueType pubKeyValue, - X509DataType x509Data) - { - EncryptionPubKeyInfoType newEncryptionPubKeyInfoType = EncryptionPubKeyInfoType.Factory.newInstance(); - newEncryptionPubKeyInfoType.setEncryptionVersion(encryptionVersion); - newEncryptionPubKeyInfoType.setPubKeyValue(pubKeyValue); - if (x509Data != null) - newEncryptionPubKeyInfoType.setX509Data(x509Data); - - return newEncryptionPubKeyInfoType; - } + /** + * Creates a new OrderData XML object + * + * @param orderData the order data as byte array + * @return the OrderData XML object + */ + public static OrderData createOrderData(byte[] orderData) { + OrderData newOrderData = OrderData.Factory.newInstance(); + newOrderData.setByteArrayValue(orderData); + + return newOrderData; + } - /** - * Creates a new org.kopi.ebics.schema.h003.PubKeyValueType XML object - * @param rsaKeyValue the RSAKeyValueType element - * @param timeStamp the current time stamp - * @return the org.kopi.ebics.schema.h003.PubKeyValueType XML object - */ - public static org.kopi.ebics.schema.h003.PubKeyValueType createH003PubKeyValueType(RSAKeyValueType rsaKeyValue, Calendar timeStamp) { - org.kopi.ebics.schema.h003.PubKeyValueType newPubKeyValueType = org.kopi.ebics.schema.h003.PubKeyValueType.Factory.newInstance(); - newPubKeyValueType.setRSAKeyValue(rsaKeyValue); - newPubKeyValueType.setTimeStamp(timeStamp); - - return newPubKeyValueType; - } + //----------------------------------------------------------------------------------------------------------------------------------------------- - //----------------------------------------------------------------------------------------------------------------------------------------------- - - /** - * Creates a new EbicsNoPubKeyDigestsRequest XML object - * @param revision the default revision - * @param version the default version - * @param header the org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header element - * @param body the org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body element - * @return the EbicsNoPubKeyDigestsRequest XML object - */ - public static EbicsNoPubKeyDigestsRequest createEbicsNoPubKeyDigestsRequest(int revision, - String version, - org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header header, - org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body body) - { - EbicsNoPubKeyDigestsRequest newEbicsNoPubKeyDigestsRequest = EbicsNoPubKeyDigestsRequest.Factory.newInstance(); - newEbicsNoPubKeyDigestsRequest.setRevision(revision); - newEbicsNoPubKeyDigestsRequest.setVersion(version); - newEbicsNoPubKeyDigestsRequest.setHeader(header); - newEbicsNoPubKeyDigestsRequest.setBody(body); - - return newEbicsNoPubKeyDigestsRequest; - } + /** + * Creates a new HIARequestOrderDataDocument XML object + * + * @param hiaRequestOrderData the HIARequestOrderDataType element + * @return the HIARequestOrderDataDocument XML object + */ + public static HIARequestOrderDataDocument createHIARequestOrderDataDocument( + HIARequestOrderDataType hiaRequestOrderData) { + HIARequestOrderDataDocument newHIARequestOrderDataDocument = HIARequestOrderDataDocument.Factory.newInstance(); + newHIARequestOrderDataDocument.setHIARequestOrderData(hiaRequestOrderData); - /** - * Creates a new org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header XML object - * @param authenticate should authenticate? - * @param mutable the EmptyMutableHeaderType element - * @param xstatic the NoPubKeyDigestsRequestStaticHeaderType element - * @return the org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header XML object - */ - public static org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header createDigestsRequestHeader(boolean authenticate, - EmptyMutableHeaderType mutable, - NoPubKeyDigestsRequestStaticHeaderType xstatic) - { - org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header newHeader = org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header.Factory.newInstance(); - newHeader.setAuthenticate(authenticate); - newHeader.setMutable(mutable); - newHeader.setStatic(xstatic); - - return newHeader; - } + return newHIARequestOrderDataDocument; + } - /** - * Creates a new NoPubKeyDigestsRequestStaticHeaderType XML object - * @param hostId the host ID - * @param nonce a random nonce - * @param timestamp the current time stamp - * @param partnerId the partner ID - * @param userId the user ID - * @param product the ProductElementType element - * @param orderDetails the OrderDetailsType element - * @param securityMedium the user security medium - * @return - */ - public static NoPubKeyDigestsRequestStaticHeaderType createNoPubKeyDigestsRequestStaticHeaderType(String hostId, - byte[] nonce, - Calendar timestamp, - String partnerId, - String userId, - ProductElementType product, - OrderDetailsType orderDetails, - String securityMedium) - { - NoPubKeyDigestsRequestStaticHeaderType newNoPubKeyDigestsRequestStaticHeaderType = NoPubKeyDigestsRequestStaticHeaderType.Factory.newInstance(); - newNoPubKeyDigestsRequestStaticHeaderType.setHostID(hostId); - newNoPubKeyDigestsRequestStaticHeaderType.setNonce(nonce); - newNoPubKeyDigestsRequestStaticHeaderType.setTimestamp(timestamp); - newNoPubKeyDigestsRequestStaticHeaderType.setPartnerID(partnerId); - newNoPubKeyDigestsRequestStaticHeaderType.setUserID(userId); - newNoPubKeyDigestsRequestStaticHeaderType.setProduct(product); - newNoPubKeyDigestsRequestStaticHeaderType.setOrderDetails(orderDetails); - newNoPubKeyDigestsRequestStaticHeaderType.setSecurityMedium(securityMedium); - - return newNoPubKeyDigestsRequestStaticHeaderType; - } + /** + * Creates a new HIARequestOrderDataType XML object + * + * @param authenticationPubKeyInfo the AuthenticationPubKeyInfoType element + * @param encryptionPubKeyInfo the EncryptionPubKeyInfoType element + * @param partnerId the partner ID + * @param userId the user ID + * @return the HIARequestOrderDataType XML object + */ + public static HIARequestOrderDataType createHIARequestOrderDataType( + AuthenticationPubKeyInfoType authenticationPubKeyInfo, + EncryptionPubKeyInfoType encryptionPubKeyInfo, String partnerId, String userId) { + HIARequestOrderDataType newHIARequestOrderDataType = HIARequestOrderDataType.Factory.newInstance(); + newHIARequestOrderDataType.setAuthenticationPubKeyInfo(authenticationPubKeyInfo); + newHIARequestOrderDataType.setEncryptionPubKeyInfo(encryptionPubKeyInfo); + newHIARequestOrderDataType.setPartnerID(partnerId); + newHIARequestOrderDataType.setUserID(userId); + + return newHIARequestOrderDataType; + } - /** - * Creates a new org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body XML object - * @return the org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body XML object - */ - public static org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body createDigestsRequestBody() { - org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body newBody = org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body.Factory.newInstance(); + /** + * Creates a new AuthenticationPubKeyInfoType XML object + * + * @param authenticationVersion the authentication version + * //@param pubKeyValue the PubKeyValueType element + * @param x509Data the X509DataType element + * @return the AuthenticationPubKeyInfoType XML object + */ + public static AuthenticationPubKeyInfoType createAuthenticationPubKeyInfoType( + String authenticationVersion, X509DataType x509Data) { + AuthenticationPubKeyInfoType type = AuthenticationPubKeyInfoType.Factory.newInstance(); + type.setAuthenticationVersion(authenticationVersion); + type.setX509Data(x509Data); + return type; + } - return newBody; - } + //----------------------------------------------------------------------------------------------------------------------------------------------- + + /** + * Creates a new EbicsNoPubKeyDigestsRequest XML object + * + * @param revision the default revision + * @param version the default version + * @param header the EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header element + * @param body the EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body element + * @return the EbicsNoPubKeyDigestsRequest XML object + */ + public static EbicsNoPubKeyDigestsRequest createEbicsNoPubKeyDigestsRequest(int revision, + String version, + EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header header, + EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body body) { + EbicsNoPubKeyDigestsRequest newEbicsNoPubKeyDigestsRequest = EbicsNoPubKeyDigestsRequest.Factory.newInstance(); + newEbicsNoPubKeyDigestsRequest.setRevision(revision); + newEbicsNoPubKeyDigestsRequest.setVersion(version); + newEbicsNoPubKeyDigestsRequest.setHeader(header); + newEbicsNoPubKeyDigestsRequest.setBody(body); + + return newEbicsNoPubKeyDigestsRequest; + } - /** - * Creates a new EbicsNoPubKeyDigestsRequestDocument XML object - * @param ebicsNoPubKeyDigestsRequest the EbicsNoPubKeyDigestsRequest element - * @return the EbicsNoPubKeyDigestsRequestDocument XML object - */ - public static EbicsNoPubKeyDigestsRequestDocument createEbicsNoPubKeyDigestsRequestDocument(EbicsNoPubKeyDigestsRequest ebicsNoPubKeyDigestsRequest) { - EbicsNoPubKeyDigestsRequestDocument newEbicsNoPubKeyDigestsRequestDocument = EbicsNoPubKeyDigestsRequestDocument.Factory.newInstance(); - newEbicsNoPubKeyDigestsRequestDocument.setEbicsNoPubKeyDigestsRequest(ebicsNoPubKeyDigestsRequest); + /** + * Creates a new EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header XML object + * + * @param authenticate should authenticate? + * @param mutable the EmptyMutableHeaderType element + * @param xstatic the NoPubKeyDigestsRequestStaticHeaderType element + * @return the EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header XML object + */ + public static EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header createDigestsRequestHeader( + boolean authenticate, EmptyMutableHeaderType mutable, + NoPubKeyDigestsRequestStaticHeaderType xstatic) { + EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header newHeader = EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header.Factory.newInstance(); + newHeader.setAuthenticate(authenticate); + newHeader.setMutable(mutable); + newHeader.setStatic(xstatic); + + return newHeader; + } - return newEbicsNoPubKeyDigestsRequestDocument; - } + /** + * Creates a new NoPubKeyDigestsRequestStaticHeaderType XML object + * + * @param hostId the host ID + * @param nonce a random nonce + * @param timestamp the current time stamp + * @param partnerId the partner ID + * @param userId the user ID + * @param product the ProductElementType element + * @param orderDetails the OrderDetailsType element + * @param securityMedium the user security medium + * @return NoPubKeyDigestsRequestStaticHeaderType + */ + public static NoPubKeyDigestsRequestStaticHeaderType createNoPubKeyDigestsRequestStaticHeaderType( + String hostId, byte[] nonce, Calendar timestamp, String partnerId, String userId, + ProductElementType product, OrderDetailsType orderDetails, String securityMedium) { + NoPubKeyDigestsRequestStaticHeaderType newNoPubKeyDigestsRequestStaticHeaderType = NoPubKeyDigestsRequestStaticHeaderType.Factory.newInstance(); + newNoPubKeyDigestsRequestStaticHeaderType.setHostID(hostId); + newNoPubKeyDigestsRequestStaticHeaderType.setNonce(nonce); + newNoPubKeyDigestsRequestStaticHeaderType.setTimestamp(timestamp); + newNoPubKeyDigestsRequestStaticHeaderType.setPartnerID(partnerId); + newNoPubKeyDigestsRequestStaticHeaderType.setUserID(userId); + newNoPubKeyDigestsRequestStaticHeaderType.setProduct(product); + newNoPubKeyDigestsRequestStaticHeaderType.setOrderDetails(orderDetails); + newNoPubKeyDigestsRequestStaticHeaderType.setSecurityMedium(securityMedium); + + return newNoPubKeyDigestsRequestStaticHeaderType; + } - //----------------------------------------------------------------------------------------------------------------------------------------------- + /** + * Creates a new EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body XML object + * + * @return the EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body XML object + */ + public static EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body createDigestsRequestBody() { + return EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body.Factory.newInstance(); + } - /** - * Creates a new EbicsRequestDocument XML object - * @param ebicsRequest the EbicsRequest element - * @return the EbicsRequestDocument XML object - */ - public static EbicsRequestDocument createEbicsRequestDocument(EbicsRequest ebicsRequest) { - EbicsRequestDocument newEbicsRequestDocument = EbicsRequestDocument.Factory.newInstance(); - newEbicsRequestDocument.setEbicsRequest(ebicsRequest); + /** + * Creates a new EbicsNoPubKeyDigestsRequestDocument XML object + * + * @param ebicsNoPubKeyDigestsRequest the EbicsNoPubKeyDigestsRequest element + * @return the EbicsNoPubKeyDigestsRequestDocument XML object + */ + public static EbicsNoPubKeyDigestsRequestDocument createEbicsNoPubKeyDigestsRequestDocument( + EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest ebicsNoPubKeyDigestsRequest) { + EbicsNoPubKeyDigestsRequestDocument newEbicsNoPubKeyDigestsRequestDocument = EbicsNoPubKeyDigestsRequestDocument.Factory.newInstance(); + newEbicsNoPubKeyDigestsRequestDocument.setEbicsNoPubKeyDigestsRequest( + ebicsNoPubKeyDigestsRequest); + + return newEbicsNoPubKeyDigestsRequestDocument; + } - return newEbicsRequestDocument; - } + //----------------------------------------------------------------------------------------------------------------------------------------------- - /** - * Creates a new EbicsRequest XML object - * @param revision the default revision - * @param version the default version - * @param header the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header element - * @param body the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body element - * @return the EbicsRequest XML object - */ - public static EbicsRequest createEbicsRequest(int revision, - String version, - org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header header, - org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body body) - { - EbicsRequest newEbicsRequest = EbicsRequest.Factory.newInstance(); - newEbicsRequest.setRevision(revision); - newEbicsRequest.setVersion(version); - newEbicsRequest.setHeader(header); - newEbicsRequest.setBody(body); - - return newEbicsRequest; - } + /** + * Creates a new EbicsRequestDocument XML object + * + * @param ebicsRequest the EbicsRequest element + * @return the EbicsRequestDocument XML object + */ + public static EbicsRequestDocument createEbicsRequestDocument(EbicsRequest ebicsRequest) { + EbicsRequestDocument newEbicsRequestDocument = EbicsRequestDocument.Factory.newInstance(); + newEbicsRequestDocument.setEbicsRequest(ebicsRequest); - /** - * Creates a new org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header XML object - * @param authenticate should authenticate? - * @param mutable the MutableHeaderType element - * @param xstatic the StaticHeaderType element - * @return the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header XML object - */ - public static org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header createEbicsRequestHeader(boolean authenticate, - MutableHeaderType mutable, - StaticHeaderType xstatic) - { - org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header newHeader = org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header.Factory.newInstance(); - newHeader.setAuthenticate(authenticate); - newHeader.setMutable(mutable); - newHeader.setStatic(xstatic); - - return newHeader; - } + return newEbicsRequestDocument; + } - /** - * Creates a new MutableHeaderType XML object - * @param transactionPhase the transaction phase - * @param segmentNumber the SegmentNumber element - * @return the MutableHeaderType XML object - */ - public static MutableHeaderType createMutableHeaderType(String transactionPhase, SegmentNumber segmentNumber) { - MutableHeaderType newMutableHeaderType = MutableHeaderType.Factory.newInstance(); - newMutableHeaderType.setTransactionPhase(Enum.forString(transactionPhase)); - if (segmentNumber != null) { - newMutableHeaderType.setSegmentNumber(segmentNumber); + /** + * Creates a new EbicsRequest XML object + * + * @param revision the default revision + * @param version the default version + * @param header the EbicsRequestDocument.EbicsRequest.Header element + * @param body the EbicsRequestDocument.EbicsRequest.Body element + * @return the EbicsRequest XML object + */ + public static EbicsRequest createEbicsRequest(int revision, String version, + EbicsRequestDocument.EbicsRequest.Header header, + EbicsRequestDocument.EbicsRequest.Body body) { + EbicsRequest newEbicsRequest = EbicsRequest.Factory.newInstance(); + newEbicsRequest.setRevision(revision); + newEbicsRequest.setVersion(version); + newEbicsRequest.setHeader(header); + newEbicsRequest.setBody(body); + + return newEbicsRequest; } - return newMutableHeaderType; - } + /** + * Creates a new EbicsRequestDocument.EbicsRequest.Header XML object + * + * @param authenticate should authenticate? + * @param mutable the MutableHeaderType element + * @param xstatic the StaticHeaderType element + * @return the EbicsRequestDocument.EbicsRequest.Header XML object + */ + public static EbicsRequestDocument.EbicsRequest.Header createEbicsRequestHeader( + boolean authenticate, MutableHeaderType mutable, StaticHeaderType xstatic) { + EbicsRequestDocument.EbicsRequest.Header newHeader = EbicsRequestDocument.EbicsRequest.Header.Factory.newInstance(); + newHeader.setAuthenticate(authenticate); + newHeader.setMutable(mutable); + newHeader.setStatic(xstatic); + + return newHeader; + } - /** - * Creates a new SegmentNumber XML object - * @param segmentNumber the segment number - * @param lastSegment is the last segment? - * @return the SegmentNumber XML object - */ - public static SegmentNumber createSegmentNumber(long segmentNumber, boolean lastSegment) { - SegmentNumber newSegmentNumber = SegmentNumber.Factory.newInstance(); - newSegmentNumber.setLongValue(segmentNumber); - newSegmentNumber.setLastSegment(lastSegment); - - return newSegmentNumber; - } + /** + * Creates a new MutableHeaderType XML object + * + * @param transactionPhase the transaction phase + * @param segmentNumber the SegmentNumber element + * @return the MutableHeaderType XML object + */ + public static MutableHeaderType createMutableHeaderType(String transactionPhase, + SegmentNumber segmentNumber) { + MutableHeaderType newMutableHeaderType = MutableHeaderType.Factory.newInstance(); + newMutableHeaderType.setTransactionPhase( + TransactionPhaseType.Enum.forString(transactionPhase)); + if (segmentNumber != null) { + newMutableHeaderType.setSegmentNumber(segmentNumber); + } - /** - * Creates a new StaticHeaderType XML object - * @param hostId the host ID - * @param nonce the random nonce - * @param numSegments the segments number - * @param partnerId the partner ID - * @param product the Product element - * @param securityMedium the security medium - * @param userId the user Id - * @param timestamp the current time stamp - * @param orderDetails the StaticHeaderOrderDetailsType element - * @param bankPubKeyDigests the BankPubKeyDigests element - * @return the StaticHeaderType XML object - */ - public static StaticHeaderType createStaticHeaderType(String hostId, - byte[] nonce, - int numSegments, - String partnerId, - Product product, - String securityMedium, - String userId, - Calendar timestamp, - StaticHeaderOrderDetailsType orderDetails, - BankPubKeyDigests bankPubKeyDigests) - { - StaticHeaderType newStaticHeaderType = StaticHeaderType.Factory.newInstance(); - newStaticHeaderType.setHostID(hostId); - newStaticHeaderType.setNonce(nonce); - newStaticHeaderType.setNumSegments(numSegments); - newStaticHeaderType.setPartnerID(partnerId); - newStaticHeaderType.setProduct(product); - newStaticHeaderType.setSecurityMedium(securityMedium); - newStaticHeaderType.setUserID(userId); - newStaticHeaderType.setTimestamp(timestamp); - newStaticHeaderType.setOrderDetails(orderDetails); - newStaticHeaderType.setBankPubKeyDigests(bankPubKeyDigests); - - return newStaticHeaderType; - } + return newMutableHeaderType; + } - /** - * Creates a new StaticHeaderType XML object - * @param hostId the host ID - * @param nonce the random nonce - * @param numSegments the segments number - * @param partnerId the partner ID - * @param product the Product element - * @param securityMedium the security medium - * @param userId the user Id - * @param timestamp the current time stamp - * @param orderDetails the StaticHeaderOrderDetailsType element - * @param bankPubKeyDigests the BankPubKeyDigests element - * @return the StaticHeaderType XML object - */ - public static StaticHeaderType createStaticHeaderType(String hostId, - byte[] nonce, - String partnerId, - Product product, - String securityMedium, - String userId, - Calendar timestamp, - StaticHeaderOrderDetailsType orderDetails, - BankPubKeyDigests bankPubKeyDigests) - { - StaticHeaderType newStaticHeaderType = StaticHeaderType.Factory.newInstance(); - newStaticHeaderType.setHostID(hostId); - newStaticHeaderType.setNonce(nonce); - newStaticHeaderType.setPartnerID(partnerId); - newStaticHeaderType.setProduct(product); - newStaticHeaderType.setSecurityMedium(securityMedium); - newStaticHeaderType.setUserID(userId); - newStaticHeaderType.setTimestamp(timestamp); - newStaticHeaderType.setOrderDetails(orderDetails); - newStaticHeaderType.setBankPubKeyDigests(bankPubKeyDigests); - - return newStaticHeaderType; - } + /** + * Creates a new SegmentNumber XML object + * + * @param segmentNumber the segment number + * @param lastSegment is the last segment? + * @return the SegmentNumber XML object + */ + public static SegmentNumber createSegmentNumber(long segmentNumber, boolean lastSegment) { + SegmentNumber newSegmentNumber = SegmentNumber.Factory.newInstance(); + newSegmentNumber.setLongValue(segmentNumber); + newSegmentNumber.setLastSegment(lastSegment); + + return newSegmentNumber; + } - /** - * Creates a new StaticHeaderOrderDetailsType XML object - * @param orderId the order ID - * @param orderAttribute the order attribute - * @param orderType the order type - * @param orderParams the FULOrderParamsType element - * @return the StaticHeaderOrderDetailsType XML object - */ - public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, - OrderAttributeType.Enum orderAttribute, - OrderType orderType, - FULOrderParamsType orderParams) - { - return createStaticHeaderOrderDetailsType(orderId, orderAttribute, orderType, orderParams, - FULOrderParamsDocument.type.getDocumentElementName()); - } + /** + * Creates a new StaticHeaderType XML object + * + * @param hostId the host ID + * @param nonce the random nonce + * @param numSegments the segments number + * @param partnerId the partner ID + * @param product the Product element + * @param securityMedium the security medium + * @param userId the user Id + * @param timestamp the current time stamp + * @param orderDetails the StaticHeaderOrderDetailsType element + * @param bankPubKeyDigests the BankPubKeyDigests element + * @return the StaticHeaderType XML object + */ + public static StaticHeaderType createStaticHeaderType(String hostId, byte[] nonce, + int numSegments, String partnerId, StaticHeaderType.Product product, String securityMedium, + String userId, Calendar timestamp, StaticHeaderOrderDetailsType orderDetails, + StaticHeaderType.BankPubKeyDigests bankPubKeyDigests) { + StaticHeaderType header = StaticHeaderType.Factory.newInstance(); + header.setHostID(hostId); + header.setNonce(nonce); + header.setNumSegments(numSegments); + header.setPartnerID(partnerId); + header.setProduct(product); + header.setSecurityMedium(securityMedium); + header.setUserID(userId); + header.setTimestamp(timestamp); + header.setOrderDetails(orderDetails); + header.setBankPubKeyDigests(bankPubKeyDigests); + + return header; + } - /** - * Creates a new StaticHeaderOrderDetailsType XML object - * @param orderId the order ID - * @param orderAttribute the order attribute - * @param orderType the order type - * @param orderParams the FDLOrderParamsType element - * @return the StaticHeaderOrderDetailsType XML object - */ - public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, - OrderAttributeType.Enum orderAttribute, - OrderType orderType, - FDLOrderParamsType orderParams) - { - return createStaticHeaderOrderDetailsType(orderId, orderAttribute, orderType, orderParams, - FDLOrderParamsDocument.type.getDocumentElementName()); - } + /** + * Creates a new StaticHeaderType XML object + * + * @param hostId the host ID + * @param nonce the random nonce + * @param partnerId the partner ID + * @param product the Product element + * @param securityMedium the security medium + * @param userId the user Id + * @param timestamp the current time stamp + * @param orderDetails the StaticHeaderOrderDetailsType element + * @param bankPubKeyDigests the BankPubKeyDigests element + * @return the StaticHeaderType XML object + */ + public static StaticHeaderType createStaticHeaderType(String hostId, byte[] nonce, + String partnerId, StaticHeaderType.Product product, String securityMedium, String userId, + Calendar timestamp, StaticHeaderOrderDetailsType orderDetails, + StaticHeaderType.BankPubKeyDigests bankPubKeyDigests) { + StaticHeaderType newStaticHeaderType = StaticHeaderType.Factory.newInstance(); + newStaticHeaderType.setHostID(hostId); + newStaticHeaderType.setNonce(nonce); + newStaticHeaderType.setPartnerID(partnerId); + newStaticHeaderType.setProduct(product); + newStaticHeaderType.setSecurityMedium(securityMedium); + newStaticHeaderType.setUserID(userId); + newStaticHeaderType.setTimestamp(timestamp); + newStaticHeaderType.setOrderDetails(orderDetails); + newStaticHeaderType.setBankPubKeyDigests(bankPubKeyDigests); + + return newStaticHeaderType; + } - /** - * Creates a new StaticHeaderOrderDetailsType XML object - * @param orderId the order ID - * @param orderAttribute the order attribute - * @param orderType the order type - * @param orderParams the StandardOrderParamsType element - * @return the StaticHeaderOrderDetailsType XML object - */ - public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, - OrderAttributeType.Enum orderAttribute, - OrderType orderType, - StandardOrderParamsType orderParams) - { - return createStaticHeaderOrderDetailsType(orderId, orderAttribute, orderType, orderParams, - StandardOrderParamsDocument.type.getDocumentElementName()); - } +// /** +// * Creates a new StaticHeaderOrderDetailsType XML object +// * +// * @param orderId the order ID +// * @param orderAttribute the order attribute +// * @param orderType the order type +// * @param orderParams the FULOrderParamsType element +// * @return the StaticHeaderOrderDetailsType XML object +// */ +// public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, +// OrderAttributeType.Enum orderAttribute, OrderType orderType, +// FULOrderParamsType orderParams) { +// return createStaticHeaderOrderDetailsType(orderId, orderAttribute, orderType, orderParams, +// FULOrderParamsDocument.type.getDocumentElementName()); +// } +// +// /** +// * Creates a new StaticHeaderOrderDetailsType XML object +// * +// * @param orderId the order ID +// * @param orderAttribute the order attribute +// * @param orderType the order type +// * @param orderParams the FDLOrderParamsType element +// * @return the StaticHeaderOrderDetailsType XML object +// */ +// public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, +// OrderAttributeType.Enum orderAttribute, OrderType orderType, +// FDLOrderParamsType orderParams) { +// return createStaticHeaderOrderDetailsType(orderId, orderAttribute, orderType, orderParams, +// FDLOrderParamsDocument.type.getDocumentElementName()); +// } + +// /** +// * Creates a new StaticHeaderOrderDetailsType XML object +// * +// * @param orderId the order ID +// * @param orderAttribute the order attribute +// * @param orderType the order type +// * @param orderParams the StandardOrderParamsType element +// * @return the StaticHeaderOrderDetailsType XML object +// */ +// public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, +// OrderAttributeType.Enum orderAttribute, OrderType orderType, +// StandardOrderParamsType orderParams) { +// return createStaticHeaderOrderDetailsType(orderId, orderAttribute, orderType, orderParams, +// StandardOrderParamsDocument.type.getDocumentElementName()); +// } + + public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, + StaticHeaderOrderDetailsType.AdminOrderType orderType, + XmlObject orderParams, SchemaType orderParamsType) { - private static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, - OrderAttributeType.Enum orderAttribute, OrderType orderType, XmlObject orderParams, QName newInstance) { StaticHeaderOrderDetailsType type = StaticHeaderOrderDetailsType.Factory.newInstance(); if (orderId != null) { type.setOrderID(orderId); } - type.setOrderAttribute(orderAttribute); - type.setOrderType(orderType); + type.setAdminOrderType(orderType); type.setOrderParams(orderParams); - qualifySubstitutionGroup(type.getOrderParams(), newInstance, null); - + qualifySubstitutionGroup(type.getOrderParams(), orderParamsType.getDocumentElementName(), null); return type; } - /** - * Creates a new FULOrderParamsType XML object - * @param fileFormat the FileFormatType element - * @return the FULOrderParamsType XML object - */ - public static FULOrderParamsType createFULOrderParamsType(FileFormatType fileFormat) { - FULOrderParamsType newFULOrderParamsType = FULOrderParamsType.Factory.newInstance(); - newFULOrderParamsType.setFileFormat(fileFormat); - - return newFULOrderParamsType; - } - - /** - * Creates a new FDLOrderParamsType XML object - * @param fileFormat the FileFormatType element - * @return the FDLOrderParamsType XML object - */ - public static FDLOrderParamsType createFDLOrderParamsType(FileFormatType fileFormat) { - FDLOrderParamsType newFDLOrderParamsType = FDLOrderParamsType.Factory.newInstance(); - newFDLOrderParamsType.setFileFormat(fileFormat); + public static BTUParamsType createBTUParams(String serviceName, String scope, String option, + String messageName, String messageVersion, boolean signatureFlag) { + var type = BTUParamsType.Factory.newInstance(); + var service = type.addNewService(); + service.setServiceName(serviceName); + service.setScope(scope); + if (option != null) { + service.setServiceOption(option); + } + var msgType = MessageType.Factory.newInstance(); + + msgType.setStringValue(messageName); + //msgType.setFormat(messageName); + msgType.setVersion(messageVersion); + service.setMsgName(msgType); + if (signatureFlag) { + var flag = type.addNewSignatureFlag(); + flag.setRequestEDS(true); + } + return type; + } - return newFDLOrderParamsType; - } + /** + * Creates the order parameters of an EBICS 3.0 (H005) BTD download order. + * + * @param serviceName the BTF service code, e.g. {@code EOP} + * @param scope the rule scope, e.g. {@code CH}; may be {@code null} + * @param option the service option; may be {@code null} + * @param messageName the message name, e.g. {@code camt.053} + * @param messageVersion the message version, e.g. {@code 08} + * @param containerType the container type ({@code XML}, {@code ZIP} or {@code SVC}); + * may be {@code null} + * @param start the first calendar day of the requested report period; may be + * {@code null} + * @param end the last calendar day of the requested report period; may be + * {@code null} + * @return the BTDParamsType XML object + */ + public static BTDParamsType createBTDParams(String serviceName, String scope, String option, + String messageName, String messageVersion, String containerType, + LocalDate start, LocalDate end) { + var type = BTDParamsType.Factory.newInstance(); + var service = type.addNewService(); + service.setServiceName(serviceName); + if (scope != null) { + service.setScope(scope); + } + if (option != null) { + service.setServiceOption(option); + } + if (containerType != null) { + // The container flag lives inside Service (not directly in BTDParamsType) and the + // generated setter takes the enum, not a String. + var container = ContainerStringType.Enum.forString(containerType); + if (container == null) { + throw new IllegalArgumentException( + "Unsupported EBICS container type: " + containerType); + } + service.addNewContainer().setContainerType(container); + } + var msgType = MessageType.Factory.newInstance(); + msgType.setStringValue(messageName); + msgType.setVersion(messageVersion); + service.setMsgName(msgType); + if (start != null && end != null) { + var range = type.addNewDateRange(); + range.xsetStart(toXmlDate(start)); + range.xsetEnd(toXmlDate(end)); + } + return type; + } - /** - * Creates a new StandardOrderParamsType XML object - * @param fileFormat the FileFormatType element - * @return the StandardOrderParamsType XML object - */ - public static StandardOrderParamsType createStandardOrderParamsType() { - StandardOrderParamsType newStandardOrderParamsType = StandardOrderParamsType.Factory.newInstance(); + /** + * Converts a calendar day into an xs:date value. No timezone is involved in + * either direction: setting a {@link Calendar} would make XMLBeans append the local offset + * (e.g. {@code 2026-08-10+02:00}), which shifts the reported day for a bank in another + * timezone, and converting through an instant would make the day itself depend on the + * machine's zone. + */ + private static DateType toXmlDate(LocalDate date) { + var value = DateType.Factory.newInstance(); + value.setStringValue(date.toString()); + return value; + } - return newStandardOrderParamsType; - } +// private static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId, +// OrderAttributeType.Enum orderAttribute, OrderType orderType, XmlObject orderParams, +// QName newInstance) { +// StaticHeaderOrderDetailsType type = StaticHeaderOrderDetailsType.Factory.newInstance(); +// if (orderId != null) { +// type.setOrderID(orderId); +// } +// type.setOrderAttribute(orderAttribute); +// type.setOrderType(orderType); +// type.setOrderParams(orderParams); +// qualifySubstitutionGroup(type.getOrderParams(), newInstance, null); +// +// return type; +// } +// +// /** +// * Creates a new FULOrderParamsType XML object +// * +// * @param fileFormat the FileFormatType element +// * @return the FULOrderParamsType XML object +// */ +// public static FULOrderParamsType createFULOrderParamsType(FileFormatType fileFormat) { +// FULOrderParamsType newFULOrderParamsType = FULOrderParamsType.Factory.newInstance(); +// newFULOrderParamsType.setFileFormat(fileFormat); +// +// return newFULOrderParamsType; +// } +// +// /** +// * Creates a new FDLOrderParamsType XML object +// * +// * @param fileFormat the FileFormatType element +// * @return the FDLOrderParamsType XML object +// */ +// public static FDLOrderParamsType createFDLOrderParamsType(FileFormatType fileFormat) { +// FDLOrderParamsType newFDLOrderParamsType = FDLOrderParamsType.Factory.newInstance(); +// newFDLOrderParamsType.setFileFormat(fileFormat); +// +// return newFDLOrderParamsType; +// } + + /** + * Creates a new StandardOrderParamsType XML object + * + * @return the StandardOrderParamsType XML object + */ + public static StandardOrderParamsType createStandardOrderParamsType() { + return StandardOrderParamsType.Factory.newInstance(); + } - /** - * Creates a new DateRange XML object - * @param start the start range - * @param end the end range - * @return the DateRange XML object - */ - public static DateRange createDateRange(Date start, Date end) { - DateRange newDateRange = DateRange.Factory.newInstance(); - Calendar startRange = Calendar.getInstance(); - Calendar endRange = Calendar.getInstance(); - - startRange.setTime(start); - endRange.setTime(end); - newDateRange.setStart(startRange); - newDateRange.setEnd(endRange); - - return newDateRange; - } + /** + * Creates a new DateRange XML object. + * + *

A {@link Date} is an instant, the EBICS date range is a pair of calendar days. + * The calendar day is therefore taken in the timezone of the machine running this code: a + * {@code Date} at UTC midnight becomes the previous day in any zone west of UTC. Prefer + * {@link #createDateRange(LocalDate, LocalDate)} — that overload has no timezone in it. + * + * @param start the start range + * @param end the end range + * @return the DateRange XML object + */ + public static StandardOrderParamsType.DateRange createDateRange(Date start, Date end) { + return createDateRange(toLocalDate(start), toLocalDate(end)); + } - /** - * Creates a new FileFormatType XML object - * @param countryCode the country code - * @param value the file format value - * @return the FileFormatType XML object - */ - public static FileFormatType createFileFormatType(String countryCode, String value) { - FileFormatType newFileFormatType = FileFormatType.Factory.newInstance(); - newFileFormatType.setCountryCode(countryCode); - newFileFormatType.setStringValue(value); - - return newFileFormatType; - } + /** + * Creates a new DateRange XML object from two calendar days. + * + * @param start the first day of the range + * @param end the last day of the range + * @return the DateRange XML object + */ + public static StandardOrderParamsType.DateRange createDateRange(LocalDate start, LocalDate end) { + StandardOrderParamsType.DateRange newDateRange = StandardOrderParamsType.DateRange.Factory.newInstance(); - /** - * Creates a new Parameter XML object - * @param name the parameter name - * @param value the parameter value - * @return the Parameter XML object - */ - public static Parameter createParameter(String name, Value value) { - Parameter newParameter = Parameter.Factory.newInstance(); - newParameter.setName(name); - newParameter.setValue(value); - - return newParameter; - } + newDateRange.xsetStart(toXmlDate(start)); + newDateRange.xsetEnd(toXmlDate(end)); - /** - * Creates a new Value XML object - * @param type the value type - * @param value the value - * @return the Value XML object - */ - public static Value createValue(String type, String value) { - Value newValue = Value.Factory.newInstance(); - newValue.setType(type); - newValue.setStringValue(value); - - return newValue; - } + return newDateRange; + } - /** - * Create the OrderType XML object - * @param orderType the order type - * @return the OrderType XML object - */ - public static OrderType createOrderType(String orderType) { - OrderType newOrderType = OrderType.Factory.newInstance(); - newOrderType.setStringValue(orderType); + /** + * Reads the calendar day out of an instant, in the timezone of this machine. Only for the + * {@link Date}-based compatibility overloads; anything new should carry a {@link LocalDate}. + */ + public static LocalDate toLocalDate(Date date) { + return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + } - return newOrderType; - } +// /** +// * Creates a new FileFormatType XML object +// * +// * @param countryCode the country code +// * @param value the file format value +// * @return the FileFormatType XML object +// */ +// public static FileFormatType createFileFormatType(String countryCode, String value) { +// FileFormatType newFileFormatType = FileFormatType.Factory.newInstance(); +// newFileFormatType.setCountryCode(countryCode); +// newFileFormatType.setStringValue(value); +// +// return newFileFormatType; +// } + + /** + * Creates a new Parameter XML object + * + * @param name the parameter name + * @param value the parameter value + * @return the Parameter XML object + */ + public static Parameter createParameter(String name, Value value) { + Parameter newParameter = Parameter.Factory.newInstance(); + newParameter.setName(name); + newParameter.setValue(value); + + return newParameter; + } - /** - * Create the Product XML object - * @param language the product language - * @param value the product value - * @return the Product XML object - */ - public static Product createProduct(String language, String value) { - Product newProduct = Product.Factory.newInstance(); - newProduct.setLanguage(language); - newProduct.setStringValue(value); - - return newProduct; - } + /** + * Creates a new Value XML object + * + * @param type the value type + * @param value the value + * @return the Value XML object + */ + public static Value createValue(String type, String value) { + Value newValue = Value.Factory.newInstance(); + newValue.setType(type); + newValue.setStringValue(value); + + return newValue; + } +// +// /** +// * Create the OrderType XML object +// * +// * @param orderType the order type +// * @return the OrderType XML object +// */ +// public static OrderType createOrderType(String orderType) { +// OrderType newOrderType = OrderType.Factory.newInstance(); +// newOrderType.setStringValue(orderType); +// +// return newOrderType; +// } + + /** + * Create the Product XML object + * + * @param language the product language + * @param value the product value + * @return the Product XML object + */ + public static Product createProduct(String language, String value) { + Product newProduct = Product.Factory.newInstance(); + newProduct.setLanguage(language); + newProduct.setStringValue(value); + + return newProduct; + } - /** - * Create the BankPubKeyDigests XML object - * @param authentication the Authentication element - * @param encryption the Encryption element - * @return the BankPubKeyDigests XML object - */ - public static BankPubKeyDigests createBankPubKeyDigests(Authentication authentication, Encryption encryption) { - BankPubKeyDigests newBankPubKeyDigests = BankPubKeyDigests.Factory.newInstance(); - newBankPubKeyDigests.setAuthentication(authentication); - newBankPubKeyDigests.setEncryption(encryption); - - return newBankPubKeyDigests; - } + /** + * Create the BankPubKeyDigests XML object + * + * @param authentication the Authentication element + * @param encryption the Encryption element + * @return the BankPubKeyDigests XML object + */ + public static BankPubKeyDigests createBankPubKeyDigests(Authentication authentication, + Encryption encryption) { + BankPubKeyDigests newBankPubKeyDigests = BankPubKeyDigests.Factory.newInstance(); + newBankPubKeyDigests.setAuthentication(authentication); + newBankPubKeyDigests.setEncryption(encryption); + + return newBankPubKeyDigests; + } - /** - * Create the Authentication XML object - * @param version the authentication version - * @param algorithm the authentication algorithm - * @param value the authentication value - * @return the Authentication XML object - */ - public static Authentication createAuthentication(String version, String algorithm, byte[] value) { - Authentication newAuthentication = Authentication.Factory.newInstance(); - newAuthentication.setVersion(version); - newAuthentication.setAlgorithm(algorithm); - newAuthentication.setByteArrayValue(value); - - return newAuthentication; - } + /** + * Create the Authentication XML object + * + * @param version the authentication version + * @param algorithm the authentication algorithm + * @param value the authentication value + * @return the Authentication XML object + */ + public static Authentication createAuthentication(String version, String algorithm, + byte[] value) { + Authentication newAuthentication = Authentication.Factory.newInstance(); + newAuthentication.setVersion(version); + newAuthentication.setAlgorithm(algorithm); + newAuthentication.setByteArrayValue(value); + + return newAuthentication; + } - /** - * Create the Encryption XML object - * @param version the encryption version - * @param algorithm the encryption algorithm - * @param value the encryption value - * @return the Encryption XML object - */ - public static Encryption createEncryption(String version, String algorithm, byte[] value) { - Encryption newEncryption = Encryption.Factory.newInstance(); - newEncryption.setVersion(version); - newEncryption.setAlgorithm(algorithm); - newEncryption.setByteArrayValue(value); - - return newEncryption; - } + /** + * Create the Encryption XML object + * + * @param version the encryption version + * @param algorithm the encryption algorithm + * @param value the encryption value + * @return the Encryption XML object + */ + public static Encryption createEncryption(String version, String algorithm, byte[] value) { + Encryption newEncryption = Encryption.Factory.newInstance(); + newEncryption.setVersion(version); + newEncryption.setAlgorithm(algorithm); + newEncryption.setByteArrayValue(value); + + return newEncryption; + } - /** - * Create the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body XML object - * @param dataTransfer the DataTransferRequestType element - * @return the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body XML object - */ - public static org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody(DataTransferRequestType dataTransfer) { - org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body newBody = org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body.Factory.newInstance(); - newBody.setDataTransfer(dataTransfer); + /** + * Create the EbicsRequestDocument.EbicsRequest.Body XML object + * + * @param dataTransfer the DataTransferRequestType element + * @return the EbicsRequestDocument.EbicsRequest.Body XML object + */ + public static EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody( + DataTransferRequestType dataTransfer) { + EbicsRequestDocument.EbicsRequest.Body newBody = EbicsRequestDocument.EbicsRequest.Body.Factory.newInstance(); + newBody.setDataTransfer(dataTransfer); + + return newBody; + } - return newBody; - } + /** + * Create the EbicsRequestDocument.EbicsRequest.Body XML object + * + * @return the EbicsRequestDocument.EbicsRequest.Body XML object + */ + public static EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody() { + return EbicsRequestDocument.EbicsRequest.Body.Factory.newInstance(); + } - /** - * Create the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body XML object - * @return the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body XML object - */ - public static org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody() { - org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body newBody = org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body.Factory.newInstance(); + /** + * Create the EbicsRequestDocument.EbicsRequest.Body XML object + * + * @param transferReceipt the TransferReceipt element + * @return the EbicsRequestDocument.EbicsRequest.Body XML object + */ + public static EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody( + TransferReceipt transferReceipt) { + EbicsRequestDocument.EbicsRequest.Body newBody = EbicsRequestDocument.EbicsRequest.Body.Factory.newInstance(); + newBody.setTransferReceipt(transferReceipt); + + return newBody; + } - return newBody; - } + /** + * Create the DataTransferRequestType XML object + * + * @param dataEncryptionInfo the DataEncryptionInfo element + * @param signatureData the SignatureData element + * @return the DataTransferRequestType XML object + */ + public static DataTransferRequestType createDataTransferRequestType( + DataEncryptionInfo dataEncryptionInfo, SignatureData signatureData, String digestValue) { + DataTransferRequestType newDataTransferRequestType = DataTransferRequestType.Factory.newInstance(); + newDataTransferRequestType.setDataEncryptionInfo(dataEncryptionInfo); + newDataTransferRequestType.setSignatureData(signatureData); + if (digestValue != null) { + var digest = DataDigestType.Factory.newInstance(); + digest.setSignatureVersion("A005"); + digest.setStringValue(digestValue); + newDataTransferRequestType.setDataDigest(digest); + } + return newDataTransferRequestType; + } - /** - * Create the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body XML object - * @param transferReceipt the TransferReceipt element - * @return the org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body XML object - */ - public static org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody(TransferReceipt transferReceipt) { - org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body newBody = org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body.Factory.newInstance(); - newBody.setTransferReceipt(transferReceipt); + /** + * Create the StaticHeaderType XML object + * + * @param hostId the host ID + * @param transactionId the transaction ID + * @return the StaticHeaderType XML object + */ + public static StaticHeaderType createStaticHeaderType(String hostId, byte[] transactionId) { + StaticHeaderType newStaticHeaderType = StaticHeaderType.Factory.newInstance(); + newStaticHeaderType.setHostID(hostId); + newStaticHeaderType.setTransactionID(transactionId); + + return newStaticHeaderType; + } - return newBody; - } + /** + * Create the DataTransferRequestType XML object + * + * @param orderData the DataTransferRequestType.OrderData element + * @return the DataTransferRequestType XML object + */ + public static DataTransferRequestType createDataTransferRequestType( + DataTransferRequestType.OrderData orderData) { + DataTransferRequestType newDataTransferRequestType = DataTransferRequestType.Factory.newInstance(); + newDataTransferRequestType.setOrderData(orderData); + + return newDataTransferRequestType; + } - /** - * Create the DataTransferRequestType XML object - * @param dataEncryptionInfo the DataEncryptionInfo element - * @param signatureData the SignatureData element - * @return the DataTransferRequestType XML object - */ - public static DataTransferRequestType createDataTransferRequestType(DataEncryptionInfo dataEncryptionInfo, - SignatureData signatureData) - { - DataTransferRequestType newDataTransferRequestType = DataTransferRequestType.Factory.newInstance(); - newDataTransferRequestType.setDataEncryptionInfo(dataEncryptionInfo); - newDataTransferRequestType.setSignatureData(signatureData); - - return newDataTransferRequestType; - } + /** + * Create the DataTransferRequestType.OrderData XML object + * + * @param orderDataValue the order data value + * @return the DataTransferRequestType.OrderData XML object + */ + public static DataTransferRequestType.OrderData createTransferRequestTypeOrderData( + byte[] orderDataValue) { + DataTransferRequestType.OrderData newOrderData = DataTransferRequestType.OrderData.Factory.newInstance(); + newOrderData.setByteArrayValue(orderDataValue); + + return newOrderData; + } - /** - * Create the StaticHeaderType XML object - * @param hostId the host ID - * @param transactionId the transaction ID - * @return the StaticHeaderType XML object - */ - public static StaticHeaderType createStaticHeaderType(String hostId, byte[] transactionId) { - StaticHeaderType newStaticHeaderType = StaticHeaderType.Factory.newInstance(); - newStaticHeaderType.setHostID(hostId); - newStaticHeaderType.setTransactionID(transactionId); - - return newStaticHeaderType; - } + /** + * Create the DataEncryptionInfo XML object + * + * @param authenticate should authenticate? + * @param encryptionPubKeyDigest the EncryptionPubKeyDigest element + * @param transactionKey the transaction key + * @return the the DataEncryptionInfo XML object + */ + public static DataEncryptionInfo createDataEncryptionInfo(boolean authenticate, + EncryptionPubKeyDigest encryptionPubKeyDigest, byte[] transactionKey) { + DataEncryptionInfo newDataEncryptionInfo = DataEncryptionInfo.Factory.newInstance(); + newDataEncryptionInfo.setAuthenticate(authenticate); + newDataEncryptionInfo.setEncryptionPubKeyDigest(encryptionPubKeyDigest); + newDataEncryptionInfo.setTransactionKey(transactionKey); + + return newDataEncryptionInfo; + } - /** - * Create the DataTransferRequestType XML object - * @param orderData the org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData element - * @return the DataTransferRequestType XML object - */ - public static DataTransferRequestType createDataTransferRequestType(org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData orderData) { - DataTransferRequestType newDataTransferRequestType = DataTransferRequestType.Factory.newInstance(); - newDataTransferRequestType.setOrderData(orderData); + /** + * Create the EncryptionPubKeyDigest XML object + * + * @param version the encryption version + * @param algorithm the encryption algorithm + * @param value the encryption value + * @return the EncryptionPubKeyDigest XML object + */ + public static EncryptionPubKeyDigest createEncryptionPubKeyDigest(String version, + String algorithm, byte[] value) { + EncryptionPubKeyDigest newEncryptionPubKeyDigest = EncryptionPubKeyDigest.Factory.newInstance(); + newEncryptionPubKeyDigest.setVersion(version); + newEncryptionPubKeyDigest.setAlgorithm(algorithm); + newEncryptionPubKeyDigest.setByteArrayValue(value); + + return newEncryptionPubKeyDigest; + } - return newDataTransferRequestType; - } + /** + * Create the DataTransferRequestType.OrderData XML object + * + * @param oderData the order data value + * @return the the DataTransferRequestType.OrderData XML object + */ + public static DataTransferRequestType.OrderData createEbicsRequestOrderData(byte[] oderData) { + DataTransferRequestType.OrderData newOrderData = DataTransferRequestType.OrderData.Factory.newInstance(); + newOrderData.setByteArrayValue(oderData); + + return newOrderData; + } - /** - * Create the org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData XML object - * @param orderDataValue the order data value - * @return the org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData XML object - */ - public static org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData createTransferRequestTypeOrderData(byte[] orderDataValue) { - org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData newOrderData = org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData.Factory.newInstance(); - newOrderData.setByteArrayValue(orderDataValue); + /** + * Create the SignatureData XML object + * + * @param authenticate should authenticate? + * @param signatureData the signature data value + * @return the SignatureData XML object + */ + public static SignatureData createSignatureData(boolean authenticate, byte[] signatureData) { + SignatureData newSignatureData = SignatureData.Factory.newInstance(); + newSignatureData.setAuthenticate(authenticate); + newSignatureData.setByteArrayValue(signatureData); + + return newSignatureData; + } - return newOrderData; - } + /** + * Create the TransferReceipt XML object + * + * @param authenticate should authenticate? + * @param receiptCode the receipt code + * @return the TransferReceipt XML object + */ + public static TransferReceipt createTransferReceipt(boolean authenticate, int receiptCode) { + TransferReceipt newTransferReceipt = TransferReceipt.Factory.newInstance(); + newTransferReceipt.setAuthenticate(authenticate); + newTransferReceipt.setReceiptCode(receiptCode); + + return newTransferReceipt; + } - /** - * Create the DataEncryptionInfo XML object - * @param authenticate should authenticate? - * @param encryptionPubKeyDigest the EncryptionPubKeyDigest element - * @param transactionKey the transaction key - * @return the the DataEncryptionInfo XML object - */ - public static DataEncryptionInfo createDataEncryptionInfo(boolean authenticate, - EncryptionPubKeyDigest encryptionPubKeyDigest, - byte[] transactionKey) - { - DataEncryptionInfo newDataEncryptionInfo = DataEncryptionInfo.Factory.newInstance(); - newDataEncryptionInfo.setAuthenticate(authenticate); - newDataEncryptionInfo.setEncryptionPubKeyDigest(encryptionPubKeyDigest); - newDataEncryptionInfo.setTransactionKey(transactionKey); - - return newDataEncryptionInfo; - } + /** + * Qualifies a valid member of a substitution group. This method tries to use the + * built-in {@link XmlObject#substitute(QName, SchemaType)} and if succesful returns + * a valid substitution which is usable (not disconnected). If it fails, it uses + * low-level {@link XmlCursor} manipulation to qualify the substitution group. Note + * that if the latter is the case the resulting document is disconnected and should + * no longer be manipulated. Thus, use it as a final step after all markup is included. + *

+ * If newType is null, this method will skip {@link XmlObject#substitute(QName, SchemaType)} + * and directly use {@link XmlCursor}. This can be used, if you are sure that the substitute + * is not in the list of (pre-compiled) valid substitutions (this is the case if a schema + * uses another schema's type as a base for elements. E.g. om:Observation uses gml:_Feature + * as the base type). + * + * @param xobj the abstract element + * @param newInstance the new {@link QName} of the instance + * @param newType the new schemaType. if null, cursors will be used and the resulting object + * will be disconnected. + * @return if successful applied {@link XmlObject#substitute(QName, SchemaType)} a living object with a + * type == newType is returned. Otherwise null is returned as you can no longer manipulate the object. + */ + public static XmlObject qualifySubstitutionGroup(XmlObject xobj, QName newInstance, + SchemaType newType) { + XmlObject substitute; + + if (newType != null) { + substitute = xobj.substitute(newInstance, newType); + if (substitute != null && substitute.schemaType() == newType && substitute.getDomNode() + .getLocalName().equals(newInstance.getLocalPart())) { + return substitute; + } + } - /** - * Create the EncryptionPubKeyDigest XML object - * @param version the encryption version - * @param algorithm the encryption algorithm - * @param value the encryption value - * @return the EncryptionPubKeyDigest XML object - */ - public static EncryptionPubKeyDigest createEncryptionPubKeyDigest(String version, String algorithm, byte[] value) { - EncryptionPubKeyDigest newEncryptionPubKeyDigest = EncryptionPubKeyDigest.Factory.newInstance(); - newEncryptionPubKeyDigest.setVersion(version); - newEncryptionPubKeyDigest.setAlgorithm(algorithm); - newEncryptionPubKeyDigest.setByteArrayValue(value); - - return newEncryptionPubKeyDigest; - } + try (XmlCursor cursor = xobj.newCursor()) { + cursor.setName(newInstance); + QName qName = new QName("http://www.w3.org/2001/XMLSchema-instance", "type"); + cursor.removeAttribute(qName); + cursor.toNextToken(); + if (cursor.isNamespace()) { + cursor.removeXml(); + } + } - /** - * Create the org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData XML object - * @param oderData the order data value - * @return the the org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData XML object - */ - public static org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData createEbicsRequestOrderData(byte[] oderData) { - org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData newOrderData = org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData.Factory.newInstance(); - newOrderData.setByteArrayValue(oderData); + return null; + } - return newOrderData; - } + public static KeyValueType createKeyValueType(RSAKeyValueType encryptionRsaKeyValue) { + var keyValue = KeyValueType.Factory.newInstance(); + keyValue.setRSAKeyValue(encryptionRsaKeyValue); + return keyValue; + } - /** - * Create the SignatureData XML object - * @param authenticate should authenticate? - * @param signatureData the signature data value - * @return the SignatureData XML object - */ - public static SignatureData createSignatureData(boolean authenticate, byte[] signatureData) { - SignatureData newSignatureData = SignatureData.Factory.newInstance(); - newSignatureData.setAuthenticate(authenticate); - newSignatureData.setByteArrayValue(signatureData); - - return newSignatureData; - } + public static PubKeyInfoType createPubKeyInfoType(X509DataType encryptionX509Data) { + var pubKeyInfo = PubKeyInfoType.Factory.newInstance(); + pubKeyInfo.setX509Data(encryptionX509Data); + return pubKeyInfo; + } - /** - * Create the TransferReceipt XML object - * @param authenticate should authenticate? - * @param receiptCode the receipt code - * @return the TransferReceipt XML object - */ - public static TransferReceipt createTransferReceipt(boolean authenticate, int receiptCode) { - TransferReceipt newTransferReceipt = TransferReceipt.Factory.newInstance(); - newTransferReceipt.setAuthenticate(authenticate); - newTransferReceipt.setReceiptCode(receiptCode); - - return newTransferReceipt; - } + public static EncryptionPubKeyInfoType createEncryptionPubKeyInfoType(String encryptionVersion, + X509DataType encryptionX509Data) { + var pubKeyInfo = EncryptionPubKeyInfoType.Factory.newInstance(); + pubKeyInfo.setEncryptionVersion(encryptionVersion); + pubKeyInfo.setX509Data(encryptionX509Data); + return pubKeyInfo; + } - /** - * Qualifies a valid member of a substitution group. This method tries to use the - * built-in {@link XmlObject#substitute(QName, SchemaType)} and if succesful returns - * a valid substitution which is usable (not disconnected). If it fails, it uses - * low-level {@link XmlCursor} manipulation to qualify the substitution group. Note - * that if the latter is the case the resulting document is disconnected and should - * no longer be manipulated. Thus, use it as a final step after all markup is included. - * - * If newType is null, this method will skip {@link XmlObject#substitute(QName, SchemaType)} - * and directly use {@link XmlCursor}. This can be used, if you are sure that the substitute - * is not in the list of (pre-compiled) valid substitutions (this is the case if a schema - * uses another schema's type as a base for elements. E.g. om:Observation uses gml:_Feature - * as the base type). - * - * @param xobj - * the abstract element - * @param newInstance - * the new {@link QName} of the instance - * @param newType the new schemaType. if null, cursors will be used and the resulting object - * will be disconnected. - * @return if successful applied {@link XmlObject#substitute(QName, SchemaType)} a living object with a - * type == newType is returned. Otherwise null is returned as you can no longer manipulate the object. - */ - public static XmlObject qualifySubstitutionGroup(XmlObject xobj, QName newInstance, SchemaType newType) { - XmlObject substitute = null; - - if (newType != null) { - substitute = xobj.substitute(newInstance, newType); - if (substitute != null && substitute.schemaType() == newType - && substitute.getDomNode().getLocalName().equals(newInstance.getLocalPart())) - { - return substitute; - } - } - - XmlCursor cursor = xobj.newCursor(); - cursor.setName(newInstance); - QName qName = new QName("http://www.w3.org/2001/XMLSchema-instance", "type"); - cursor.removeAttribute(qName); - cursor.toNextToken(); - if (cursor.isNamespace()) { - cursor.removeXml(); - } - - cursor.dispose(); - - return null; + private EbicsXmlFactory() { } } diff --git a/src/main/java/org/kopi/ebics/xml/HIARequestElement.java b/src/main/java/org/kopi/ebics/xml/HIARequestElement.java index 37a5c8cc..1cb13954 100644 --- a/src/main/java/org/kopi/ebics/xml/HIARequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/HIARequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -29,7 +28,6 @@ * to send the authentication and encryption keys to the ebics * bank server * - * @author hachani * */ public class HIARequestElement extends DefaultEbicsRootElement { @@ -51,23 +49,21 @@ public String getName() { @Override public void build() throws EbicsException { - HIARequestOrderDataElement requestOrderData; - requestOrderData = new HIARequestOrderDataElement(session); - requestOrderData.build(); - unsecuredRequest = new UnsecuredRequestElement(session, - OrderType.HIA, - orderId == null ? session.getUser().getPartner().nextOrderId() : orderId, - Utils.zip(requestOrderData.prettyPrint())); - unsecuredRequest.build(); + var requestOrderData = new HIARequestOrderDataElement(session); + requestOrderData.build(); + unsecuredRequest = new UnsecuredRequestElement(session, OrderType.HIA, + orderId == null ? session.getUser().getPartner().nextOrderId() : orderId, + Utils.zip(requestOrderData.prettyPrint())); + unsecuredRequest.setSaveSuggestedPrefixes("urn:org:ebics:H005", ""); + unsecuredRequest.build(); } - @Override - public byte[] toByteArray() { - setSaveSuggestedPrefixes("http://www.ebics.org/H003", ""); + @Override + public byte[] toByteArray() { - return unsecuredRequest.toByteArray(); - } + return unsecuredRequest.toByteArray(); + } @Override public void validate() throws EbicsException { @@ -78,7 +74,7 @@ public void validate() throws EbicsException { // DATA MEMBERS // -------------------------------------------------------------------- - private String orderId; + private final String orderId; private UnsecuredRequestElement unsecuredRequest; private static final long serialVersionUID = 1130436605993828777L; } diff --git a/src/main/java/org/kopi/ebics/xml/HIARequestOrderDataElement.java b/src/main/java/org/kopi/ebics/xml/HIARequestOrderDataElement.java index 09ac4703..cb274855 100644 --- a/src/main/java/org/kopi/ebics/xml/HIARequestOrderDataElement.java +++ b/src/main/java/org/kopi/ebics/xml/HIARequestOrderDataElement.java @@ -13,96 +13,71 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; -import java.util.Calendar; - import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.AuthenticationPubKeyInfoType; -import org.kopi.ebics.schema.h003.EncryptionPubKeyInfoType; -import org.kopi.ebics.schema.h003.HIARequestOrderDataType; -import org.kopi.ebics.schema.h003.PubKeyValueType; -import org.kopi.ebics.schema.xmldsig.RSAKeyValueType; +import org.kopi.ebics.schema.h005.AuthenticationPubKeyInfoType; +import org.kopi.ebics.schema.h005.EncryptionPubKeyInfoType; +import org.kopi.ebics.schema.h005.HIARequestOrderDataType; import org.kopi.ebics.schema.xmldsig.X509DataType; import org.kopi.ebics.session.EbicsSession; - /** * The HIARequestOrderDataElement is the element that contains * X002 and E002 keys information needed for a HIA request in order to send * the authentication and encryption user keys to the bank server. * - * @author hachani * */ public class HIARequestOrderDataElement extends DefaultEbicsRootElement { - /** - * Constructs a new HIA Request Order Data element - * @param session the current ebics session - */ - public HIARequestOrderDataElement(EbicsSession session) { - super(session); - } + /** + * Constructs a new HIA Request Order Data element + * + * @param session the current ebics session + */ + public HIARequestOrderDataElement(EbicsSession session) { + super(session); + } + + @Override + public void build() throws EbicsException { + X509DataType encryptionX509Data = EbicsXmlFactory.createX509DataType( + session.getUser().getDN(), session.getUser().getE002Certificate()); + + X509DataType authX509Data = EbicsXmlFactory.createX509DataType(session.getUser().getDN(), + session.getUser().getX002Certificate()); + - @Override - public void build() throws EbicsException { - HIARequestOrderDataType request; - AuthenticationPubKeyInfoType authenticationPubKeyInfo; - EncryptionPubKeyInfoType encryptionPubKeyInfo; - PubKeyValueType encryptionPubKeyValue; - X509DataType encryptionX509Data; - RSAKeyValueType encryptionRsaKeyValue; - PubKeyValueType authPubKeyValue; - X509DataType authX509Data; - RSAKeyValueType AuthRsaKeyValue; + var encryptionPubKeyInfo = EbicsXmlFactory.createEncryptionPubKeyInfoType(session.getConfiguration().getEncryptionVersion(), + encryptionX509Data); + AuthenticationPubKeyInfoType authenticationPubKeyInfo = EbicsXmlFactory.createAuthenticationPubKeyInfoType( + session.getConfiguration().getAuthenticationVersion(), authX509Data); - encryptionX509Data = null; - if (session.getUser().getPartner().getBank().useCertificate()) - encryptionX509Data = EbicsXmlFactory.createX509DataType(session.getUser().getDN(), - session.getUser().getE002Certificate()); - encryptionRsaKeyValue = EbicsXmlFactory.createRSAKeyValueType(session.getUser().getE002PublicKey().getPublicExponent().toByteArray(), - session.getUser().getE002PublicKey().getModulus().toByteArray()); - encryptionPubKeyValue = EbicsXmlFactory.createH003PubKeyValueType(encryptionRsaKeyValue, Calendar.getInstance()); - encryptionPubKeyInfo = EbicsXmlFactory.createEncryptionPubKeyInfoType(session.getConfiguration().getEncryptionVersion(), - encryptionPubKeyValue, - encryptionX509Data); - authX509Data = null; - if (session.getUser().getPartner().getBank().useCertificate()) - authX509Data = EbicsXmlFactory.createX509DataType(session.getUser().getDN(), - session.getUser().getX002Certificate()); - AuthRsaKeyValue = EbicsXmlFactory.createRSAKeyValueType(session.getUser().getX002PublicKey().getPublicExponent().toByteArray(), - session.getUser().getX002PublicKey().getModulus().toByteArray()); - authPubKeyValue = EbicsXmlFactory.createH003PubKeyValueType(AuthRsaKeyValue, Calendar.getInstance()); - authenticationPubKeyInfo = EbicsXmlFactory.createAuthenticationPubKeyInfoType(session.getConfiguration().getAuthenticationVersion(), - authPubKeyValue, - authX509Data); - request = EbicsXmlFactory.createHIARequestOrderDataType(authenticationPubKeyInfo, - encryptionPubKeyInfo, - session.getUser().getPartner().getPartnerId(), - session.getUser().getUserId()); - document = EbicsXmlFactory.createHIARequestOrderDataDocument(request); - } + HIARequestOrderDataType request = EbicsXmlFactory.createHIARequestOrderDataType( + authenticationPubKeyInfo, encryptionPubKeyInfo, + session.getUser().getPartner().getPartnerId(), session.getUser().getUserId()); + document = EbicsXmlFactory.createHIARequestOrderDataDocument(request); + } - @Override - public String getName() { - return "HIARequestOrderData.xml"; - } + @Override + public String getName() { + return "HIARequestOrderData.xml"; + } - @Override - public byte[] toByteArray() { - addNamespaceDecl("ds", "http://www.w3.org/2000/09/xmldsig#"); - setSaveSuggestedPrefixes("http://www.ebics.org/S001", ""); + @Override + public byte[] toByteArray() { + addNamespaceDecl("ds", "http://www.w3.org/2000/09/xmldsig#"); + setSaveSuggestedPrefixes("urn:org:ebics:H005", ""); - return super.toByteArray(); - } + return super.toByteArray(); + } - // -------------------------------------------------------------------- - // DATA MEMBERS - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- + // DATA MEMBERS + // -------------------------------------------------------------------- - private static final long serialVersionUID = -7333250823464659004L; + private static final long serialVersionUID = -7333250823464659004L; } diff --git a/src/main/java/org/kopi/ebics/xml/HPBRequestElement.java b/src/main/java/org/kopi/ebics/xml/HPBRequestElement.java index 6fc1ee4a..1de2a382 100644 --- a/src/main/java/org/kopi/ebics/xml/HPBRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/HPBRequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -26,7 +25,6 @@ * The HPBRequestElement is the element to be sent when * a HPB request is needed to retrieve the bank public keys * - * @author hachani * */ public class HPBRequestElement extends DefaultEbicsRootElement { @@ -46,15 +44,12 @@ public String getName() { @Override public void build() throws EbicsException { - SignedInfo signedInfo; - byte[] signature; - noPubKeyDigestsRequest = new NoPubKeyDigestsRequestElement(session); noPubKeyDigestsRequest.build(); - signedInfo = new SignedInfo(session.getUser(), noPubKeyDigestsRequest.getDigest()); + var signedInfo = new SignedInfo(session.getUser(), noPubKeyDigestsRequest.getDigest()); signedInfo.build(); noPubKeyDigestsRequest.setAuthSignature(signedInfo.getSignatureType()); - signature = signedInfo.sign(noPubKeyDigestsRequest.toByteArray()); + var signature = signedInfo.sign(noPubKeyDigestsRequest.toByteArray()); noPubKeyDigestsRequest.setSignatureValue(signature); } diff --git a/src/main/java/org/kopi/ebics/xml/HPBResponseOrderDataElement.java b/src/main/java/org/kopi/ebics/xml/HPBResponseOrderDataElement.java index 653c9daf..cbe17b8a 100644 --- a/src/main/java/org/kopi/ebics/xml/HPBResponseOrderDataElement.java +++ b/src/main/java/org/kopi/ebics/xml/HPBResponseOrderDataElement.java @@ -14,22 +14,20 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.schema.h003.HPBResponseOrderDataDocument; -import org.kopi.ebics.schema.h003.HPBResponseOrderDataType; +import org.kopi.ebics.schema.h005.HPBResponseOrderDataDocument; +import org.kopi.ebics.schema.h005.HPBResponseOrderDataType; /** * The HPBResponseOrderDataElement contains the public bank * keys in encrypted mode. The user should decrypt with his encryption * key to have the bank public keys. * - * @author hachani * */ public class HPBResponseOrderDataElement extends DefaultResponseElement { @@ -59,25 +57,9 @@ public byte[] getBankE002Certificate() { return response.getEncryptionPubKeyInfo().getX509Data().getX509CertificateArray(0); } - public byte[] getBankE002PublicKeyModulus() { - return response.getEncryptionPubKeyInfo().getPubKeyValue().getRSAKeyValue().getModulus(); - } - - public byte[] getBankE002PublicKeyExponent() { - return response.getEncryptionPubKeyInfo().getPubKeyValue().getRSAKeyValue().getExponent(); - } - - public byte[] getBankX002PublicKeyModulus() { - return response.getAuthenticationPubKeyInfo().getPubKeyValue().getRSAKeyValue().getModulus(); - } - - public byte[] getBankX002PublicKeyExponent() { - return response.getAuthenticationPubKeyInfo().getPubKeyValue().getRSAKeyValue().getExponent(); - } - @Override public void build() throws EbicsException { - parse(factory); + parse(factory, HPBResponseOrderDataDocument.Factory); response = ((HPBResponseOrderDataDocument)document).getHPBResponseOrderData(); } diff --git a/src/main/java/org/kopi/ebics/xml/INIRequestElement.java b/src/main/java/org/kopi/ebics/xml/INIRequestElement.java index b2cd823a..35dc840b 100644 --- a/src/main/java/org/kopi/ebics/xml/INIRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/INIRequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -28,7 +27,6 @@ * The INI request XML element. This root element is to be sent * to the ebics server to initiate the signature certificate. * - * @author hachani * */ public class INIRequestElement extends DefaultEbicsRootElement { @@ -48,23 +46,21 @@ public String getName() { return "INIRequest.xml"; } - @Override - public void build() throws EbicsException { - SignaturePubKeyOrderDataElement signaturePubKey; + @Override + public void build() throws EbicsException { + var signaturePubKey = new SignaturePubKeyOrderDataElement(session); + signaturePubKey.build(); + unsecuredRequest = new UnsecuredRequestElement(session, OrderType.INI, + orderId == null ? session.getUser().getPartner().nextOrderId() : orderId, + Utils.zip(signaturePubKey.prettyPrint())); + unsecuredRequest.build(); + unsecuredRequest.addNamespaceDecl("ds", "http://www.w3.org/2000/09/xmldsig#"); + unsecuredRequest.setSaveSuggestedPrefixes("urn:org:ebics:H005", ""); - signaturePubKey = new SignaturePubKeyOrderDataElement(session); - signaturePubKey.build(); - unsecuredRequest = new UnsecuredRequestElement(session, - OrderType.INI, - orderId == null ? session.getUser().getPartner().nextOrderId() : orderId, - Utils.zip(signaturePubKey.prettyPrint())); - unsecuredRequest.build(); - } + } @Override public byte[] toByteArray() { - setSaveSuggestedPrefixes("http://www.ebics.org/H003", ""); - return unsecuredRequest.toByteArray(); } @@ -77,7 +73,7 @@ public void validate() throws EbicsException { // DATA MEMBERS // -------------------------------------------------------------------- - private String orderId; + private final String orderId; private UnsecuredRequestElement unsecuredRequest; private static final long serialVersionUID = -1966559247739923555L; } diff --git a/src/main/java/org/kopi/ebics/xml/InitializationRequestElement.java b/src/main/java/org/kopi/ebics/xml/InitializationRequestElement.java index cbcf1c15..a1b00e73 100644 --- a/src/main/java/org/kopi/ebics/xml/InitializationRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/InitializationRequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -22,16 +21,17 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; +import java.util.HexFormat; import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.EbicsRequestDocument; +import org.kopi.ebics.interfaces.EbicsOrderType; + +import org.kopi.ebics.schema.h005.EbicsRequestDocument; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; import org.kopi.ebics.utils.Utils; @@ -40,7 +40,6 @@ * ebics uploads and downloads requests. The response of this element is * then used either to upload or download files from the ebics server. * - * @author Hachani * */ public abstract class InitializationRequestElement extends DefaultEbicsRootElement { @@ -50,29 +49,28 @@ public abstract class InitializationRequestElement extends DefaultEbicsRootEleme * @param session the current ebics session. * @param type the initialization type (UPLOAD, DOWNLOAD). * @param name the element name. - * @throws EbicsException */ - public InitializationRequestElement(EbicsSession session, - OrderType type, - String name) - throws EbicsException - { + protected InitializationRequestElement(EbicsSession session, + EbicsOrderType type, + String name) { super(session); this.type = type; this.name = name; nonce = Utils.generateNonce(); + key = Utils.generateKey(); + keySpec = new SecretKeySpec(key, "EAS"); } - @Override - public void build() throws EbicsException { - SignedInfo signedInfo; - - buildInitialization(); - signedInfo = new SignedInfo(session.getUser(), getDigest()); - signedInfo.build(); - ((EbicsRequestDocument)document).getEbicsRequest().setAuthSignature(signedInfo.getSignatureType()); - ((EbicsRequestDocument)document).getEbicsRequest().getAuthSignature().setSignatureValue(EbicsXmlFactory.createSignatureValueType(signedInfo.sign(toByteArray()))); - } + @Override + public void build() throws EbicsException { + buildInitialization(); + SignedInfo signedInfo = new SignedInfo(session.getUser(), getDigest()); + signedInfo.build(); + var ebicsRequest = ((EbicsRequestDocument) document).getEbicsRequest(); + ebicsRequest.setAuthSignature(signedInfo.getSignatureType()); + ebicsRequest.getAuthSignature().setSignatureValue( + EbicsXmlFactory.createSignatureValueType(signedInfo.sign(toByteArray()))); + } @Override public String getName() { @@ -96,9 +94,7 @@ public byte[] getDigest() throws EbicsException { try { return MessageDigest.getInstance("SHA-256", "BC").digest(Utils.canonize(toByteArray())); - } catch (NoSuchAlgorithmException e) { - throw new EbicsException(e.getMessage()); - } catch (NoSuchProviderException e) { + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { throw new EbicsException(e.getMessage()); } } @@ -108,7 +104,7 @@ public byte[] getDigest() throws EbicsException { * @return the element type. */ public String getType() { - return type.toString(); + return type.getCode(); } /** @@ -123,8 +119,8 @@ protected byte[] decodeHex(byte[] hex) throws EbicsException { } try { - return Hex.decodeHex((new String(hex)).toCharArray()); - } catch (DecoderException e) { + return HexFormat.of().parseHex(new String(hex)); + } catch (IllegalArgumentException e) { throw new EbicsException(e.getMessage()); } } @@ -135,12 +131,10 @@ protected byte[] decodeHex(byte[] hex) throws EbicsException { */ protected byte[] generateTransactionKey() throws EbicsException { try { - Cipher cipher; - - cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding", BouncyCastleProvider.PROVIDER_NAME); + Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding", BouncyCastleProvider.PROVIDER_NAME); cipher.init(Cipher.ENCRYPT_MODE, session.getBankE002Key()); - return cipher.doFinal(nonce); + return cipher.doFinal(key); } catch (Exception e) { throw new EbicsException(e.getMessage()); } @@ -157,8 +151,10 @@ protected byte[] generateTransactionKey() throws EbicsException { // DATA MEMBERS // -------------------------------------------------------------------- - private String name; - protected OrderType type; - protected byte[] nonce; - private static final long serialVersionUID = 8983807819242699280L; + private final String name; + protected EbicsOrderType type; + protected final byte[] nonce; + private final byte[] key; + protected final SecretKeySpec keySpec; + private static final long serialVersionUID = 8983807819242699280L; } diff --git a/src/main/java/org/kopi/ebics/xml/InitializationResponseElement.java b/src/main/java/org/kopi/ebics/xml/InitializationResponseElement.java index e3505e98..ccb4e6ea 100644 --- a/src/main/java/org/kopi/ebics/xml/InitializationResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/InitializationResponseElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -22,15 +21,14 @@ import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.schema.h003.EbicsResponseDocument; -import org.kopi.ebics.schema.h003.EbicsResponseDocument.EbicsResponse; -import org.kopi.ebics.session.OrderType; +import org.kopi.ebics.interfaces.EbicsOrderType; +import org.kopi.ebics.schema.h005.EbicsResponseDocument; +import org.kopi.ebics.schema.h005.EbicsResponseDocument.EbicsResponse; /** * The InitializationResponseElement is the common * element for transfer initialization responses. * - * @author Hachani * */ public class InitializationResponseElement extends DefaultResponseElement { @@ -42,24 +40,24 @@ public class InitializationResponseElement extends DefaultResponseElement { * @param name the element name */ public InitializationResponseElement(ContentFactory factory, - OrderType orderType, + EbicsOrderType orderType, String name) { super(factory, name); this.orderType = orderType; } - @Override - public void build() throws EbicsException { - parse(factory); - response = ((EbicsResponseDocument)document).getEbicsResponse(); - String code = response.getHeader().getMutable().getReturnCode(); - String text = response.getHeader().getMutable().getReportText(); - returnCode = ReturnCode.toReturnCode(code, text); - checkReturnCode(returnCode); - processBodyReturnCode(); - transactionId = response.getHeader().getStatic().getTransactionID(); - } + @Override + public void build() throws EbicsException { + var doc = parse(factory, EbicsResponseDocument.Factory); + response = doc.getEbicsResponse(); + String code = response.getHeader().getMutable().getReturnCode(); + String text = response.getHeader().getMutable().getReportText(); + returnCode = ReturnCode.toReturnCode(code, text); + checkReturnCode(returnCode); + processBodyReturnCode(); + transactionId = response.getHeader().getStatic().getTransactionID(); + } protected void processBodyReturnCode() throws EbicsException { String bodyRetCode = response.getBody().getReturnCode().getStringValue(); @@ -81,7 +79,7 @@ public byte[] getTransactionId() { * @return the order type. */ public String getOrderType() { - return orderType.toString(); + return orderType.getCode(); } // -------------------------------------------------------------------- @@ -89,7 +87,7 @@ public String getOrderType() { // -------------------------------------------------------------------- protected EbicsResponse response; - private OrderType orderType; + private final EbicsOrderType orderType; private byte[] transactionId; private static final long serialVersionUID = 7684048385353175772L; } diff --git a/src/main/java/org/kopi/ebics/xml/KeyManagementResponseElement.java b/src/main/java/org/kopi/ebics/xml/KeyManagementResponseElement.java index dd3b678d..f43453cf 100644 --- a/src/main/java/org/kopi/ebics/xml/KeyManagementResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/KeyManagementResponseElement.java @@ -14,16 +14,16 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; +import org.apache.xmlbeans.impl.schema.DocumentFactory; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.schema.h003.EbicsKeyManagementResponseDocument; -import org.kopi.ebics.schema.h003.EbicsKeyManagementResponseDocument.EbicsKeyManagementResponse; +import org.kopi.ebics.schema.h005.EbicsKeyManagementResponseDocument; +import org.kopi.ebics.schema.h005.EbicsKeyManagementResponseDocument.EbicsKeyManagementResponse; /** * The KeyManagementResponseElement is the common element @@ -31,7 +31,6 @@ * returned code from the ebics server and throw an exception if it is * not an EBICS_OK code. * - * @author hachani * */ public class KeyManagementResponseElement extends DefaultResponseElement { @@ -58,25 +57,31 @@ public byte[] getTransactionKey() { * Returns the order data of the response. * @return the order data. */ - @SuppressWarnings("deprecation") public byte[] getOrderData() { - return response.getBody().getDataTransfer().getOrderData().byteArrayValue(); + return response.getBody().getDataTransfer().getOrderData().getByteArrayValue(); } @Override public void build() throws EbicsException { - String code; - String text; - - parse(factory); - response = ((EbicsKeyManagementResponseDocument)document).getEbicsKeyManagementResponse(); - code = response.getHeader().getMutable().getReturnCode(); - text = response.getHeader().getMutable().getReportText(); + var doc = parse(factory, EbicsKeyManagementResponseDocument.Factory); + response = doc.getEbicsKeyManagementResponse(); + String code = response.getHeader().getMutable().getReturnCode(); + String text = response.getHeader().getMutable().getReportText(); returnCode = ReturnCode.toReturnCode(code, text); report(); } - // -------------------------------------------------------------------- + @Override + public void report() throws EbicsException { + super.report(); + // there is a response code also in the body which needs to be checked + var bodyReturnCode = response.getBody().getReturnCode().getStringValue(); + var code = ReturnCode.toReturnCode(bodyReturnCode, "Code " + bodyReturnCode); + checkReturnCode(code); + } + + + // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- diff --git a/src/main/java/org/kopi/ebics/xml/NoPubKeyDigestsRequestElement.java b/src/main/java/org/kopi/ebics/xml/NoPubKeyDigestsRequestElement.java index ef3ce9df..645b7452 100644 --- a/src/main/java/org/kopi/ebics/xml/NoPubKeyDigestsRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/NoPubKeyDigestsRequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -25,14 +24,14 @@ import java.util.Calendar; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument; -import org.kopi.ebics.schema.h003.EmptyMutableHeaderType; -import org.kopi.ebics.schema.h003.NoPubKeyDigestsRequestStaticHeaderType; -import org.kopi.ebics.schema.h003.OrderDetailsType; -import org.kopi.ebics.schema.h003.ProductElementType; -import org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest; -import org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header; +import org.kopi.ebics.schema.h005.EbicsNoPubKeyDigestsRequestDocument; +import org.kopi.ebics.schema.h005.EmptyMutableHeaderType; +import org.kopi.ebics.schema.h005.NoPubKeyDigestsRequestStaticHeaderType; +import org.kopi.ebics.schema.h005.OrderDetailsType; +import org.kopi.ebics.schema.h005.ProductElementType; +import org.kopi.ebics.schema.h005.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest; +import org.kopi.ebics.schema.h005.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsNoPubKeyDigestsRequestDocument.EbicsNoPubKeyDigestsRequest.Header; import org.kopi.ebics.schema.xmldsig.SignatureType; import org.kopi.ebics.session.EbicsSession; import org.kopi.ebics.session.OrderType; @@ -42,7 +41,6 @@ * The NoPubKeyDigestsRequestElement is the root element * for a HPB ebics server request. * - * @author hachani * */ public class NoPubKeyDigestsRequestElement extends DefaultEbicsRootElement { @@ -65,16 +63,14 @@ public byte[] getDigest() throws EbicsException { try { return MessageDigest.getInstance("SHA-256", "BC").digest(Utils.canonize(toByteArray())); - } catch (NoSuchAlgorithmException e) { - throw new EbicsException(e.getMessage()); - } catch (NoSuchProviderException e) { + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { throw new EbicsException(e.getMessage()); } } /** * Sets the authentication signature of the NoPubKeyDigestsRequestElement - * @param authSignature the the authentication signature. + * @param authSignature the authentication signature. */ public void setAuthSignature(SignatureType authSignature) { ((EbicsNoPubKeyDigestsRequestDocument)document).getEbicsNoPubKeyDigestsRequest().setAuthSignature(authSignature); @@ -99,7 +95,7 @@ public void build() throws EbicsException { OrderDetailsType orderDetails; product = EbicsXmlFactory.creatProductElementType(session.getProduct().getLanguage(), session.getProduct().getName()); - orderDetails = EbicsXmlFactory.createOrderDetailsType("DZHNN", null, OrderType.HPB.toString()); + orderDetails = EbicsXmlFactory.createOrderDetailsType(OrderType.HPB.getCode()); xstatic = EbicsXmlFactory.createNoPubKeyDigestsRequestStaticHeaderType(session.getBankID(), Utils.generateNonce(), Calendar.getInstance(), diff --git a/src/main/java/org/kopi/ebics/xml/ReceiptRequestElement.java b/src/main/java/org/kopi/ebics/xml/ReceiptRequestElement.java index 60fcccfa..9ba09975 100644 --- a/src/main/java/org/kopi/ebics/xml/ReceiptRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/ReceiptRequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -24,13 +23,13 @@ import java.security.NoSuchProviderException; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.EbicsRequestDocument; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.StaticHeaderType; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body.TransferReceipt; +import org.kopi.ebics.schema.h005.EbicsRequestDocument; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.StaticHeaderType; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body.TransferReceipt; import org.kopi.ebics.session.EbicsSession; import org.kopi.ebics.utils.Utils; @@ -39,7 +38,6 @@ * The ReceiptRequestElement is the element containing the * receipt request to tell the server bank that all segments are received. * - * @author Hachani * */ public class ReceiptRequestElement extends DefaultEbicsRootElement { @@ -117,7 +115,7 @@ public byte[] getDigest() throws EbicsException { // DATA MEMBERS // -------------------------------------------------------------------- - private byte[] transactionId; - private String name; + private final byte[] transactionId; + private final String name; private static final long serialVersionUID = -1969616441705744725L; } diff --git a/src/main/java/org/kopi/ebics/xml/ReceiptResponseElement.java b/src/main/java/org/kopi/ebics/xml/ReceiptResponseElement.java index 449cfb33..7cfc859a 100644 --- a/src/main/java/org/kopi/ebics/xml/ReceiptResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/ReceiptResponseElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -22,14 +21,12 @@ import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.schema.h003.EbicsResponseDocument; -import org.kopi.ebics.schema.h003.EbicsResponseDocument.EbicsResponse; +import org.kopi.ebics.schema.h005.EbicsResponseDocument; /** * The ReceiptResponseElement is the response element * for ebics receipt request. * - * @author Hachani * */ public class ReceiptResponseElement extends DefaultResponseElement { @@ -45,16 +42,12 @@ public ReceiptResponseElement(ContentFactory factory, String name) { @Override public void build() throws EbicsException { - String code; - String text; - EbicsResponse response; - - parse(factory); - response = ((EbicsResponseDocument)document).getEbicsResponse(); - code = response.getHeader().getMutable().getReturnCode(); - text = response.getHeader().getMutable().getReportText(); - returnCode = ReturnCode.toReturnCode(code, text); - report(); + var doc = parse(factory, EbicsResponseDocument.Factory); + var response = doc.getEbicsResponse(); + String code = response.getHeader().getMutable().getReturnCode(); + String text = response.getHeader().getMutable().getReportText(); + returnCode = ReturnCode.toReturnCode(code, text); + report(); } @Override diff --git a/src/main/java/org/kopi/ebics/xml/SPRRequestElement.java b/src/main/java/org/kopi/ebics/xml/SPRRequestElement.java index 6bed752d..d636ccd0 100644 --- a/src/main/java/org/kopi/ebics/xml/SPRRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/SPRRequestElement.java @@ -14,34 +14,31 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import java.util.Calendar; -import javax.crypto.spec.SecretKeySpec; - import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.DataEncryptionInfoType.EncryptionPubKeyDigest; -import org.kopi.ebics.schema.h003.DataTransferRequestType; -import org.kopi.ebics.schema.h003.DataTransferRequestType.DataEncryptionInfo; -import org.kopi.ebics.schema.h003.DataTransferRequestType.SignatureData; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.OrderAttributeType; -import org.kopi.ebics.schema.h003.StandardOrderParamsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType.OrderType; -import org.kopi.ebics.schema.h003.StaticHeaderType; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Authentication; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Encryption; -import org.kopi.ebics.schema.h003.StaticHeaderType.Product; +import org.kopi.ebics.schema.h005.DataEncryptionInfoType.EncryptionPubKeyDigest; +import org.kopi.ebics.schema.h005.DataTransferRequestType; +import org.kopi.ebics.schema.h005.DataTransferRequestType.DataEncryptionInfo; +import org.kopi.ebics.schema.h005.DataTransferRequestType.SignatureData; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.StandardOrderParamsDocument; +import org.kopi.ebics.schema.h005.StandardOrderParamsType; +import org.kopi.ebics.schema.h005.StaticHeaderOrderDetailsType; +import org.kopi.ebics.schema.h005.StaticHeaderType; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Authentication; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Encryption; +import org.kopi.ebics.schema.h005.StaticHeaderType.Product; import org.kopi.ebics.session.EbicsSession; +import org.kopi.ebics.session.OrderType; import org.kopi.ebics.utils.Utils; @@ -49,7 +46,6 @@ * The SPRRequestElement is the request element * for revoking a subscriber * - * @author Hachani * */ public class SPRRequestElement extends InitializationRequestElement { @@ -58,9 +54,8 @@ public class SPRRequestElement extends InitializationRequestElement { * Constructs a new SPR request element. * @param session the current ebic session. */ - public SPRRequestElement(EbicsSession session) throws EbicsException { - super(session, org.kopi.ebics.session.OrderType.SPR, "SPRRequest.xml"); - keySpec = new SecretKeySpec(nonce, "EAS"); + public SPRRequestElement(EbicsSession session) { + super(session, OrderType.SPR, "SPRRequest.xml"); } @Override @@ -79,7 +74,6 @@ public void buildInitialization() throws EbicsException { SignatureData signatureData; EncryptionPubKeyDigest encryptionPubKeyDigest; StaticHeaderOrderDetailsType orderDetails; - OrderType orderType; StandardOrderParamsType standardOrderParamsType; UserSignature userSignature; @@ -99,12 +93,13 @@ public void buildInitialization() throws EbicsException { "http://www.w3.org/2001/04/xmlenc#sha256", decodeHex(session.getUser().getPartner().getBank().getE002Digest())); bankPubKeyDigests = EbicsXmlFactory.createBankPubKeyDigests(authentication, encryption); - orderType = EbicsXmlFactory.createOrderType(type.toString()); standardOrderParamsType = EbicsXmlFactory.createStandardOrderParamsType(); - orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(session.getUser().getPartner().nextOrderId(), - OrderAttributeType.UZHNN, - orderType, - standardOrderParamsType); + var type = StaticHeaderOrderDetailsType.AdminOrderType.Factory.newInstance(); + type.setStringValue(this.getType()); + + orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(session.getUser().getPartner().nextOrderId(), type, + standardOrderParamsType, + StandardOrderParamsDocument.type); xstatic = EbicsXmlFactory.createStaticHeaderType(session.getBankID(), nonce, 0, @@ -123,7 +118,7 @@ public void buildInitialization() throws EbicsException { dataEncryptionInfo = EbicsXmlFactory.createDataEncryptionInfo(true, encryptionPubKeyDigest, generateTransactionKey()); - dataTransfer = EbicsXmlFactory.createDataTransferRequestType(dataEncryptionInfo, signatureData); + dataTransfer = EbicsXmlFactory.createDataTransferRequestType(dataEncryptionInfo, signatureData, null); body = EbicsXmlFactory.createEbicsRequestBody(dataTransfer); request = EbicsXmlFactory.createEbicsRequest(session.getConfiguration().getRevision(), session.getConfiguration().getVersion(), @@ -136,6 +131,5 @@ public void buildInitialization() throws EbicsException { // DATA MEMBERS // -------------------------------------------------------------------- - private SecretKeySpec keySpec; private static final long serialVersionUID = -6742241777786111337L; } diff --git a/src/main/java/org/kopi/ebics/xml/SPRResponseElement.java b/src/main/java/org/kopi/ebics/xml/SPRResponseElement.java index 015e3c24..8aa45301 100644 --- a/src/main/java/org/kopi/ebics/xml/SPRResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/SPRResponseElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -22,14 +21,13 @@ import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.schema.h003.EbicsResponseDocument; -import org.kopi.ebics.schema.h003.EbicsResponseDocument.EbicsResponse; +import org.kopi.ebics.schema.h005.EbicsResponseDocument; +import org.kopi.ebics.schema.h005.EbicsResponseDocument.EbicsResponse; /** * The SPRResponseElement is the response element * for an ebics subscriber revoking. * - * @author Hachani * */ public class SPRResponseElement extends DefaultResponseElement { @@ -44,13 +42,10 @@ public SPRResponseElement(ContentFactory factory) { @Override public void build() throws EbicsException { - String code; - String text; - - parse(factory); - response = ((EbicsResponseDocument)document).getEbicsResponse(); - code = response.getHeader().getMutable().getReturnCode(); - text = response.getHeader().getMutable().getReportText(); + var doc = parse(factory, EbicsResponseDocument.Factory); + response =doc.getEbicsResponse(); + String code = response.getHeader().getMutable().getReturnCode(); + String text = response.getHeader().getMutable().getReportText(); returnCode = ReturnCode.toReturnCode(code, text); report(); } diff --git a/src/main/java/org/kopi/ebics/xml/SignaturePubKeyOrderDataElement.java b/src/main/java/org/kopi/ebics/xml/SignaturePubKeyOrderDataElement.java index 86b99964..2a325810 100644 --- a/src/main/java/org/kopi/ebics/xml/SignaturePubKeyOrderDataElement.java +++ b/src/main/java/org/kopi/ebics/xml/SignaturePubKeyOrderDataElement.java @@ -14,17 +14,14 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; -import java.util.Calendar; - +import org.ebics.s002.SignaturePubKeyInfoType; +import org.ebics.s002.SignaturePubKeyOrderDataType; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.s001.PubKeyValueType; -import org.kopi.ebics.schema.s001.SignaturePubKeyInfoType; -import org.kopi.ebics.schema.s001.SignaturePubKeyOrderDataType; + import org.kopi.ebics.schema.xmldsig.RSAKeyValueType; import org.kopi.ebics.schema.xmldsig.X509DataType; import org.kopi.ebics.session.EbicsSession; @@ -34,7 +31,6 @@ * The SignaturePubKeyOrderDataElement is the order data * component for the INI request. * - * @author hachani * */ public class SignaturePubKeyOrderDataElement extends DefaultEbicsRootElement { @@ -47,29 +43,23 @@ public SignaturePubKeyOrderDataElement(EbicsSession session) { super(session); } - @Override - public void build() throws EbicsException { - SignaturePubKeyInfoType signaturePubKeyInfo; - X509DataType x509Data; - RSAKeyValueType rsaKeyValue; - PubKeyValueType pubKeyValue; - SignaturePubKeyOrderDataType signaturePubKeyOrderData; + @Override + public void build() throws EbicsException { + X509DataType x509Data = EbicsXmlFactory.createX509DataType(session.getUser().getDN(), + session.getUser().getA005Certificate()); - x509Data = null; - if (session.getUser().getPartner().getBank().useCertificate()) - x509Data = EbicsXmlFactory.createX509DataType(session.getUser().getDN(), - session.getUser().getA005Certificate()); - rsaKeyValue = EbicsXmlFactory.createRSAKeyValueType(session.getUser().getA005PublicKey().getPublicExponent().toByteArray(), - session.getUser().getA005PublicKey().getModulus().toByteArray()); - pubKeyValue = EbicsXmlFactory.createPubKeyValueType(rsaKeyValue, Calendar.getInstance()); - signaturePubKeyInfo = EbicsXmlFactory.createSignaturePubKeyInfoType(x509Data, - pubKeyValue, - session.getConfiguration().getSignatureVersion()); - signaturePubKeyOrderData = EbicsXmlFactory.createSignaturePubKeyOrderData(signaturePubKeyInfo, - session.getUser().getPartner().getPartnerId(), - session.getUser().getUserId()); - document = EbicsXmlFactory.createSignaturePubKeyOrderDataDocument(signaturePubKeyOrderData); - } + var rsaKeyValue = EbicsXmlFactory.createRSAKeyValueType( + session.getUser().getA005PublicKey().getPublicExponent().toByteArray(), + session.getUser().getA005PublicKey().getModulus().toByteArray()); + //var pubKeyValue = EbicsXmlFactory.createPubKeyValueType(rsaKeyValue, Calendar.getInstance()); + var signaturePubKeyInfo = EbicsXmlFactory.createSignaturePubKeyInfoType(x509Data, null, + // pubKeyValue, + session.getConfiguration().getSignatureVersion()); + var signaturePubKeyOrderData = EbicsXmlFactory.createSignaturePubKeyOrderData( + signaturePubKeyInfo, session.getUser().getPartner().getPartnerId(), + session.getUser().getUserId()); + document = EbicsXmlFactory.createSignaturePubKeyOrderDataDocument(signaturePubKeyOrderData); + } @Override public String getName() { @@ -79,7 +69,7 @@ public String getName() { @Override public byte[] toByteArray() { addNamespaceDecl("ds", "http://www.w3.org/2000/09/xmldsig#"); - setSaveSuggestedPrefixes("http://www.ebics.org/S001", ""); + setSaveSuggestedPrefixes("http://www.ebics.org/S002", ""); return super.toByteArray(); } diff --git a/src/main/java/org/kopi/ebics/xml/SignedInfo.java b/src/main/java/org/kopi/ebics/xml/SignedInfo.java index fe805f71..f249d17e 100644 --- a/src/main/java/org/kopi/ebics/xml/SignedInfo.java +++ b/src/main/java/org/kopi/ebics/xml/SignedInfo.java @@ -14,20 +14,21 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import org.apache.xml.security.c14n.Canonicalizer; import org.apache.xml.security.transforms.TransformationException; import org.apache.xml.security.utils.IgnoreAllErrorHandler; -import org.apache.xpath.XPathAPI; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.EbicsUser; import org.kopi.ebics.schema.xmldsig.CanonicalizationMethodType; @@ -101,7 +102,6 @@ public byte[] getDigest() { /** * Returns the signed info element as an XmlObject * @return he signed info element - * @throws EbicsException user Signature and Canonicalization errors */ public SignatureType getSignatureType() { return ((SignatureType)document); @@ -133,7 +133,6 @@ public byte[] sign(byte[] toSign) throws EbicsException { DocumentBuilderFactory factory; DocumentBuilder builder; Document document; - Node node; Canonicalizer canonicalizer; factory = DocumentBuilderFactory.newInstance(); @@ -142,9 +141,12 @@ public byte[] sign(byte[] toSign) throws EbicsException { builder = factory.newDocumentBuilder(); builder.setErrorHandler(new IgnoreAllErrorHandler()); document = builder.parse(new ByteArrayInputStream(toSign)); - node = XPathAPI.selectSingleNode(document, "//ds:SignedInfo"); + Node node = (Node) XPathFactory.newInstance().newXPath() + .evaluate("//*[name()='ds:SignedInfo']", document, XPathConstants.NODE); canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); - return user.authenticate(canonicalizer.canonicalizeSubtree(node)); + var bos = new ByteArrayOutputStream(); + canonicalizer.canonicalizeSubtree(node, bos); + return user.authenticate(bos.toByteArray()); } catch(Exception e) { throw new EbicsException(e.getMessage()); } @@ -167,7 +169,7 @@ public String getName() { // DATA MEMBERS // -------------------------------------------------------------------- - private byte[] digest; - private EbicsUser user; + private final byte[] digest; + private final EbicsUser user; private static final long serialVersionUID = 4194924578678778580L; } diff --git a/src/main/java/org/kopi/ebics/xml/TransferRequestElement.java b/src/main/java/org/kopi/ebics/xml/TransferRequestElement.java index e833abb4..baa55e68 100644 --- a/src/main/java/org/kopi/ebics/xml/TransferRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/TransferRequestElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -24,9 +23,9 @@ import java.security.NoSuchProviderException; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.EbicsRequestDocument; +import org.kopi.ebics.interfaces.EbicsOrderType; +import org.kopi.ebics.schema.h005.EbicsRequestDocument; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; import org.kopi.ebics.utils.Utils; @@ -34,7 +33,6 @@ * The TransferRequestElement is the common root element * for all ebics transfer for the bank server. * - * @author Hachani * */ public abstract class TransferRequestElement extends DefaultEbicsRootElement { @@ -46,11 +44,11 @@ public abstract class TransferRequestElement extends DefaultEbicsRootElement { * @param type the order type * @param segmentNumber the segment number to be sent * @param lastSegment is it the last segment? - * @param transactionID the transaction ID + * @param transactionId the transaction ID */ - public TransferRequestElement(EbicsSession session, + protected TransferRequestElement(EbicsSession session, String name, - OrderType type, + EbicsOrderType type, int segmentNumber, boolean lastSegment, byte[] transactionId) @@ -89,9 +87,7 @@ public byte[] getDigest() throws EbicsException { try { return MessageDigest.getInstance("SHA-256", "BC").digest(Utils.canonize(toByteArray())); - } catch (NoSuchAlgorithmException e) { - throw new EbicsException(e.getMessage()); - } catch (NoSuchProviderException e) { + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { throw new EbicsException(e.getMessage()); } } @@ -101,7 +97,7 @@ public byte[] getDigest() throws EbicsException { * @return the order type element. */ public String getOrderType() { - return type.toString(); + return type.getCode(); } @Override @@ -124,7 +120,7 @@ public byte[] toByteArray() { protected int segmentNumber; protected boolean lastSegment; protected byte[] transactionId; - private OrderType type; - private String name; + private final EbicsOrderType type; + private final String name; private static final long serialVersionUID = -4212072825371398259L; } diff --git a/src/main/java/org/kopi/ebics/xml/TransferResponseElement.java b/src/main/java/org/kopi/ebics/xml/TransferResponseElement.java index d2b35f75..c8f8a9bd 100644 --- a/src/main/java/org/kopi/ebics/xml/TransferResponseElement.java +++ b/src/main/java/org/kopi/ebics/xml/TransferResponseElement.java @@ -14,7 +14,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; @@ -22,14 +21,13 @@ import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.exception.ReturnCode; import org.kopi.ebics.interfaces.ContentFactory; -import org.kopi.ebics.schema.h003.EbicsResponseDocument; -import org.kopi.ebics.schema.h003.EbicsResponseDocument.EbicsResponse; +import org.kopi.ebics.schema.h005.EbicsResponseDocument; +import org.kopi.ebics.schema.h005.EbicsResponseDocument.EbicsResponse; /** * The TransferResponseElement is the common element * response for all ebics transfers. * - * @author Hachani * */ public class TransferResponseElement extends DefaultResponseElement { @@ -37,7 +35,6 @@ public class TransferResponseElement extends DefaultResponseElement { /** * Constructs a new TransferResponseElement element. * @param factory the content factory - * @param orderType the order type * @param name the element name; */ public TransferResponseElement(ContentFactory factory, String name) { @@ -46,13 +43,10 @@ public TransferResponseElement(ContentFactory factory, String name) { @Override public void build() throws EbicsException { - String code; - String text; - - parse(factory); - response = ((EbicsResponseDocument)document).getEbicsResponse(); - code = response.getHeader().getMutable().getReturnCode(); - text = response.getHeader().getMutable().getReportText(); + var doc = parse(factory, EbicsResponseDocument.Factory); + response = doc.getEbicsResponse(); + String code = response.getHeader().getMutable().getReturnCode(); + String text = response.getHeader().getMutable().getReportText(); returnCode = ReturnCode.toReturnCode(code, text); report(); } diff --git a/src/main/java/org/kopi/ebics/xml/UnsecuredRequestElement.java b/src/main/java/org/kopi/ebics/xml/UnsecuredRequestElement.java index 55b048dc..9e2b496f 100644 --- a/src/main/java/org/kopi/ebics/xml/UnsecuredRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/UnsecuredRequestElement.java @@ -14,29 +14,27 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import org.kopi.ebics.exception.EbicsException; -import org.kopi.ebics.schema.h003.EmptyMutableHeaderType; -import org.kopi.ebics.schema.h003.OrderDetailsType; -import org.kopi.ebics.schema.h003.ProductElementType; -import org.kopi.ebics.schema.h003.UnsecuredRequestStaticHeaderType; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Header; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer; -import org.kopi.ebics.schema.h003.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer.OrderData; +import org.kopi.ebics.interfaces.EbicsOrderType; +import org.kopi.ebics.schema.h005.EmptyMutableHeaderType; +import org.kopi.ebics.schema.h005.OrderDetailsType; +import org.kopi.ebics.schema.h005.ProductElementType; +import org.kopi.ebics.schema.h005.UnsecuredRequestStaticHeaderType; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Header; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer; +import org.kopi.ebics.schema.h005.EbicsUnsecuredRequestDocument.EbicsUnsecuredRequest.Body.DataTransfer.OrderData; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; /** * The UnsecuredRequestElement is the common element * used for key management requests. * - * @author hachani * */ public class UnsecuredRequestElement extends DefaultEbicsRootElement { @@ -48,7 +46,7 @@ public class UnsecuredRequestElement extends DefaultEbicsRootElement { * @param orderId the order id, if null a random one is generated. */ public UnsecuredRequestElement(EbicsSession session, - OrderType orderType, + EbicsOrderType orderType, String orderId, byte[] orderData) { @@ -70,9 +68,7 @@ public void build() throws EbicsException { OrderData orderData; EbicsUnsecuredRequest request; - orderDetails = EbicsXmlFactory.createOrderDetailsType("DZNNN", - orderId == null ? session.getUser().getPartner().nextOrderId() : orderId, - orderType.toString()); + orderDetails = EbicsXmlFactory.createOrderDetailsType(orderType.getCode()); productType = EbicsXmlFactory.creatProductElementType(session.getProduct().getLanguage(), session.getProduct().getName()); @@ -105,12 +101,14 @@ public String getName() { return "UnsecuredRequest.xml"; } + + // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- - private OrderType orderType; - private String orderId; - private byte[] orderData; + private final EbicsOrderType orderType; + private final String orderId; + private final byte[] orderData; private static final long serialVersionUID = -3548730114599886711L; } diff --git a/src/main/java/org/kopi/ebics/xml/UploadInitializationRequestElement.java b/src/main/java/org/kopi/ebics/xml/UploadInitializationRequestElement.java index e9fd2fee..701147b6 100644 --- a/src/main/java/org/kopi/ebics/xml/UploadInitializationRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/UploadInitializationRequestElement.java @@ -14,41 +14,39 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import javax.crypto.spec.SecretKeySpec; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Base64; +import java.util.Calendar; +import org.apache.xmlbeans.XmlObject; +import org.kopi.ebics.client.EbicsUploadParams; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; +import org.kopi.ebics.interfaces.EbicsOrderType; import org.kopi.ebics.io.Splitter; -import org.kopi.ebics.schema.h003.DataEncryptionInfoType.EncryptionPubKeyDigest; -import org.kopi.ebics.schema.h003.DataTransferRequestType; -import org.kopi.ebics.schema.h003.DataTransferRequestType.DataEncryptionInfo; -import org.kopi.ebics.schema.h003.DataTransferRequestType.SignatureData; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header; -import org.kopi.ebics.schema.h003.FULOrderParamsType; -import org.kopi.ebics.schema.h003.FileFormatType; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.OrderAttributeType; -import org.kopi.ebics.schema.h003.ParameterDocument.Parameter; -import org.kopi.ebics.schema.h003.ParameterDocument.Parameter.Value; -import org.kopi.ebics.schema.h003.StandardOrderParamsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType; -import org.kopi.ebics.schema.h003.StaticHeaderOrderDetailsType.OrderType; -import org.kopi.ebics.schema.h003.StaticHeaderType; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Authentication; -import org.kopi.ebics.schema.h003.StaticHeaderType.BankPubKeyDigests.Encryption; -import org.kopi.ebics.schema.h003.StaticHeaderType.Product; +import org.kopi.ebics.schema.h005.BTUOrderParamsDocument; +import org.kopi.ebics.schema.h005.DataEncryptionInfoType.EncryptionPubKeyDigest; +import org.kopi.ebics.schema.h005.DataTransferRequestType; +import org.kopi.ebics.schema.h005.DataTransferRequestType.DataEncryptionInfo; +import org.kopi.ebics.schema.h005.DataTransferRequestType.SignatureData; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.StandardOrderParamsType; +import org.kopi.ebics.schema.h005.StaticHeaderOrderDetailsType; +import org.kopi.ebics.schema.h005.StaticHeaderType; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Authentication; +import org.kopi.ebics.schema.h005.StaticHeaderType.BankPubKeyDigests.Encryption; +import org.kopi.ebics.schema.h005.StaticHeaderType.Product; import org.kopi.ebics.session.EbicsSession; import org.kopi.ebics.utils.Utils; @@ -57,7 +55,6 @@ * The UInitializationRequestElement is the common initialization * element for all ebics file uploads. * - * @author Hachani * */ public class UploadInitializationRequestElement extends InitializationRequestElement { @@ -68,128 +65,86 @@ public class UploadInitializationRequestElement extends InitializationRequestEle * @param session the current ebics session. * @param orderType the upload order type * @param userData the user data to be uploaded - * @throws EbicsException - */ - public UploadInitializationRequestElement(EbicsSession session, - org.kopi.ebics.session.OrderType orderType, OrderAttributeType.Enum orderAttribute, - byte[] userData) - throws EbicsException - { - super(session, orderType, generateName(orderType)); - this.userData = userData; - keySpec = new SecretKeySpec(nonce, "EAS"); - splitter = new Splitter(userData); - this.orderAttribute = orderAttribute; - } - - @Override - public void buildInitialization() throws EbicsException { - EbicsRequest request; - Header header; - Body body; - MutableHeaderType mutable; - StaticHeaderType xstatic; - Product product; - BankPubKeyDigests bankPubKeyDigests; - Authentication authentication; - Encryption encryption; - DataTransferRequestType dataTransfer; - DataEncryptionInfo dataEncryptionInfo; - SignatureData signatureData; - EncryptionPubKeyDigest encryptionPubKeyDigest; - OrderType orderType; - FileFormatType fileFormat; - - userSignature = new UserSignature(session.getUser(), - generateName("UserSignature"), - session.getConfiguration().getSignatureVersion(), - userData); - userSignature.build(); - userSignature.validate(); - - splitter.readInput(session.getConfiguration().isCompressionEnabled(), keySpec); - - mutable = EbicsXmlFactory.createMutableHeaderType("Initialisation", null); - product = EbicsXmlFactory.createProduct(session.getProduct().getLanguage(), session.getProduct().getName()); - authentication = EbicsXmlFactory.createAuthentication(session.getConfiguration().getAuthenticationVersion(), - "http://www.w3.org/2001/04/xmlenc#sha256", - decodeHex(session.getUser().getPartner().getBank().getX002Digest())); - encryption = EbicsXmlFactory.createEncryption(session.getConfiguration().getEncryptionVersion(), - "http://www.w3.org/2001/04/xmlenc#sha256", - decodeHex(session.getUser().getPartner().getBank().getE002Digest())); - bankPubKeyDigests = EbicsXmlFactory.createBankPubKeyDigests(authentication, encryption); - orderType = EbicsXmlFactory.createOrderType(type.toString()); - fileFormat = EbicsXmlFactory.createFileFormatType(session.getConfiguration().getLocale().getCountry().toUpperCase(), - session.getSessionParam("FORMAT")); - - String nextOrderId = session.getUser().getPartner().nextOrderId(); - - StaticHeaderOrderDetailsType orderDetails; - if (type == org.kopi.ebics.session.OrderType.FUL) { - FULOrderParamsType fULOrderParams = EbicsXmlFactory.createFULOrderParamsType(fileFormat); - - List parameters = new ArrayList<>(); - if (Boolean.valueOf(session.getSessionParam("TEST")).booleanValue()) { - Value value = EbicsXmlFactory.createValue("String", "TRUE"); - Parameter parameter = EbicsXmlFactory.createParameter("TEST", value); - parameters.add(parameter); - } + */ + public UploadInitializationRequestElement(EbicsSession session, EbicsOrderType orderType, + EbicsUploadParams params, + byte[] userData) { + super(session, orderType, generateName(orderType)); + setSaveSuggestedPrefixes("urn:org:ebics:H005", ""); + this.userData = userData; + splitter = new Splitter(userData); + this.uploadParams = params; + } - if (Boolean.valueOf(session.getSessionParam("EBCDIC")).booleanValue()) { - Value value = EbicsXmlFactory.createValue("String", "TRUE"); - Parameter parameter = EbicsXmlFactory.createParameter("EBCDIC", value); - parameters.add(parameter); + @Override + public void buildInitialization() throws EbicsException { + userSignature = new UserSignature(session.getUser(), generateName("UserSignature"), + session.getConfiguration().getSignatureVersion(), userData); + userSignature.build(); + userSignature.validate(); + + splitter.readInput(session.getConfiguration().isCompressionEnabled(), keySpec); + + var mutable = EbicsXmlFactory.createMutableHeaderType("Initialisation", null); + var product = EbicsXmlFactory.createProduct(session.getProduct().getLanguage(), + session.getProduct().getName()); + var authentication = EbicsXmlFactory.createAuthentication( + session.getConfiguration().getAuthenticationVersion(), + "http://www.w3.org/2001/04/xmlenc#sha256", + decodeHex(session.getUser().getPartner().getBank().getX002Digest())); + var encryption = EbicsXmlFactory.createEncryption( + session.getConfiguration().getEncryptionVersion(), + "http://www.w3.org/2001/04/xmlenc#sha256", + decodeHex(session.getUser().getPartner().getBank().getE002Digest())); + var bankPubKeyDigests = EbicsXmlFactory.createBankPubKeyDigests(authentication, encryption); + + String nextOrderId = uploadParams.orderId(); + + var type = StaticHeaderOrderDetailsType.AdminOrderType.Factory.newInstance(); + type.setStringValue(this.getType()); + + var orderParamsType = (XmlObject) EbicsXmlFactory.createStandardOrderParamsType(); + var orderParamsSchema = StandardOrderParamsType.type; + + if (uploadParams.orderParams() != null) { + var p = uploadParams.orderParams(); + orderParamsType = EbicsXmlFactory.createBTUParams(p.serviceName(), p.scope(), + p.option(), p.messageName(), p.messageVersion(), p.signatureFlag()); + orderParamsSchema = BTUOrderParamsDocument.type; } - if (parameters.size() > 0) { - fULOrderParams.setParameterArray(parameters.toArray(new Parameter[parameters.size()])); + StaticHeaderOrderDetailsType orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType( + nextOrderId, type, orderParamsType,orderParamsSchema); + + var xstatic = EbicsXmlFactory.createStaticHeaderType(session.getBankID(), nonce, + splitter.getSegmentNumber(), session.getUser().getPartner().getPartnerId(), product, + session.getUser().getSecurityMedium(), session.getUser().getUserId(), + Calendar.getInstance(), orderDetails, bankPubKeyDigests); + var header = EbicsXmlFactory.createEbicsRequestHeader(true, mutable, xstatic); + var encryptionPubKeyDigest = EbicsXmlFactory.createEncryptionPubKeyDigest( + session.getConfiguration().getEncryptionVersion(), + "http://www.w3.org/2001/04/xmlenc#sha256", + decodeHex(session.getUser().getPartner().getBank().getE002Digest())); + var signatureData = EbicsXmlFactory.createSignatureData(true, + Utils.encrypt(Utils.zip(userSignature.prettyPrint()), keySpec)); + var dataEncryptionInfo = EbicsXmlFactory.createDataEncryptionInfo(true, + encryptionPubKeyDigest, generateTransactionKey()); + + String digest; + try { + // TODO: check if this is correct + digest = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256", "BC").digest(this.userData)); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + throw new EbicsException(e); } - orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(nextOrderId, - orderAttribute, - orderType, - fULOrderParams); - } else { - StandardOrderParamsType standardOrderParamsType = EbicsXmlFactory.createStandardOrderParamsType(); - orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(nextOrderId, - orderAttribute, - orderType, - standardOrderParamsType); + var dataTransfer = EbicsXmlFactory.createDataTransferRequestType(dataEncryptionInfo, + signatureData, digest); + var body = EbicsXmlFactory.createEbicsRequestBody(dataTransfer); + var request = EbicsXmlFactory.createEbicsRequest(session.getConfiguration().getRevision(), + session.getConfiguration().getVersion(), header, body); + document = EbicsXmlFactory.createEbicsRequestDocument(request); } - xstatic = EbicsXmlFactory.createStaticHeaderType(session.getBankID(), - nonce, - splitter.getSegmentNumber(), - session.getUser().getPartner().getPartnerId(), - product, - session.getUser().getSecurityMedium(), - session.getUser().getUserId(), - Calendar.getInstance(), - orderDetails, - bankPubKeyDigests); - header = EbicsXmlFactory.createEbicsRequestHeader(true, mutable, xstatic); - encryptionPubKeyDigest = EbicsXmlFactory.createEncryptionPubKeyDigest(session.getConfiguration().getEncryptionVersion(), - "http://www.w3.org/2001/04/xmlenc#sha256", - decodeHex(session.getUser().getPartner().getBank().getE002Digest())); - signatureData = EbicsXmlFactory.createSignatureData(true, Utils.encrypt(Utils.zip(userSignature.prettyPrint()), keySpec)); - dataEncryptionInfo = EbicsXmlFactory.createDataEncryptionInfo(true, - encryptionPubKeyDigest, - generateTransactionKey()); - dataTransfer = EbicsXmlFactory.createDataTransferRequestType(dataEncryptionInfo, signatureData); - body = EbicsXmlFactory.createEbicsRequestBody(dataTransfer); - request = EbicsXmlFactory.createEbicsRequest(session.getConfiguration().getRevision(), - session.getConfiguration().getVersion(), - header, - body); - document = EbicsXmlFactory.createEbicsRequestDocument(request); - } - - @Override - public byte[] toByteArray() { - setSaveSuggestedPrefixes("http://www.ebics.org/H003", ""); - - return super.toByteArray(); - } - /** * Returns the user signature data. * @return the user signature data. @@ -218,11 +173,9 @@ public int getSegmentNumber() { // -------------------------------------------------------------------- // DATA MEMBERS // -------------------------------------------------------------------- - - private final OrderAttributeType.Enum orderAttribute; - private byte[] userData; + private final EbicsUploadParams uploadParams; + private final byte[] userData; private UserSignature userSignature; - private SecretKeySpec keySpec; - private Splitter splitter; + private final Splitter splitter; private static final long serialVersionUID = -8083183483311283608L; } diff --git a/src/main/java/org/kopi/ebics/xml/UploadTransferRequestElement.java b/src/main/java/org/kopi/ebics/xml/UploadTransferRequestElement.java index abf6899f..3f9bc3ef 100644 --- a/src/main/java/org/kopi/ebics/xml/UploadTransferRequestElement.java +++ b/src/main/java/org/kopi/ebics/xml/UploadTransferRequestElement.java @@ -14,30 +14,28 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.ContentFactory; +import org.kopi.ebics.interfaces.EbicsOrderType; import org.kopi.ebics.io.IOUtils; -import org.kopi.ebics.schema.h003.DataTransferRequestType; -import org.kopi.ebics.schema.h003.DataTransferRequestType.OrderData; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Body; -import org.kopi.ebics.schema.h003.EbicsRequestDocument.EbicsRequest.Header; -import org.kopi.ebics.schema.h003.MutableHeaderType; -import org.kopi.ebics.schema.h003.MutableHeaderType.SegmentNumber; -import org.kopi.ebics.schema.h003.StaticHeaderType; +import org.kopi.ebics.schema.h005.DataTransferRequestType; +import org.kopi.ebics.schema.h005.DataTransferRequestType.OrderData; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body; +import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header; +import org.kopi.ebics.schema.h005.MutableHeaderType; +import org.kopi.ebics.schema.h005.MutableHeaderType.SegmentNumber; +import org.kopi.ebics.schema.h005.StaticHeaderType; import org.kopi.ebics.session.EbicsSession; -import org.kopi.ebics.session.OrderType; /** * The UTransferRequestElement is the root element * for all ebics upload transfers. * - * @author Hachani * */ public class UploadTransferRequestElement extends TransferRequestElement { @@ -52,7 +50,7 @@ public class UploadTransferRequestElement extends TransferRequestElement { * @param content the content factory */ public UploadTransferRequestElement(EbicsSession session, - OrderType orderType, + EbicsOrderType orderType, int segmentNumber, boolean lastSegment, byte[] transactionId, @@ -91,6 +89,6 @@ public void buildTransfer() throws EbicsException { // DATA MEMBERS // -------------------------------------------------------------------- - private ContentFactory content; + private final ContentFactory content; private static final long serialVersionUID = 8465397978597444978L; } diff --git a/src/main/java/org/kopi/ebics/xml/UserSignature.java b/src/main/java/org/kopi/ebics/xml/UserSignature.java index 3ca8a3d7..0f665c02 100644 --- a/src/main/java/org/kopi/ebics/xml/UserSignature.java +++ b/src/main/java/org/kopi/ebics/xml/UserSignature.java @@ -14,20 +14,17 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ */ package org.kopi.ebics.xml; import java.io.IOException; import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import org.apache.commons.codec.binary.Hex; +import org.ebics.s002.OrderSignatureDataType; +import org.ebics.s002.UserSignatureDataSigBookType; import org.kopi.ebics.exception.EbicsException; import org.kopi.ebics.interfaces.EbicsUser; -import org.kopi.ebics.schema.s001.OrderSignatureDataType; -import org.kopi.ebics.schema.s001.UserSignatureDataSigBookType; /** @@ -35,7 +32,6 @@ * element. The user data is signed with the user signature * key sent in the INI request to the EBICS bank server * - * @author hachani * */ public class UserSignature extends DefaultEbicsRootElement { @@ -60,8 +56,8 @@ public UserSignature(EbicsUser user, @Override public void build() throws EbicsException { - UserSignatureDataSigBookType userSignatureData; - OrderSignatureDataType orderSignatureData; + UserSignatureDataSigBookType userSignatureData; + OrderSignatureDataType orderSignatureData; byte[] signature; try { @@ -76,7 +72,7 @@ public void build() throws EbicsException { user.getPartner().getPartnerId(), user.getUserId(), signature); - userSignatureData = EbicsXmlFactory.createUserSignatureDataSigBookType(new OrderSignatureDataType[] {orderSignatureData}); + userSignatureData = EbicsXmlFactory.createUserSignatureDataSigBookType(new OrderSignatureDataType[]{orderSignatureData}); document = EbicsXmlFactory.createUserSignatureDataDocument(userSignatureData); } @@ -96,9 +92,9 @@ public byte[] toByteArray() { // DATA MEMBERS // -------------------------------------------------------------------- - private EbicsUser user; - private String signatureVersion; - private byte[] toSign; - private String name; + private final EbicsUser user; + private final String signatureVersion; + private final byte[] toSign; + private final String name; private static final long serialVersionUID = 2992372604876703738L; } diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties deleted file mode 100644 index 4fd9dc45..00000000 --- a/src/main/resources/log4j.properties +++ /dev/null @@ -1,27 +0,0 @@ - # - # Copyright (c) 1990-2012 kopiLeft Development SARL, Bizerte, Tunisia - # - # This library is free software; you can redistribute it and/or - # modify it under the terms of the GNU Lesser General Public - # License version 2.1 as published by the Free Software Foundation. - # - # This library is distributed in the hope that it will be useful, - # but WITHOUT ANY WARRANTY; without even the implied warranty of - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - # Lesser General Public License for more details. - # - # You should have received a copy of the GNU Lesser General Public - # License along with this library; if not, write to the Free Software - # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - # - # $Id$ - # - -# Root logger option -log4j.rootLogger=INFO, stdout - -# Direct log messages to stdout -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.Target=System.out -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d %5p - %m%n \ No newline at end of file diff --git a/src/main/resources/org/kopi/ebics/client/config.properties b/src/main/resources/org/kopi/ebics/client/config.properties index aafd812f..c9d9e386 100644 --- a/src/main/resources/org/kopi/ebics/client/config.properties +++ b/src/main/resources/org/kopi/ebics/client/config.properties @@ -17,8 +17,6 @@ # $Id: config.properties 2 2012-02-28 09:39:55Z bentaher $ # -log.dir.name=log -log.file.name=ebics.log conf.file.name=ebics.properties keystore.dir.name=keystore traces.dir.name=traces diff --git a/src/main/resources/org/kopi/ebics/exception/messages_en.properties b/src/main/resources/org/kopi/ebics/exception/messages_en.properties index 4378dad9..162d01be 100644 --- a/src/main/resources/org/kopi/ebics/exception/messages_en.properties +++ b/src/main/resources/org/kopi/ebics/exception/messages_en.properties @@ -51,4 +51,4 @@ 091301 = Verification of the ES has failed In the case of asynchronously implemented orders, the error can occur during preliminary verification 091209 = certificate is not valid because it is not yet in effect 090005 = No download data available - +090003 = The subscriber is not entitled to submit orders of the selected order type. diff --git a/src/main/resources/org/kopi/ebics/exception/messages_fr.properties b/src/main/resources/org/kopi/ebics/exception/messages_fr.properties index 55b4f453..68ee42a6 100644 --- a/src/main/resources/org/kopi/ebics/exception/messages_fr.properties +++ b/src/main/resources/org/kopi/ebics/exception/messages_fr.properties @@ -50,3 +50,5 @@ 091301 = La V\u00E9rification de l'ES a \u00E9chou\u00E9. Dans le cas de commandes asynchrone, l'erreur peut se produire lors de la v\u00E9rification pr\u00E9liminaire 091209 = Le certificat n'est pas valide car il n'est pas encore en vigueur 090005 = Aucune donnée disponible pour t\u00E9l\u00E9chargement +090003 = L?abonné n?est pas autorisé à passer des ordres du type d?ordre sélectionné. + diff --git a/src/main/xsd/config/config.xsdconfig b/src/main/xsd/config/config.xsdconfig index 681adb58..f3e773ff 100644 --- a/src/main/xsd/config/config.xsdconfig +++ b/src/main/xsd/config/config.xsdconfig @@ -1,6 +1,7 @@ @@ -12,7 +13,11 @@ org.kopi.ebics.schema.h003 - + + + org.kopi.ebics.schema.h005 + + org.kopi.ebics.schema.xmldsig diff --git a/src/main/xsd/ebics.xsd b/src/main/xsd/ebics.xsd deleted file mode 100644 index 4ea0a868..00000000 --- a/src/main/xsd/ebics.xsd +++ /dev/null @@ -1,11 +0,0 @@ - - - - ebics.xsd inkludiert alle Schemadateien des EBICS-Protokolls, um die Eindeutigkeit von Element- und Typnamen im EBCIS Namespace zu erzwingen. - ebics.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/src/main/xsd/ebics_H005.xsd b/src/main/xsd/ebics_H005.xsd new file mode 100644 index 00000000..149bf263 --- /dev/null +++ b/src/main/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/src/main/xsd/ebics_keymgmt_request.xsd b/src/main/xsd/ebics_keymgmt_request_H005.xsd similarity index 85% rename from src/main/xsd/ebics_keymgmt_request.xsd rename to src/main/xsd/ebics_keymgmt_request_H005.xsd index c9f7fecb..cb93d3c4 100644 --- a/src/main/xsd/ebics_keymgmt_request.xsd +++ b/src/main/xsd/ebics_keymgmt_request_H005.xsd @@ -1,15 +1,16 @@ - + + - ebics_keymgmt_request.xsd ist das EBICS-Protokollschema für Schlüsselmanagement-Anfragen (HIA, HPB, HSA, INI). + 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). @@ -68,21 +69,11 @@ Datentyp für OrderDetails im statischen EBICS-Header (allgemein). - + Auftragsart. - - - Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen. - - - - - Auftragsattribut. - - @@ -177,7 +168,7 @@ - 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, Auftragsattribut DZNNN + 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 @@ -239,21 +230,11 @@ - + Auftragsart. - - - Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen. - - - - - Auftragsattribut: DZNNN. - - @@ -369,50 +350,43 @@ - Datentyp für OrderDetails im statischen EBICS-Header von ebicsNoPubKeyDigestsRequest. + Datentyp für OrderDetails im statischen EBICS-Header von ebicsNoPubKeyDigestsRequest. - + Auftragsart. - - - - Auftragsnummer von Sendeaufträgen gemaess DFÜ-Abkommen. - - - - - Auftragsattribut: DZHNN. - - - Anfragestruktur für Sendeaufträge mit EU-Datei und Nutzdaten aber ohne Authentifizierungssignatur und Digests der Bankschlüssel (Auftrag HSA Authentifikations- und Verschlüsselungsschlüssel senden, signiert mit FTAM-Schlüssel). + 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. @@ -422,6 +396,7 @@ + Contains the order data and the ESs. enthält die Auftragsdaten und EUs. @@ -431,12 +406,14 @@ + Transfer of order data and the ESs. Transfer von Auftragsdaten und EUs. + Contains the ESs. enthält Signaturdaten (EUs). @@ -449,6 +426,7 @@ + Contains the order data enthält Auftragsdaten. @@ -533,21 +511,11 @@ - + Auftragsart. - - - Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen. - - - - - Auftragsattribut: OZNNN. - - diff --git a/src/main/xsd/ebics_keymgmt_response.xsd b/src/main/xsd/ebics_keymgmt_response_H005.xsd similarity index 82% rename from src/main/xsd/ebics_keymgmt_response.xsd rename to src/main/xsd/ebics_keymgmt_response_H005.xsd index 9a751d3d..dfc33909 100644 --- a/src/main/xsd/ebics_keymgmt_response.xsd +++ b/src/main/xsd/ebics_keymgmt_response_H005.xsd @@ -1,15 +1,16 @@ - + + - ebics_keymgmt_response.xsd ist das EBICS-Protokollschema für Schlüsselmanagement-Antwortnachrichten (HIA, HPB, HSA, INI). + 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. @@ -115,6 +116,11 @@ 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. diff --git a/src/main/xsd/ebics_orders.xsd b/src/main/xsd/ebics_orders_H005.xsd similarity index 73% rename from src/main/xsd/ebics_orders.xsd rename to src/main/xsd/ebics_orders_H005.xsd index fc991220..30db1213 100644 --- a/src/main/xsd/ebics_orders.xsd +++ b/src/main/xsd/ebics_orders_H005.xsd @@ -1,12 +1,13 @@ - + + - ebics_orders.xsd enthält auftragsbezogene Referenzelemente und auftragsbezogene Typdefinitionen für EBICS. - ebics_orders.xsd contains order-based reference elements and order-based type definitions for EBICS. + 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. @@ -37,10 +38,10 @@ Order data for order type HIA (request: initialise user's keys for authentication and encryption). - + - Auftragsdaten für Auftragsart HSA (Anfrage: Initialisierung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung, bankfachlich signiert mit Signaturschlüssel aus FTAM). - Order data for order type HSA (request: initialise the user's keys for authentication and encryption; this request is signed using the user's FTAM signature key). + Order data for order type H3K (request: initialise all three user's keys). + Auftragsdaten für Auftragsart H3K (Anfrage: Initialisierung aller drei Teilnehmerschlüssel). @@ -134,7 +135,7 @@ 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). @@ -147,7 +148,7 @@ contains the digital signatures. - + zusätzliche Auftragsparameter, die zur Ausführung des Auftrags notwendig sind. @@ -190,31 +191,13 @@ additional order parameters for order type HVZ. - - - zusätzliche Auftragsparameter für Auftragsart FUL. - additional order parameters for order type FUL. - - - - - zusätzliche Auftragsparameter für Auftragsart FDL. - additional order parameters for order type FDL. - - zusätzliche Auftragsparameter für Standard-Auftragsarten. additional order parameters for standard order types. - - - zusätzliche Auftragsparameter für beliebige Auftragsarten. - additional order parameters for generic order types. - - - + Standard-Requeststruktur für HVx-Aufträge (HVD, HVT, HVE, HVS). @@ -231,10 +214,10 @@ Customer ID of the presenter of the selected order. - + - Auftragsart des ausgewählten Auftrags. - Order type of the selected order. + BTF Service Parameter struktur im Falle von BTU/BTD + Identification of the file format in the case of FUL/FDL @@ -283,7 +266,7 @@ - + Datentyp für Signaturdaten des Kreditinstituts beim EU-Transfer. @@ -316,11 +299,13 @@ 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. @@ -329,6 +314,7 @@ Datentyp für Kontenberechtigungsdaten zur Vorabprüfung. + Data type for the account authorisation data for the prevalidation. @@ -346,6 +332,7 @@ Datentyp für den Transfer von Auftragsdaten (Anfrage). + Data type for the transfer of order data (request). @@ -355,10 +342,12 @@ 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. @@ -371,6 +360,7 @@ enthält Signaturdaten (EUs). + contains signature data (ESs). @@ -380,14 +370,27 @@ + + + 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. @@ -410,10 +413,12 @@ 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. @@ -426,6 +431,7 @@ enthält Signaturdaten (EUs). + contains signature data (ESs). @@ -439,6 +445,7 @@ enthält Auftragsdaten. + contains order data. @@ -454,11 +461,13 @@ 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. @@ -472,6 +481,7 @@ Antwortcode für den vorangegangenen Transfer. + response code for the foregoing transfer. @@ -485,11 +495,13 @@ 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. @@ -498,26 +510,31 @@ 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. @@ -526,27 +543,32 @@ 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. @@ -555,57 +577,72 @@ 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 HSA (Anfrage: Initialisierung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung, bankfachlich signiert mit FTAM-Schlüssel). + 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). - + - öffentlicher Authentifikationsschlüssel. + Key for electronic Signature + Signaturschlüssel. - + - öffentlicher Verschlüsselungsschlüssel. + Authentication key + Authentifikationsschlüssel. + + + + + Encryption key + Verschlüsselungsschlüssel. + PartnerID. Kunden-ID. + UserID. Teilnehmer-ID. - @@ -632,26 +669,31 @@ 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. @@ -660,16 +702,19 @@ 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. @@ -677,11 +722,13 @@ Datentyp für HPD-Zugangsparameter. + data type for HPD Access Parameter. institutsspezifische IP-Adresse/URL. + individual IP-address/URL of the bank. @@ -689,6 +736,7 @@ Gültigkeitsbeginn für die angegebene URL/IP. + Valid-From-Date of the URL/IP. @@ -698,6 +746,7 @@ Institutsbezeichnung. + Name of the bank. @@ -747,21 +796,6 @@ - - - Parameter zur X.509-Funktionalität. - Parameter denoting the X.509 functionality. - - - - - - Sind die X.509-Daten der Teilnehmer serverseitig persistent gespeichert? - Will the user's X.509 data be stored persistently on server side? - - - - Parameter zum Download von Kunden- und Teilnehmerdaten (Auftragsarten HKD/HTD). @@ -786,11 +820,13 @@ Datentyp für HPD-Versionsinformationen. + Data type for HPD version information. unterstützte EBICS-Protokollversionen (H...). + supported EBICS protocol versions. (H...). @@ -799,6 +835,7 @@ unterstützte Versionen der Authentifikation (X...). + supported version for authentication (X...). @@ -807,6 +844,7 @@ unterstützte Versionen der Verschlüsselung (E...). + supported version for encryption (E...). @@ -815,6 +853,7 @@ unterstützte EU-Versionen (A...). + supported version for ES (A...). @@ -826,6 +865,7 @@ 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). @@ -846,6 +886,7 @@ Datentyp für Auftragsdaten für Auftragsart HVD (Antwort: VEU-Status abrufen). + Data type for order data for order type HVD (Response: EDS-status). @@ -896,6 +937,7 @@ Datentyp für zusätzliche Auftragsparameter für Auftragsart HVD. + Data type for additional order parameters for order type HVD. @@ -905,6 +947,7 @@ Datentyp für zusätzliche Auftragsparameter für Auftragsart HVE. + Data type for additional order parameters for order type HVE. @@ -914,6 +957,7 @@ Datentyp für zusätzliche Auftragsparameter für Auftragsart HVS. + Data type for additional order parameters for order type HVS. @@ -923,11 +967,13 @@ 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. @@ -936,6 +982,7 @@ 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"). @@ -964,22 +1011,20 @@ - Datentyp für HVT-Auftragsinformationen. + //MODIFIED - Replaced Element OrderFormat with MsgName// Datentyp für HVT-Auftragsinformationen. - - - Auftragsformat (z.B. DTAZV). - - + kontobezogene Details des Auftrags (Auftraggeber, Empfänger etc.). + account related details of the order (ordering party, receiver etc.). Ausführungsdatum. + Execution date. @@ -990,6 +1035,7 @@ Betrag. + Amount. @@ -997,11 +1043,13 @@ Gutschrift (isCredit = "true") oder Lastschrift (isCredit = "false")? + Credit (isCredit = "true") or debit (isCredit = "false")? Währungscode. + Currency code. @@ -1011,6 +1059,7 @@ Textfeld zur weiteren Beschreibung der Transaktion (Verwendungszweck, Auftragsdetails, Kommentar). + text field for additional descriptions regarding the transaction (remittance information, order details, annotations). @@ -1018,22 +1067,26 @@ Beschreibungstyp. + Description type. Verwendungszweck + remittance information. Auftragsdetails + Order details. Kommentar + Annotation. @@ -1049,17 +1102,18 @@ 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? - Are the transaction details so be transmitted as particular order content information requested for display matters or in complete order data file form? + 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. - 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. + 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). @@ -1067,10 +1121,10 @@ - + - Offset vom Anfang der Originalauftragsdatei für die zu liefernden Transaktionsdetails, bei completeOrderData=false bezogen auf laufende Nummer des Einzelauftrags. - 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. + 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). @@ -1110,6 +1164,7 @@ 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). @@ -1126,9 +1181,10 @@ Datentyp für HVU-Auftragsdetails. + Data type for HVU order details. - + Auftragsart lt. DFÜ-Abkommen des ausgewählten Auftrags. Type of the order. @@ -1137,26 +1193,37 @@ 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). @@ -1165,9 +1232,10 @@ 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. @@ -1178,9 +1246,10 @@ 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. @@ -1260,9 +1329,9 @@ Datentyp für HVZ-Auftragsdetails. - + - Auftragsart lt. DFÜ-Abkommen des ausgewählten Auftrags. + BTF Service Parameter-Struktur des ausgewählten Auftrags. Type of the order. @@ -1320,6 +1389,11 @@ Information regarding the originator of the order. + + + Additional Information about the order (unstructured, up to 255 characters). + + @@ -1340,9 +1414,17 @@ 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. + + + + + @@ -1408,7 +1490,7 @@ - + Bankleitzahl (deutsches Format oder international als SWIFT-BIC). @@ -1501,12 +1583,18 @@ 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. @@ -1556,9 +1644,9 @@ - + - Liste der Auftragsartenbeschränkungen; falls nicht angegeben, gibt es keine Auftragsartenbeschränkungen; falls Liste leer, ist das Konto für keine Auftragsart freigegeben. + //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. @@ -1680,19 +1768,15 @@ Data type for user permissions with regard to distributed signatures (order types HKD, HTD). - + - Auftragsart. + Administrative EBICS Auftragsart. - + - Transfertyp (Upload/Download). - - - - - Auftragsformat (z.B. DTAZV). + BTF Service Parameter struktur im Falle von BTU/BTD + Identification of the file format in the case of FUL/FDL @@ -1734,78 +1818,277 @@ - + - Datentyp für zusätzliche Auftragsparameter für beliebige Auftragsarten. + 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 + + + + - + - Datentyp für zusätzliche Auftragsparameter für Auftragsart FUL. + Abstract Type containing all BTF params structures - - + + + Service name - target system for the further processing of the order + + + - Bezeichnung des Dateiformats - Name of data format + 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 zusätzliche Auftragsparameter für Auftragsart FDL. + 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 + + + - Datumsbereich (von-bis). - Range of date (from-to). + 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 - - - - - Startdatum (inkl.). - - - - - Enddatum (inkl.). - - - - - - + - Bezeichnung des Dateiformats - Name of data format + 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) - + - Attribute zur EBICS-Protokollversion und -revision. - Attributes regarding the protocol version and revision of EBICS. + Type is arestriction of the generic ServiceType, defining the mandatory elements - - - Version des EBICS-Protokolls (z.B. "H003"). - Version of the EBICS protocol (e.g. "H003"). - - - - - Revision des EBICS-Protokolls (z.B. 1). - Revision of the EBICS protocol (e.g. 1). - - - + + + + + + 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/src/main/xsd/ebics_request.xsd b/src/main/xsd/ebics_request_H005.xsd similarity index 90% rename from src/main/xsd/ebics_request.xsd rename to src/main/xsd/ebics_request_H005.xsd index 0fb894d9..dc7ad70a 100644 --- a/src/main/xsd/ebics_request.xsd +++ b/src/main/xsd/ebics_request_H005.xsd @@ -1,16 +1,17 @@ - + + - ebics_request.xsd ist das EBICS-Protokollschema für Anfragen. - ebics_request.xsd is the appropriate EBICS protocol schema for standard requests. + 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 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. + 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. @@ -306,7 +307,7 @@ - + Ist dies das letzte Segment der Übertragung? Is this segment meant to be the last one regarding this transmission? @@ -321,13 +322,13 @@ - Datentyp für Auftragsdetails im statischen EBICS-Header. + //MODIFIED - Removed OrderAtribute ELEMENT// Datentyp für Auftragsdetails im statischen EBICS-Header. Data type for order details stored in the static EBICS header. - + - Auftragsart. + //MODIFIED - Umbenannt von OrderType// Auftragsart. type code of the order. @@ -342,12 +343,6 @@ ID of the (upload) order, formatted in accordance with the document "DFÜ-Abkommen". - - - Auftragsattribut. - attribute describing the order contents. - - diff --git a/src/main/xsd/ebics_response.xsd b/src/main/xsd/ebics_response_H005.xsd similarity index 86% rename from src/main/xsd/ebics_response.xsd rename to src/main/xsd/ebics_response_H005.xsd index 3103483e..841286b7 100644 --- a/src/main/xsd/ebics_response.xsd +++ b/src/main/xsd/ebics_response_H005.xsd @@ -1,16 +1,17 @@ - + + - ebics_response.xsd ist das EBICS-Protokollschema für Antwortnachrichten. - ebics_response.xsd is the appropriate EBICS protocol schema for standard responses. + 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. @@ -96,7 +97,7 @@ - Datentyp für den statischen EBICS-Header. + //TODO - Modify anotation TransactionID// Datentyp für den statischen EBICS-Header. Data type for the static EBICS header. @@ -134,7 +135,7 @@ - + Ist dies das letzte Segment der Übertragung? @@ -143,6 +144,11 @@ + + + Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen. + + Rückmeldung des technischen Status mit einer eindeutigen Fehlernummer. diff --git a/src/main/xsd/ebics_signature.xsd b/src/main/xsd/ebics_signature_S002.xsd similarity index 75% rename from src/main/xsd/ebics_signature.xsd rename to src/main/xsd/ebics_signature_S002.xsd index 79abed9b..3127faa7 100644 --- a/src/main/xsd/ebics_signature.xsd +++ b/src/main/xsd/ebics_signature_S002.xsd @@ -1,8 +1,9 @@ - + + - ebics_signature enthält Typdefinitionen für elektronische Unterschriften der Versionen A004, A005, A006 und folgende. + 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. @@ -24,32 +25,12 @@ Data type for digital signature data transferred using EBICS. - - - - bankfachliche Elektronische Unterschrift oder Transportunterschrift (Binärformat). - Digital signature (either autorising an order or applied for transportation), binary format. - - - - - - - Kunden-ID des Unterzeichners. - Customer ID of the signer. - - - - - - - - - bankfachliche Elektronische Unterschrift oder Transportunterschrift (strukturiertes Format). - Digital signature (either autorising an order or applied for transportation), structured format. - - - + + + bankfachliche Elektronische Unterschrift oder Transportunterschrift (strukturiertes Format). + Digital signature (either autorising an order or applied for transportation), structured format. + + @@ -183,28 +164,7 @@ Datentyp für die Darstellung eines öffentlichen RSA-Schlüssels als Exponent-Modulus-Kombination oder als X509-Zertifikat. - - - - - Darstellung als Exponent-Modulus-Kombination. - - - - - - - - - Datentyp für die Exponent-Modulus-Darstellung eines öffentlichen RSA-Schlüssels. - - - - - - Zeitpunkt der Generierung des Schlüssels. - - + diff --git a/src/main/xsd/ebics_types.xsd b/src/main/xsd/ebics_types_H005.xsd similarity index 71% rename from src/main/xsd/ebics_types.xsd rename to src/main/xsd/ebics_types_H005.xsd index 89eebd0b..ea13f06b 100644 --- a/src/main/xsd/ebics_types.xsd +++ b/src/main/xsd/ebics_types_H005.xsd @@ -1,9 +1,10 @@ - - + + + - ebics_types.xsd enthält einfache Typdefinitionen für EBICS. + ebics_types_H005.xsd enthält einfache Typdefinitionen für EBICS. @@ -967,536 +968,6 @@ - - - Listentyp für allgemeine Auftragsarten. - - - - - - Datentyp für zulässige Auftragsarten im EBICS-Kontext. - - - - - - Senden der Public Keys für Authentifikation und Verschlüsselung, bankfachlich signiert mit FTAM-Signaturschlüssel - - - - - Senden der Public Keys zur Authentifikation und zur Verschlüsselung - - - - - Abholen der Public Keys der Bank - - - - - Ändern der Public Keys zur Authentifikation und zur Verschlüsselung - - - - - Abholen Bankparameter für internetbasierten Standard - - - - - Abholen VEU Übersicht - - - - - Abholen VEU Auftragsdaten (Daten-trägerbegleitzettel) - - - - - Abholen VEU Auftragsdaten ( Transakti-onsdetails gemäß Parametervorgabe) - - - - - Senden EU zu bestehendem VEU-Auftrag - - - - - Senden Stornierung für bestehenden VEU-Auftrag - - - - - Abholen Konfigurationsdaten des Teilnehmers - - - - - Abholen Übersicht zu abrufbaren Aufträgen - - - - - VEU-Übersicht abholen - - - - - VEU-Status abrufen - - - - - VEU-Transaktion-Details abrufen - - - - - EU hinzufügen - - - - - VEU-Stornierung - - - - - Senden Importakkreditiv Änderung - - - - - Senden Exportakkreditive - - - - - Senden Import-Akkreditive Avisierung - - - - - Abholen Import-Akkreditive - - - - - AWV-Meldung senden - - - - - AZV im Magnetbandformat senden (Satzlänge variabel) - - - - - AZV im Diskettenformat senden - - - - - AZV im Magnetbandformat senden (Satzlängenfeld 2 Bytes) - - - - - AZV im Magnetbandformat senden (Satzlängenfeld 4 Bytes) - - - - - Abholen Devisenhandelsbestätigung - - - - - Senden Devisenhandelsbestätigung - - - - - Eilauftrag (IZV im DTAUS0-Format) senden - - - - - IZV-Datei abholen - - - - - MCV-Datei abholen (Format analog MCV) - - - - - Zahlungsverkehrsdateien von Service-Rechenzentren senden - - - - - MC2-Datei abholen (Format analog MC2) - - - - - MC4-Datei abholen (Format analog MC4) - - - - - Exportakkreditive abholen - - - - - Senden electronic-cash Lastschriftdatei - - - - - Senden Maestro-Lastschriftdatei - - - - - EDIFACT abholen ASCII - - - - - EDIFACT abholen EBCDIC - - - - - Ausführungsanzeige (Exportinkasso) Bank an Kunde abholen - - - - - Senden Exportinkassi - - - - - EDIFACT senden ASCII - - - - - EU-Standardüberweisung (Zahlungsart 13) im Magnetbandformat (Satzlängenfeld 4 Bytes) - - - - - Einreichung von EDIFACT-Lastschriften - - - - - EDIFACT senden EBCDIC - - - - - EU-Standardüberweisung (Zahlungsart 13) - - - - - Taggleiche grenzüberschreitende Euro-Eilzahlung - - - - - Abholen Garantien - - - - - Senden Garantien - - - - - GeldKarte-Umsatz senden (Datenaufbau gemäß GeldKarte-Spezifikation) - - - - - Internationale Lastschriften - - - - - Abholen Importinkassi - - - - - Senden Importinkassi - - - - - Internationaler Zahlungsverkehr - - - - - Inlandszahlungsverkehrsauftrag senden (nur Gutschriften) - - - - - Inlandszahlungsverkehrsauftrag senden (nur Lastschriften) - - - - - Inlandszahlungsverkehrsauftrag senden - - - - - Abholen Magnetband-Datei aus optischer Beleglesung - - - - - Senden IZV-Magnetbandformat (Satzlängenfeld 4 Bytes) - - - - - Senden IZV-Magnetbandformat (Satzlängenfeld 2 Bytes) - - - - - Senden IZV-Magnetbandformat (Satzlänge variabel) - - - - - Senden POZ-Datei - - - - - Rücklastschrift an Kunde - - - - - Request for Transfer - - - - - Abholen Swift-Tagesauszüge - - - - - Abholen kurzfristige Vormerkposten - - - - - Abholen Wertpapierabrechnung - - - - - Abholen Wertpapierausführungsanzeige - - - - - Abholen Depotaufstellung - - - - - Abholen sonstige WP-Umsätze - - - - - Initialisierung der bankfachlichen EU des Teilnehmers. - - - - - Abholen Kundenprotokoll - - - - - Senden Public Key zur Unterschriftenverifizierung - - - - - Änderung der Teilnehmerschlüssel für Authentifikation und Verschlüsselung - - - - - Sperren der Zugangsberechtigung - - - - - Abholen Public Key der Bank zur Verschlüsselung - - - - - EDIFACT-FINPAY senden - - - - - Informationen von Zentralstellen - - - - - ec-Karten-Sperrdatei - - - - - Teilausnutzung Importakkreditiv (Kreditinstitut an Kunde) - - - - - Auftragsart für elektronische Kontoauszüge - - - - - Barzahlungskarte - - - - - Devisenkursinformationen abholen (Euro) - - - - - Abholen Devisenmarktinformationen - - - - - Abholen Devisenswapinformationen - - - - - ESG-Datei für Elektronische Zweitunterschrift abholen - - - - - ESP-Datei für Elektronische Zweitunterschrift senden - - - - - Abholen/Senden beliebige Datei - - - - - Freie Textdatei senden/abholen - - - - - Abholen Institutsbestätigungsdatei (Komplettbestand) - - - - - Abholen Institutsbestätigungsdatei (Komplettbestand weitere Datei) - - - - - Abholen Institutsbestätigungsdatei (tägliches Update) - - - - - Senden Institutskonten (Komplettbestand begrenzt auf 170 MB) - - - - - Senden Institutskonten (tägliches Update) - - - - - Senden Institutskonten (Komplettbestand weitere Datei) - - - - - KTOHIN: Automatisiertes Verfahren für die Änderung von Kontonummern und Bankleitzahlen - - - - - KTORUECK: Automatisiertes Verfahren für die Änderung von Kontonummern und Bankleitzahlen - - - - - Kontenkonzentration und Saldenausgleich - - - - - Senden/Abholen Testdatei (ASCII) - - - - - Updates abholen - - - - - camt.052 Vormerkposten / Avise (VMK) - - - - - camt.053 Tagesauszug (STA) - - - - - Sammelbuchungsinformationen (DTI) - - - - - Datentyp für eine Auftragsnummer lt. DFÜ-Abkommen. @@ -1506,36 +977,6 @@ - - - Datentyp für ein einzelnes Auftragsattributkennzeichen (Grundtyp). - - - - - - - - Datentyp für Auftragsattributkennzeichen gemäß DFÜ-Abkommen. - - - - - Auftragsdaten mit Unterschrift, ZIP-komprimiert, hybrid verschlüsselt - - - - - Unterschrift, ZIP-komprimiert, hybrid verschlüsselt - - - - - Auftragsdaten ohne Unterschrift, ZIP-komprimiert, hybrid verschlüsselt - - - - Datentyp für das Sicherheitsmedium. @@ -1726,7 +1167,7 @@ - + Bankleitzahl (deutsches Format und/oder international als SWIFT-BIC). @@ -1938,7 +1379,7 @@ - + Bankleitzahl (deutsches Format oder international als SWIFT-BIC). @@ -2056,31 +1497,6 @@ - - - ISO-Code zur Länderkennzeichnung. - ISO-Code to identify the country. - - - - - - - - - Datentyp für das Dateiformat. - - - - - - ISO-Code zur Länderkennzeichnung (EU für Europa) - ISO-Code to identify the country (EU for Europe) - - - - - Datentyp für Berechtigungsklassen zur Elektronischen Unterschrift. @@ -2130,7 +1546,7 @@ - + Version des Signaturverfahrens. Version of the algorithm used for signature creation. @@ -2166,33 +1582,12 @@ - - - Datentyp für die Exponent-Modulus-Darstellung eines öffentlichen RSA-Schlüssels. - - - - - - Zeitpunkt der Generierung des Schlüssels. - - - - - Datentyp für die Darstellung eines öffentlichen RSA-Schlüssels als Exponent-Modulus-Kombination oder als X509-Zertifikat. - - - - - Darstellung als Exponent-Modulus-Kombination. - - - + @@ -2228,6 +1623,70 @@ + + + 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. @@ -2260,23 +1719,6 @@ - - - Datentyp für den Transfertyp (Upload/Download). - - - - - Auftragsdaten werden bei der Anfrage transferiert. - - - - - Auftragsdaten werden bei der Antwort transferiert. - - - - Datentyp für die Beschreibung von Auftragsarten. @@ -2285,14 +1727,6 @@ - - - Datentyp für das Auftragsformat. - - - - - Datentyp für den Teilnehmerstatus. @@ -2303,29 +1737,29 @@ - generische Schlüssel-Wert-Parameter. + generic parameter Generic key value parameters. - Name des Parameters. + name of parameter Name of the parameter (= key). - Wert des Parameters. + value of parameter Value of the parameter. - + - XML-Typ des Parameterwerts (Default=string). - XML type of the parameter value (default is string). + XML-Typ des Parameterwerts (Vorschlag für default ist string). + XML type of the parameter value (Proposal for default is string). @@ -2374,4 +1808,78 @@ 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 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/xsd/xmldsig-core-schema.xsd b/src/main/xsd/xmldsig-core-schema.xsd index fc34f273..1698c2fb 100644 --- a/src/main/xsd/xmldsig-core-schema.xsd +++ b/src/main/xsd/xmldsig-core-schema.xsd @@ -1,6 +1,6 @@ @@ -11,7 +11,7 @@