提交 f80edefe 编写于 作者: R robm

Merge

...@@ -666,6 +666,40 @@ public final class SoftSynthesizer implements AudioSynthesizer, ...@@ -666,6 +666,40 @@ public final class SoftSynthesizer implements AudioSynthesizer,
} }
}); });
actions.add(new PrivilegedAction<InputStream>() {
public InputStream run() {
if (System.getProperties().getProperty("os.name")
.startsWith("Linux")) {
File[] systemSoundFontsDir = new File[] {
/* Arch, Fedora, Mageia */
new File("/usr/share/soundfonts/"),
new File("/usr/local/share/soundfonts/"),
/* Debian, Gentoo, OpenSUSE, Ubuntu */
new File("/usr/share/sounds/sf2/"),
new File("/usr/local/share/sounds/sf2/"),
};
/*
* Look for a default.sf2
*/
for (File systemSoundFontDir : systemSoundFontsDir) {
if (systemSoundFontDir.exists()) {
File defaultSoundFont = new File(systemSoundFontDir, "default.sf2");
if (defaultSoundFont.exists()) {
try {
return new FileInputStream(defaultSoundFont);
} catch (IOException e) {
// continue with lookup
}
}
}
}
}
return null;
}
});
actions.add(new PrivilegedAction<InputStream>() { actions.add(new PrivilegedAction<InputStream>() {
public InputStream run() { public InputStream run() {
if (System.getProperties().getProperty("os.name") if (System.getProperties().getProperty("os.name")
......
...@@ -200,4 +200,9 @@ public class ArrayTypeImpl extends ReferenceTypeImpl ...@@ -200,4 +200,9 @@ public class ArrayTypeImpl extends ReferenceTypeImpl
* Defined always to be true for arrays * Defined always to be true for arrays
*/ */
public boolean isFinal() { return true; } public boolean isFinal() { return true; }
/*
* Defined always to be false for arrays
*/
public boolean isStatic() { return false; }
} }
...@@ -36,9 +36,7 @@ import java.util.Date; ...@@ -36,9 +36,7 @@ import java.util.Date;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.DerInputStream; import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;
import sun.security.x509.SerialNumber; import sun.security.x509.SerialNumber;
import sun.security.x509.KeyIdentifier;
import sun.security.x509.AuthorityKeyIdentifierExtension; import sun.security.x509.AuthorityKeyIdentifierExtension;
/** /**
...@@ -131,13 +129,7 @@ class AdaptableX509CertSelector extends X509CertSelector { ...@@ -131,13 +129,7 @@ class AdaptableX509CertSelector extends X509CertSelector {
serial = null; serial = null;
if (ext != null) { if (ext != null) {
KeyIdentifier akid = (KeyIdentifier)ext.get( ski = ext.getEncodedKeyIdentifier();
AuthorityKeyIdentifierExtension.KEY_ID);
if (akid != null) {
DerOutputStream derout = new DerOutputStream();
derout.putOctetString(akid.getIdentifier());
ski = derout.toByteArray();
}
SerialNumber asn = (SerialNumber)ext.get( SerialNumber asn = (SerialNumber)ext.get(
AuthorityKeyIdentifierExtension.SERIAL_NUMBER); AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
if (asn != null) { if (asn != null) {
......
...@@ -33,7 +33,6 @@ import javax.security.auth.x500.X500Principal; ...@@ -33,7 +33,6 @@ import javax.security.auth.x500.X500Principal;
import java.util.*; import java.util.*;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.DerOutputStream;
import static sun.security.x509.PKIXExtensions.*; import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*; import sun.security.x509.*;
...@@ -608,12 +607,9 @@ public class DistributionPointFetcher { ...@@ -608,12 +607,9 @@ public class DistributionPointFetcher {
AuthorityKeyIdentifierExtension akidext = AuthorityKeyIdentifierExtension akidext =
crlImpl.getAuthKeyIdExtension(); crlImpl.getAuthKeyIdExtension();
if (akidext != null) { if (akidext != null) {
KeyIdentifier akid = (KeyIdentifier)akidext.get( byte[] kid = akidext.getEncodedKeyIdentifier();
AuthorityKeyIdentifierExtension.KEY_ID); if (kid != null) {
if (akid != null) { certSel.setSubjectKeyIdentifier(kid);
DerOutputStream derout = new DerOutputStream();
derout.putOctetString(akid.getIdentifier());
certSel.setSubjectKeyIdentifier(derout.toByteArray());
} }
SerialNumber asn = (SerialNumber)akidext.get( SerialNumber asn = (SerialNumber)akidext.get(
......
...@@ -46,9 +46,10 @@ import sun.security.provider.certpath.PKIX.BuilderParams; ...@@ -46,9 +46,10 @@ import sun.security.provider.certpath.PKIX.BuilderParams;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.x509.AccessDescription; import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.AuthorityKeyIdentifierExtension;
import static sun.security.x509.PKIXExtensions.*; import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.X500Name; import sun.security.x509.X500Name;
import sun.security.x509.AuthorityKeyIdentifierExtension; import sun.security.x509.X509CertImpl;
/** /**
* This class represents a forward builder, which is able to retrieve * This class represents a forward builder, which is able to retrieve
...@@ -69,7 +70,6 @@ class ForwardBuilder extends Builder { ...@@ -69,7 +70,6 @@ class ForwardBuilder extends Builder {
private AdaptableX509CertSelector caSelector; private AdaptableX509CertSelector caSelector;
private X509CertSelector caTargetSelector; private X509CertSelector caTargetSelector;
TrustAnchor trustAnchor; TrustAnchor trustAnchor;
private Comparator<X509Certificate> comparator;
private boolean searchAllCertStores = true; private boolean searchAllCertStores = true;
/** /**
...@@ -93,7 +93,6 @@ class ForwardBuilder extends Builder { ...@@ -93,7 +93,6 @@ class ForwardBuilder extends Builder {
trustedSubjectDNs.add(anchor.getCA()); trustedSubjectDNs.add(anchor.getCA());
} }
} }
comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores; this.searchAllCertStores = searchAllCertStores;
} }
...@@ -122,6 +121,8 @@ class ForwardBuilder extends Builder { ...@@ -122,6 +121,8 @@ class ForwardBuilder extends Builder {
* As each cert is added, it is sorted based on the PKIXCertComparator * As each cert is added, it is sorted based on the PKIXCertComparator
* algorithm. * algorithm.
*/ */
Comparator<X509Certificate> comparator =
new PKIXCertComparator(trustedSubjectDNs, currState.cert);
Set<X509Certificate> certs = new TreeSet<>(comparator); Set<X509Certificate> certs = new TreeSet<>(comparator);
/* /*
...@@ -264,14 +265,6 @@ class ForwardBuilder extends Builder { ...@@ -264,14 +265,6 @@ class ForwardBuilder extends Builder {
CertPathHelper.setPathToNames CertPathHelper.setPathToNames
(caSelector, currentState.subjectNamesTraversed); (caSelector, currentState.subjectNamesTraversed);
/*
* Facilitate certification path construction with authority
* key identifier and subject key identifier.
*/
AuthorityKeyIdentifierExtension akidext =
currentState.cert.getAuthorityKeyIdentifierExtension();
caSelector.setSkiAndSerialNumber(akidext);
/* /*
* check the validity period * check the validity period
*/ */
...@@ -404,41 +397,68 @@ class ForwardBuilder extends Builder { ...@@ -404,41 +397,68 @@ class ForwardBuilder extends Builder {
* *
* Preference order for current cert: * Preference order for current cert:
* *
* 1) Issuer matches a trusted subject * 1) The key identifier of an AKID extension (if present) in the
* previous certificate matches the key identifier in the SKID extension
*
* 2) Issuer matches a trusted subject
* Issuer: ou=D,ou=C,o=B,c=A * Issuer: ou=D,ou=C,o=B,c=A
* *
* 2) Issuer is a descendant of a trusted subject (in order of * 3) Issuer is a descendant of a trusted subject (in order of
* number of links to the trusted subject) * number of links to the trusted subject)
* a) Issuer: ou=E,ou=D,ou=C,o=B,c=A [links=1] * a) Issuer: ou=E,ou=D,ou=C,o=B,c=A [links=1]
* b) Issuer: ou=F,ou=E,ou=D,ou=C,ou=B,c=A [links=2] * b) Issuer: ou=F,ou=E,ou=D,ou=C,ou=B,c=A [links=2]
* *
* 3) Issuer is an ancestor of a trusted subject (in order of number of * 4) Issuer is an ancestor of a trusted subject (in order of number of
* links to the trusted subject) * links to the trusted subject)
* a) Issuer: ou=C,o=B,c=A [links=1] * a) Issuer: ou=C,o=B,c=A [links=1]
* b) Issuer: o=B,c=A [links=2] * b) Issuer: o=B,c=A [links=2]
* *
* 4) Issuer is in the same namespace as a trusted subject (in order of * 5) Issuer is in the same namespace as a trusted subject (in order of
* number of links to the trusted subject) * number of links to the trusted subject)
* a) Issuer: ou=G,ou=C,o=B,c=A [links=2] * a) Issuer: ou=G,ou=C,o=B,c=A [links=2]
* b) Issuer: ou=H,o=B,c=A [links=3] * b) Issuer: ou=H,o=B,c=A [links=3]
* *
* 5) Issuer is an ancestor of certificate subject (in order of number * 6) Issuer is an ancestor of certificate subject (in order of number
* of links to the certificate subject) * of links to the certificate subject)
* a) Issuer: ou=K,o=J,c=A * a) Issuer: ou=K,o=J,c=A
* Subject: ou=L,ou=K,o=J,c=A * Subject: ou=L,ou=K,o=J,c=A
* b) Issuer: o=J,c=A * b) Issuer: o=J,c=A
* Subject: ou=L,ou=K,0=J,c=A * Subject: ou=L,ou=K,0=J,c=A
* *
* 6) Any other certificates * 7) Any other certificates
*/ */
static class PKIXCertComparator implements Comparator<X509Certificate> { static class PKIXCertComparator implements Comparator<X509Certificate> {
final static String METHOD_NME = "PKIXCertComparator.compare()"; static final String METHOD_NME = "PKIXCertComparator.compare()";
private final Set<X500Principal> trustedSubjectDNs; private final Set<X500Principal> trustedSubjectDNs;
private final X509CertSelector certSkidSelector;
PKIXCertComparator(Set<X500Principal> trustedSubjectDNs) { PKIXCertComparator(Set<X500Principal> trustedSubjectDNs,
X509CertImpl previousCert) throws IOException {
this.trustedSubjectDNs = trustedSubjectDNs; this.trustedSubjectDNs = trustedSubjectDNs;
this.certSkidSelector = getSelector(previousCert);
}
/**
* Returns an X509CertSelector for matching on the authority key
* identifier, or null if not applicable.
*/
private X509CertSelector getSelector(X509CertImpl previousCert)
throws IOException {
if (previousCert != null) {
AuthorityKeyIdentifierExtension akidExt =
previousCert.getAuthorityKeyIdentifierExtension();
if (akidExt != null) {
byte[] skid = akidExt.getEncodedKeyIdentifier();
if (skid != null) {
X509CertSelector selector = new X509CertSelector();
selector.setSubjectKeyIdentifier(skid);
return selector;
}
}
}
return null;
} }
/** /**
...@@ -462,6 +482,16 @@ class ForwardBuilder extends Builder { ...@@ -462,6 +482,16 @@ class ForwardBuilder extends Builder {
// if certs are the same, return 0 // if certs are the same, return 0
if (oCert1.equals(oCert2)) return 0; if (oCert1.equals(oCert2)) return 0;
// If akid/skid match then it is preferable
if (certSkidSelector != null) {
if (certSkidSelector.match(oCert1)) {
return -1;
}
if (certSkidSelector.match(oCert2)) {
return 1;
}
}
X500Principal cIssuer1 = oCert1.getIssuerX500Principal(); X500Principal cIssuer1 = oCert1.getIssuerX500Principal();
X500Principal cIssuer2 = oCert2.getIssuerX500Principal(); X500Principal cIssuer2 = oCert2.getIssuerX500Principal();
X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1); X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1);
......
...@@ -307,4 +307,16 @@ implements CertAttrSet<String> { ...@@ -307,4 +307,16 @@ implements CertAttrSet<String> {
public String getName() { public String getName() {
return (NAME); return (NAME);
} }
/**
* Return the encoded key identifier, or null if not specified.
*/
public byte[] getEncodedKeyIdentifier() throws IOException {
if (id != null) {
DerOutputStream derOut = new DerOutputStream();
id.encode(derOut);
return derOut.toByteArray();
}
return null;
}
} }
/* /*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1501,7 +1501,9 @@ final public class AccessBridge extends AccessBridgeLoader { ...@@ -1501,7 +1501,9 @@ final public class AccessBridge extends AccessBridgeLoader {
s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) { s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) {
// Indicate whether this component manages its own // Indicate whether this component manages its own
// children // children
AccessibleRole role = ac.getAccessibleRole(); AccessibleRole role = InvocationUtils.invokeAndWait(() -> {
return ac.getAccessibleRole();
}, ac);
if (role == AccessibleRole.LIST || if (role == AccessibleRole.LIST ||
role == AccessibleRole.TABLE || role == AccessibleRole.TABLE ||
role == AccessibleRole.TREE) { role == AccessibleRole.TREE) {
...@@ -1759,7 +1761,9 @@ final public class AccessBridge extends AccessBridgeLoader { ...@@ -1759,7 +1761,9 @@ final public class AccessBridge extends AccessBridgeLoader {
*/ */
private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) { private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) {
if (ac != null) { if (ac != null) {
AccessibleComponent acmp = ac.getAccessibleComponent(); AccessibleComponent acmp = InvocationUtils.invokeAndWait(() -> {
return ac.getAccessibleComponent();
}, ac);
if (acmp != null) { if (acmp != null) {
debugString("Returning AccessibleComponent Context"); debugString("Returning AccessibleComponent Context");
return acmp; return acmp;
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <winsock2.h> /* needed for htonl */ #include <winsock2.h> /* needed for htonl */
#include <iprtrmib.h> #include <iprtrmib.h>
#include <assert.h> #include <assert.h>
#include <limits.h>
#include "java_net_NetworkInterface.h" #include "java_net_NetworkInterface.h"
#include "jni_util.h" #include "jni_util.h"
...@@ -70,7 +71,7 @@ void printnifs (netif *netifPP, char *str) { ...@@ -70,7 +71,7 @@ void printnifs (netif *netifPP, char *str) {
#endif #endif
static int bufsize = 1024; static int bufsize = 4096;
/* /*
* return an array of IP_ADAPTER_ADDRESSES containing one element * return an array of IP_ADAPTER_ADDRESSES containing one element
...@@ -94,7 +95,12 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) { ...@@ -94,7 +95,12 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {
ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
if (ret == ERROR_BUFFER_OVERFLOW) { if (ret == ERROR_BUFFER_OVERFLOW) {
IP_ADAPTER_ADDRESSES * newAdapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
if (len < (ULONG_MAX - bufsize)) {
len = len + bufsize;
}
newAdapterInfo =
(IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
if (newAdapterInfo == NULL) { if (newAdapterInfo == NULL) {
free(adapterInfo); free(adapterInfo);
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
...@@ -103,7 +109,6 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) { ...@@ -103,7 +109,6 @@ static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {
adapterInfo = newAdapterInfo; adapterInfo = newAdapterInfo;
bufsize = len;
ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
} }
...@@ -137,7 +142,12 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) { ...@@ -137,7 +142,12 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) {
flags |= GAA_FLAG_INCLUDE_PREFIX; flags |= GAA_FLAG_INCLUDE_PREFIX;
val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
if (val == ERROR_BUFFER_OVERFLOW) { if (val == ERROR_BUFFER_OVERFLOW) {
IP_ADAPTER_ADDRESSES * newAdapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
if (len < (ULONG_MAX - bufsize)) {
len = len + bufsize;
}
newAdapterInfo =
(IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
if (newAdapterInfo == NULL) { if (newAdapterInfo == NULL) {
free(adapterInfo); free(adapterInfo);
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
...@@ -146,7 +156,6 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) { ...@@ -146,7 +156,6 @@ IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) {
adapterInfo = newAdapterInfo; adapterInfo = newAdapterInfo;
bufsize = len;
val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
} }
......
...@@ -352,7 +352,8 @@ needs_jdk = \ ...@@ -352,7 +352,8 @@ needs_jdk = \
javax/xml/bind/jxc \ javax/xml/bind/jxc \
javax/xml/ws/8033113 \ javax/xml/ws/8033113 \
javax/xml/ws/clientjar/TestWsImport.java \ javax/xml/ws/clientjar/TestWsImport.java \
javax/xml/ws/ebcdic javax/xml/ws/ebcdic \
javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
# JRE adds further tests to compact3 # JRE adds further tests to compact3
# #
......
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Arrays;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
/*
* @test
* @bug 8048604
* @summary This test verifies the assertion "The chaining feature of
* Filter streams should be supported." for feature "CipherInputStream &
* CipherOutputStream"
* @run main CICOChainingTest
*/
public class CICOChainingTest {
/**
* Plain text length.
*/
private static final int PLAIN_TEXT_LENGTH = 200;
public static void main(String argv[]) throws Exception {
CICOChainingTest test = new CICOChainingTest();
test.chainTest(true);
test.chainTest(false);
}
/**
* Chain CipherInputStream/CipherOutputStream with other stream, encrypt
* the text and decrypt it, recovered text is supposed to be same as
* original text.
* @param useInt true if read byte by byte false if read with buffer.
* @throws IOException any I/O operation failed.
*/
public void chainTest(boolean useInt) throws IOException {
byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
byte[] recoveredText = new byte[plainText.length];
// Do initialization
try (MyNullCipherInputStream ciInput1 = new MyNullCipherInputStream(
new ByteArrayInputStream(plainText));
PipedOutputStream piOut = new PipedOutputStream();
MyNullCipherInputStream ciInput2 = new MyNullCipherInputStream(
new PipedInputStream(piOut));
MyNullCipherOutputStream ciOut = new MyNullCipherOutputStream(
piOut);) {
if (useInt) {
int buffer = ciInput1.read();
while (buffer != -1) {
piOut.write(buffer);
buffer = ciInput1.read();
}
} else {
byte[] buffer = new byte[20];
int len = ciInput1.read(buffer);
while (len != -1) {
ciOut.write(buffer, 0, len);
len = ciInput1.read(buffer);
}
}
ciOut.flush();
piOut.flush();
// Get the output
ciInput2.read(recoveredText);
if (ciInput2.available() > 0) {
throw new RuntimeException("Expected no data from ciInput2, but"
+ " ciInput2.available() = " + ciInput2.available());
}
}
// Verify output is same to input.
if (!Arrays.equals(plainText, recoveredText)) {
throw new RuntimeException("plainText:" + new String(plainText)
+ " recoveredText:" + new String(recoveredText)
+ " Test failed due to result compare fail");
}
}
}
class MyNullCipherInputStream extends CipherInputStream {
public MyNullCipherInputStream(InputStream is) {
super(is);
}
}
class MyNullCipherOutputStream extends CipherOutputStream {
public MyNullCipherOutputStream(OutputStream os) {
super(os);
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.System.out;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
/*
* @test
* @bug 8048604
* @summary to verify cipherInputStream and cipherInputStream cipher function
* @run main CICODESFuncTest
*/
public class CICODESFuncTest {
/**
* Algorithms name.
*/
private static final String[] ALGORITHMS = { "DES", "DESede", "Blowfish" };
private static final String[] MODES = { "ECB", "CBC", "CFB", "CFB24",
"CFB32", "CFB40", "CFB72", "OFB", "OFB20", "OFB48", "OFB56",
"OFB64", "PCBC" };
/**
* Padding mode.
*/
private static final String[] PADDINGS = { "noPadding", "pkcs5padding" };
/**
* Plain text length.
*/
private static final int TEXT_LENGTH = 80;
/**
* Initialization vector length.
*/
private static final int IV_LENGTH = 8;
public static void main(String[] args) throws Exception {
Provider provider = Security.getProvider("SunJCE");
if (provider == null) {
throw new RuntimeException("SunJCE provider does not exist.");
}
for (String algorithm : ALGORITHMS) {
for (String mode : MODES) {
// We only test noPadding and pkcs5padding for CFB72, OFB20, ECB
// PCBC and CBC. Otherwise test noPadding only.
int padKinds = 1;
if (mode.equalsIgnoreCase("CFB72")
|| mode.equalsIgnoreCase("OFB20")
|| mode.equalsIgnoreCase("ECB")
|| mode.equalsIgnoreCase("PCBC")
|| mode.equalsIgnoreCase("CBC")) {
padKinds = PADDINGS.length;
}
// PKCS5padding is meaningful only for ECB, CBC, PCBC
for (int k = 0; k < padKinds; k++) {
for (ReadModel readMode : ReadModel.values()) {
runTest(provider, algorithm, mode, PADDINGS[k], readMode);
}
}
}
}
}
private static void runTest(Provider p, String algo, String mo, String pad,
ReadModel whichRead) throws GeneralSecurityException, IOException {
// Do initialization
byte[] plainText = TestUtilities.generateBytes(TEXT_LENGTH);
byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
AlgorithmParameterSpec aps = new IvParameterSpec(iv);
try {
KeyGenerator kg = KeyGenerator.getInstance(algo, p);
out.println(algo + "/" + mo + "/" + pad + "/" + whichRead);
SecretKey key = kg.generateKey();
Cipher ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
throw new RuntimeException(
"NoSuchAlgorithmException not throw when mode"
+ " is CFB72 or OFB20");
}
Cipher ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
if ("ECB".equalsIgnoreCase(mo)) {
ci1.init(Cipher.ENCRYPT_MODE, key);
ci2.init(Cipher.DECRYPT_MODE, key);
} else {
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
ci2.init(Cipher.DECRYPT_MODE, key, aps);
}
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
try (CipherInputStream cInput
= new CipherInputStream(
new ByteArrayInputStream(plainText), ci1);
CipherOutputStream ciOutput
= new CipherOutputStream(baOutput, ci2);) {
// Read from the input and write to the output using 2 types
// of buffering : byte[] and int
whichRead.read(cInput, ciOutput, ci1, plainText.length);
}
// Verify input and output are same.
if (!Arrays.equals(plainText, baOutput.toByteArray())) {
throw new RuntimeException("Test failed due to compare fail ");
}
} catch (NoSuchAlgorithmException nsaEx) {
if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
out.println("NoSuchAlgorithmException is expected for CFB72 and OFB20");
} else {
throw new RuntimeException("Unexpected exception testing: "
+ algo + "/" + mo + "/" + pad + "/" + whichRead, nsaEx);
}
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.System.out;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/*
* @test
* @bug 8048604
* @summary This test verifies the assertion "The skip feature of Filter
* streams should be supported." for feature
* CipherInputStream and CipherOutputStream
*/
public class CICOSkipTest {
/**
* Block length.
*/
private static final int BLOCK = 50;
/**
* Saving bytes length.
*/
private static final int SAVE = 45;
/**
* Plain text length.
*/
private static final int PLAIN_TEXT_LENGTH = 800;
/**
* Skip reading byte size. This should be same to BLOCK - SAVE
*/
private static final int DISCARD = BLOCK - SAVE;
private static final String[] ALGOS = {"DES", "DESede", "Blowfish"};
private static final String[] MODES = {"ECB", "CBC", "CFB", "CFB32",
"OFB", "OFB64", "PCBC"};
private static final String[] PADDINGS = {"NoPadding", "Pkcs5Padding"};
private static final String[] PBE_ALGOS = {"PBEWithMD5AndDES",
"PBEWithMD5AndDES/CBC/PKCS5Padding"};
public static void main(String[] args) throws Exception {
// how many kinds of padding mode such as PKCS5padding and NoPadding
for (String algo : ALGOS) {
for (String mode : MODES) {
int padKinds = 1;
if (mode.equalsIgnoreCase("ECB")
|| mode.equalsIgnoreCase("PCBC")
|| mode.equalsIgnoreCase("CBC")) {
padKinds = PADDINGS.length;
}
// PKCS5padding is meaningful only for ECB, CBC, PCBC
for (int k = 0; k < padKinds; k++) {
String info = algo + "/" + mode + "/" + PADDINGS[k];
try {
CipherGenerator cg = new CipherGenerator(algo, mode,
PADDINGS[k]);
for (ReadMethod model : ReadMethod.values()) {
runTest(cg.getPair(), info, model);
}
} catch (LengthLimitException exp) {
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
out.println(exp.getMessage() + " is expected.");
}
}
}
}
for (String pbeAlgo : PBE_ALGOS) {
for (ReadMethod model : ReadMethod.values()) {
System.out.println("Testing Algorithm : " + pbeAlgo
+ " ReadMethod : " + model);
runTest(new CipherGenerator(pbeAlgo).getPair(), pbeAlgo, model);
}
}
}
private static void runTest(Cipher[] pair, String info, ReadMethod whichRead)
throws IOException {
byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
out.println("Testing: " + info + "/" + whichRead);
try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
CipherInputStream ciInput1 = new CipherInputStream(baInput,
pair[0]);
CipherInputStream ciInput2 = new CipherInputStream(ciInput1,
pair[1]);) {
// Skip 5 bytes after read 45 bytes and repeat until finish
// (Read from the input and write to the output using 2 types
// of buffering : byte[] and int)
// So output has size:
// (OVERALL/BLOCK)* SAVE = (800 / 50) * 45 = 720 bytes
int numOfBlocks = plainText.length / BLOCK;
// Output buffer.
byte[] outputText = new byte[numOfBlocks * SAVE];
int index = 0;
for (int i = 0; i < numOfBlocks; i++) {
index = whichRead.readByte(ciInput2, outputText, SAVE, index);
// If available is more than expected discard byte size. Skip
// discard bytes, otherwise try to read discard bytes by read.
if (ciInput2.available() >= DISCARD) {
ciInput2.skip(DISCARD);
} else {
for (int k = 0; k < DISCARD; k++) {
ciInput2.read();
}
}
}
// Verify output is same as input
if (!TestUtilities
.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
throw new RuntimeException("Test failed with compare fail");
}
}
}
}
class CipherGenerator {
/**
* Initialization vector length.
*/
private static final int IV_LENGTH = 8;
private static final String PASSWD = "Sesame!(@#$%^&*)";
private final Cipher[] pair = new Cipher[2];
// For DES/DESede ciphers
CipherGenerator(String algo, String mo, String pad)
throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException,
NoSuchPaddingException, SecurityException, LengthLimitException {
// Do initialization
KeyGenerator kg = KeyGenerator.getInstance(algo);
SecretKey key = kg.generateKey();
if (key.getEncoded().length * 8 > Cipher.getMaxAllowedKeyLength(algo)) {
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
throw new LengthLimitException(
"Skip this test if key length is larger than what's"
+ "configured in the jce jurisdiction policy files");
}
AlgorithmParameterSpec aps = null;
if (!mo.equalsIgnoreCase("ECB")) {
byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
aps = new IvParameterSpec(iv);
}
initCiphers(algo + "/" + mo + "/" + pad, key, aps);
}
// For PBE ciphers
CipherGenerator(String algo) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException,
NoSuchPaddingException, InvalidKeySpecException {
// Do initialization
byte[] salt = TestUtilities.generateBytes(IV_LENGTH);
int iterCnt = 6;
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);
SecretKey key = skf
.generateSecret(new PBEKeySpec(PASSWD.toCharArray()));
AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterCnt);
initCiphers(algo, key, aps);
}
private void initCiphers(String algo, SecretKey key,
AlgorithmParameterSpec aps) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException {
Provider provider = Security.getProvider("SunJCE");
if (provider == null) {
throw new RuntimeException("SunJCE provider does not exist.");
}
Cipher ci1 = Cipher.getInstance(algo, provider);
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
pair[0] = ci1;
Cipher ci2 = Cipher.getInstance(algo, provider);
ci2.init(Cipher.DECRYPT_MODE, key, aps);
pair[1] = ci2;
}
Cipher[] getPair() {
return pair;
}
}
enum ReadMethod {
// read one byte at a time for save times
READ_ONE_BYTE {
@Override
int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
int index) throws IOException {
for (int j = 0; j < save; j++, index++) {
int buffer0 = ciIn2.read();
if (buffer0 != -1) {
outputText[index] = (byte) buffer0;
} else {
break;
}
}
return index;
}
},
// read a chunk of save bytes if possible
READ_BLOCK {
@Override
int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
int index) throws IOException {
int len1 = ciIn2.read(outputText, index, save);
out.println("Init: index=" + index + ",len=" + len1);
// read more until save bytes
index += len1;
int len2 = 0;
while (len1 != save && len2 != -1) {
len2 = ciIn2.read(outputText, index, save - len1);
out.println("Cont: index=" + index + ",len=" + len2);
len1 += len2;
index += len2;
}
return index;
}
};
abstract int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
int index) throws IOException;
};
class LengthLimitException extends Exception {
public LengthLimitException(String string) {
super(string);
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
/**
* Wrapper class to test a given AES-based PBE algorithm.
*/
public class AESPBEWrapper extends AbstractPBEWrapper {
/**
* the algorithm parameters.
*/
private AlgorithmParameters pbeParams;
/**
* the encryption key.
*/
private final SecretKey key;
/**
* The Wrapper constructor. Instantiate Cipher using the given AES-based PBE
* algorithm.
*
* @param algo AES-based PBE algorithm.
* @param passwd password phrase.
* @throws GeneralSecurityException all security exceptions are thrown.
*/
public AESPBEWrapper(PBEAlgorithm algo, String passwd)
throws GeneralSecurityException {
// salt and iteration count will be generated during encryption
super(algo, passwd, 0);
// Generate secret key. We expect no mode and padding specified.
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.baseAlgo);
key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));
}
/**
* Initiate the Cipher object using given "mode".
* @return a cipher object.
* @throws GeneralSecurityException all security exceptions are thrown.
*/
@Override
protected Cipher initCipher(int mode) throws GeneralSecurityException {
Provider provider = Security.getProvider("SunJCE");
if (provider == null) {
throw new RuntimeException("SunJCE provider does not exist.");
}
// get Cipher instance
Cipher ci = Cipher.getInstance(transformation, provider);
if (Cipher.ENCRYPT_MODE == mode) {
ci.init(Cipher.ENCRYPT_MODE, key);
pbeParams = ci.getParameters();
} else {
ci.init(Cipher.DECRYPT_MODE, key, pbeParams);
}
return ci;
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
/**
* PBEWrapper is an abstract class for all concrete PBE Cipher wrappers.
*/
public abstract class AbstractPBEWrapper {
/**
* Iteration count.
*/
public static final int DEFAULT_ITERATION = 1000;
public static final String PBKDF2 = "PBKDF2";
public static final String AES = "AES";
public static final String DEFAULT = "default";
/**
* transformation the name of the transformation, e.g.,
* DES/CBC/PKCS5Padding
*/
protected final String transformation;
/**
* the standard name of the requested secret-key algorithm.
*/
protected final String baseAlgo;
/**
* The contents of salt are copied to protect against subsequent
* modification.
*/
protected final byte[] salt;
/**
* Password.
*/
protected final String password;
/**
* PBEWrapper creator.
*
* @param algo PBE algorithm to test
* @param passwd a password phrase
* @return PBEWrapper in accordance to requested algo.
* @throws GeneralSecurityException all exceptions are thrown.
*/
public static AbstractPBEWrapper createWrapper(PBEAlgorithm algo, String passwd)
throws GeneralSecurityException {
switch (algo.type) {
case PBKDF2:
return new PBKDF2Wrapper(algo, passwd);
case AES:
return new AESPBEWrapper(algo, passwd);
default:
return new DefaultPBEWrapper(algo, passwd);
}
}
/**
* PBEWrapper constructor.
*
* @param algo algorithm to wrap
* @param password password phrase
* @param saltSize salt size (defined in subclasses)
*/
protected AbstractPBEWrapper(PBEAlgorithm algo, String password, int saltSize) {
this.transformation = algo.getTransformation();
this.baseAlgo = algo.baseAlgo;
this.salt = TestUtilities.generateBytes(saltSize);
this.password = password;
}
/**
* Initialize Cipher object for the operation requested in the mode parameter.
*
* @param mode encryption or decryption
* @return a cipher initialize by mode.
* @throws GeneralSecurityException all security exceptions are thrown.
*/
protected abstract Cipher initCipher(int mode) throws GeneralSecurityException;
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8048604
* @summary This test verifies the assertion "The encrypt/decrypt
* mechanism of cipher should perform correctly." for feature
* "CipherInputStream & CipherOutputStream".
* @library ../
* @run main CICOPBEFuncTest
*/
import java.util.Arrays;
import javax.crypto.Cipher;
public class CICOPBEFuncTest {
public static void main(String[] args) throws Exception {
for (PBEAlgorithm algorithm : PBEAlgorithm.values()) {
// int buffertin test
String algo = algorithm.baseAlgo.toUpperCase();
if (!algo.contains("TRIPLEDES") && !algo.contains("AES_256")
|| Cipher.getMaxAllowedKeyLength(algo) > 128) {
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
System.out.println("Testing " + algorithm.getTransformation());
for (String type : Arrays.asList(CICO_PBE_Test.INT_BYTE_BUFFER,
CICO_PBE_Test.BYTE_ARR_BUFFER)) {
new CICO_PBE_RW_Test(algorithm)
.proceedTest(type);
new CICO_PBE_SKIP_Test(algorithm)
.proceedTest(type);
}
}
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.crypto.CipherOutputStream;
/**
* CICO PBE Read/Write functional test.
*
* Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
* performed correctly for CipherInputStream and CipherOutputStream.
*
* Test scenario:
* 1. initializes plain text with random generated data.
* 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
* 3. instantiates CipherInputStream with the encrypt Cipher.
* 4. instantiates CipherOutputStream with the decrypt Cipher.
* 5. performs reading from the CipherInputStream (encryption data) and writing
* to the CipherOutputStream (decryption). As a result the output of the
* CipherOutputStream should be the same as an original plain text.
* 6. compares if the original plain text is the same as the output of the
* CipherOutputStream.
*
* The test implements 2 test cases in accordance with buffering type:
* 1. byte array buffering
* 2. int buffering
*/
public class CICO_PBE_RW_Test extends CICO_PBE_Test {
public CICO_PBE_RW_Test(PBEAlgorithm pbeAlgo)
throws GeneralSecurityException {
super(pbeAlgo);
}
/**
* The CICO PBE RW test specific part of the super.doTest(). Implements the
* scenario in accordance to the class description.
* @param type byteArrayBuffering or intByteBuffering
* @throws IOException any I/O operation failed.
* @throws GeneralSecurityException any security error.
*/
@Override
public void proceedTest(String type) throws IOException,
GeneralSecurityException {
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
getDecryptCipher())) {
if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
proceedTestUsingByteArrayBuffer(ciOutput);
} else {
proceedTestUsingIntBuffer(ciOutput);
}
ciOutput.flush();
}
// Compare input and output
if (!TestUtilities.equalsBlock(plainText, baOutput.toByteArray(), TEXT_SIZE)) {
throw new RuntimeException("outputText not same with expectedText"
+ " when test " + type);
}
}
/**
* Implements byte array buffering type test case of the CICO PBE RW test.
* @param ciOutput output stream for data written.
* @throws java.io.IOException any I/O operation failed.
*/
public void proceedTestUsingByteArrayBuffer(
CipherOutputStream ciOutput) throws IOException {
byte[] buffer = new byte[TEXT_SIZE];
int len = getCiInput().read(buffer);
while (len != -1) {
ciOutput.write(buffer, 0, len);
len = getCiInput().read(buffer);
}
}
/**
* Implements int buffering type test case.
* @param ciOutput output stream for data written.
* @throws java.io.IOException any I/O operation failed.
*/
public void proceedTestUsingIntBuffer(CipherOutputStream ciOutput)
throws IOException {
int buffer = getCiInput().read();
while (buffer != -1) {
ciOutput.write(buffer);
buffer = getCiInput().read();
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.crypto.CipherInputStream;
/**
* CICO PBE SKIP functional test.
*
* Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
* performed correctly for CipherInputStream when skip() method is used.
*
* Test scenario:
* 1. initializes plain text with random generated data with length TEXT_SIZE.
* 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
* 3. instantiates CipherInputStream 1 with the encrypt Cipher.
* 4. instantiates CipherInputStream 2 with the CipherInputStream 1 and decrypt
* Cipher.
* 5. the plain text is divided on TEXT_SIZE/BLOCK blocks. Reading from
* CipherInputStream 2 one block at time. The last BLOCK - SAVE bytes are
* skipping for each block. Therefor the plain text data go through
* CipherInputStream 1 (encrypting) and CipherInputStream 2 (decrypting).
* As a result the output should equal to the original text except DISCARD
* byte for each block are skipped.
* 6. get the standard output.
* 7. compares the expected standard output with the output of the
* CipherInputStream 2. If it is the same the test passed. Otherwise it
* failed. Any uncaught exceptions should be considered as an error.
* The test implements 2 test cases in accordance with a buffering type:
* 1. byte array buffering
* 2. int buffering
*/
public class CICO_PBE_SKIP_Test extends CICO_PBE_Test {
/**
* Block size.
*/
private static final int BLOCK = 50;
/**
* Valid reading byte size.
*/
private static final int SAVE = 45;
/**
* Skip reading byte size. This should be same to BLOCK - SAVE
*/
private static final int DISCARD = BLOCK - SAVE;
/**
* Number of blocks.
*/
private static final int NUMBER_OF_BLOCKS = TEXT_SIZE / BLOCK;
private final byte[] outputText;
/**
* CICO PBE Skip test constructor
*
* @param pbeAlgo the PBE algorithm to test.
* @throws java.security.GeneralSecurityException
*/
public CICO_PBE_SKIP_Test(PBEAlgorithm pbeAlgo)
throws GeneralSecurityException {
super(pbeAlgo);
outputText = new byte[NUMBER_OF_BLOCKS * SAVE];
}
/**
* Implements byte array buffering type test case of the CICO SKIP test.
*
* @param blockNum block number to read.
*/
private void proceedSkipTestUsingByteArrayBufferingType(
CipherInputStream ciIn2, int blockNum) throws IOException {
int index = blockNum * SAVE;
int len1 = ciIn2.read(outputText, index, SAVE);
// read more until SAVE bytes
index += len1;
int len2 = 0;
int totalRead = len1;
while (len1 != SAVE && len2 != -1) {
len2 = ciIn2.read(outputText, index, SAVE - len1);
len1 += len2;
index += len2;
totalRead += len2;
}
if (totalRead != SAVE) {
throw new RuntimeException("Read bytes number " + totalRead
+ " does not equal to given number " + SAVE);
}
}
/**
* Implements int buffering type test case of the CICO SKIP test.
*
* @param blockNum block number to read.
*/
private void proceedSkipTestUsingIntBufferingType(CipherInputStream ciIn2,
int blockNum) throws IOException {
int index = blockNum * SAVE;
int totalRead = 0;
for (int j = 0; j < SAVE; j++, index++) {
int buffer0 = ciIn2.read();
if (buffer0 != -1) {
outputText[index] = (byte) buffer0;
totalRead++;
} else {
break;
}
}
if (totalRead != SAVE) {
throw new RuntimeException("Read bytes number " + totalRead
+ " does not equal to given number " + SAVE);
}
}
/**
* The CICO PBE SKIP test specific part of the super.doTest(). Implements
* the scenario in accordance to the class description.
* @throws java.io.IOException any I/O failed.
*/
@Override
public void proceedTest(String type) throws IOException {
System.out.println("Test type: " + type);
// init second input stream with decrypt Cipher
try (CipherInputStream ciIn2 = new CipherInputStream(getCiInput(),
getDecryptCipher())) {
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
proceedSkipTestUsingByteArrayBufferingType(ciIn2, i);
} else {
proceedSkipTestUsingIntBufferingType(ciIn2, i);
}
if (ciIn2.available() >= DISCARD) {
ciIn2.skip(DISCARD);
} else {
for (int k = 0; k < DISCARD; k++) {
ciIn2.read();
}
}
}
}
if (!TestUtilities.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
throw new RuntimeException("outputText not same with expectedText"
+ " when test " + type);
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
/**
* This is an abstract class for CipherInputStream/CipherOutputStream PBE
* functional tests.
*/
public abstract class CICO_PBE_Test {
/**
* Sample string for byte buffer.
*/
public static final String BYTE_ARR_BUFFER = "byteArrayBuffering";
/**
* Sample string for int buffer.
*/
public static final String INT_BYTE_BUFFER = "intByteBuffering";
public static final String PASS_PHRASE = "Some password phrase!";
/**
* Text string size.
*/
public static final int TEXT_SIZE = 800;
protected final byte[] plainText;
private final Cipher encryptCipher, decryptCipher;
/**
* An CipherInputStream for reading cipher and plain text.
*/
private final CipherInputStream ciInput;
/**
* Constructor by algorithm.
* @param pbeAlgo PBE algorithm to test.
* @throws GeneralSecurityException if any security error.
*/
public CICO_PBE_Test(PBEAlgorithm pbeAlgo) throws GeneralSecurityException {
// Do initialization of the plainText
plainText = TestUtilities.generateBytes(TEXT_SIZE);
// Do initialization of the ciphers
AbstractPBEWrapper pbeWrap = AbstractPBEWrapper.createWrapper(pbeAlgo, PASS_PHRASE);
encryptCipher = pbeWrap.initCipher(Cipher.ENCRYPT_MODE);
decryptCipher = pbeWrap.initCipher(Cipher.DECRYPT_MODE);
// init cipher input stream
ciInput = new CipherInputStream(new ByteArrayInputStream(plainText),
encryptCipher);
}
protected byte[] getPlainText() {
return plainText;
}
/**
* The body of the test. Should be defined in subclasses.
* @param type byteArrayBuffering or intByteBuffering
* @throws IOException I/O operation failed.
* @throws GeneralSecurityException all exceptions thrown.
*/
protected abstract void proceedTest(String type)
throws IOException, GeneralSecurityException;
protected Cipher getEncryptCipher() {
return encryptCipher;
}
public CipherInputStream getCiInput() {
return ciInput;
}
public Cipher getDecryptCipher() {
return decryptCipher;
}
}
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8048604
* @library ../ /lib/testlibrary
* @summary This test verifies the assertion "There should be no transformation
* on the plaintext/ciphertext in encryption/decryption mechanism" for
* feature "NullCipher".
*/
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NullCipher;
import javax.crypto.ShortBufferException;
import jdk.testlibrary.RandomFactory;
public class CipherNCFuncTest {
public static void main(String[] args) throws ShortBufferException,
IllegalBlockSizeException, BadPaddingException {
byte[] plainText = new byte[801];
// Initialization
RandomFactory.getRandom().nextBytes(plainText);
Cipher ci = new NullCipher();
// Encryption
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
int offset = ci.update(plainText, 0, plainText.length, cipherText, 0);
ci.doFinal(cipherText, offset);
// Decryption
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
int len = ci.doFinal(cipherText, 0, cipherText.length, recoveredText);
// Comparison
if (len != plainText.length ||
!TestUtilities.equalsBlock(plainText, cipherText, len) ||
!TestUtilities.equalsBlock(plainText, recoveredText, len)) {
throw new RuntimeException(
"Test failed because plainText not equal to cipherText and revoveredText");
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/**
* Default wrapper for a password based encryption Cipher.
*/
public class DefaultPBEWrapper extends AbstractPBEWrapper {
/**
* Define default SALT size as 8.
*/
private static final int PBE_SALT_SIZE = 8;
/**
* Default PBE wrapper constructor.
*
* @param algo PGE algorithm to wrap.
* @param passwd password phrase
*/
public DefaultPBEWrapper(PBEAlgorithm algo, String passwd) {
super(algo, passwd, PBE_SALT_SIZE);
}
/**
* Instantiate Cipher for the PBE algorithm.
*
* @param mode Cipher mode: encrypt or decrypt.
* @return Cipher in accordance to the PBE algorithm
* @throws java.security.GeneralSecurityException
*/
@Override
protected Cipher initCipher(int mode) throws GeneralSecurityException {
Provider provider = Security.getProvider("SunJCE");
if (provider == null) {
throw new RuntimeException("SunJCE provider does not exist.");
}
SecretKey key = SecretKeyFactory.getInstance(baseAlgo)
.generateSecret(new PBEKeySpec(password.toCharArray()));
Cipher ci = Cipher.getInstance(transformation, provider);
ci.init(mode, key, new PBEParameterSpec(salt, DEFAULT_ITERATION));
return ci;
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.StringJoiner;
public enum PBEAlgorithm {
MD5_DES("PBEWithMD5ANDdes", "", "", AbstractPBEWrapper.DEFAULT),
MD5_DES_CBC_PKCS5("PBEWithMD5AndDES", "CBC", "PKCS5Padding",
AbstractPBEWrapper.DEFAULT),
MD5_TRIPLEDES("PBEWithMD5ANDtripledes", "", "", AbstractPBEWrapper.DEFAULT),
MD5_TRIPLEDES_CBC_PKCS5("PBEWithMD5AndTRIPLEDES", "CBC", "PKCS5Padding",
AbstractPBEWrapper.DEFAULT),
SHA1_DESEDE("PBEwithSHA1AndDESede", "", "", AbstractPBEWrapper.DEFAULT),
SHA1_DESEDE_CBC_PKCS5("PBEwithSHA1AndDESede", "CBC", "PKCS5Padding",
AbstractPBEWrapper.DEFAULT),
SHA1_RC2_40("PBEwithSHA1AndRC2_40", "", "", AbstractPBEWrapper.DEFAULT),
SHA1_RC2_40_PKCS5("PBEwithSHA1Andrc2_40", "CBC", "PKCS5Padding",
AbstractPBEWrapper.DEFAULT),
SHA1_RC2_128("PBEWithSHA1AndRC2_128", "", "", AbstractPBEWrapper.DEFAULT),
SHA1_RC2_128_PKCS5("PBEWithSHA1andRC2_128", "CBC", "PKCS5Padding",
AbstractPBEWrapper.DEFAULT),
SHA1_RC4_40("PBEWithSHA1AndRC4_40", "", "", AbstractPBEWrapper.DEFAULT),
SHA1_RC4_40_ECB_NOPADDING("PBEWithsha1AndRC4_40", "ECB", "NoPadding",
AbstractPBEWrapper.DEFAULT),
SHA1_RC4_128("PBEWithSHA1AndRC4_128", "", "", AbstractPBEWrapper.DEFAULT),
SHA1_RC4_128_ECB_NOPADDING("pbeWithSHA1AndRC4_128", "ECB", "NoPadding",
AbstractPBEWrapper.DEFAULT),
HMAC_SHA1_AES_128("PBEWithHmacSHA1AndAES_128", "", "", AbstractPBEWrapper.AES),
HMAC_SHA224_AES_128("PBEWithHmacSHA224AndAES_128", "", "", AbstractPBEWrapper.AES),
HMAC_SHA256_AES_128("PBEWithHmacSHA256AndAES_128", "", "", AbstractPBEWrapper.AES),
HMAC_SHA384_AES_128("PBEWithHmacSHA384AndAES_128", "", "", AbstractPBEWrapper.AES),
HMAC_SHA512_AES_128("PBEWithHmacSHA512AndAES_128", "", "", AbstractPBEWrapper.AES),
HMAC_SHA1_AES_256("PBEWithHmacSHA1AndAES_256", "", "", AbstractPBEWrapper.AES),
HMAC_SHA224_AES_256("PBEWithHmacSHA224AndAES_256", "", "", AbstractPBEWrapper.AES),
HMAC_SHA256_AES_256("PBEWithHmacSHA256AndAES_256", "", "", AbstractPBEWrapper.AES),
HMAC_SHA384_AES_256("PBEWithHmacSHA384AndAES_256", "", "", AbstractPBEWrapper.AES),
HMAC_SHA512_AES_256("PBEWithHmacSHA512AndAES_256", "", "", AbstractPBEWrapper.AES),
PBKDF_HMAC_SHA1("PBKDF2WithHmacSHA1", "", "", AbstractPBEWrapper.PBKDF2),
PBKDF_HMAC_SHA224("PBKDF2WithHmacSHA224", "", "", AbstractPBEWrapper.PBKDF2),
PBKDF_HMAC_SHA256("PBKDF2WithHmacSHA256", "", "", AbstractPBEWrapper.PBKDF2),
PBKDF_HMAC_SHA384("PBKDF2WithHmacSHA384", "", "", AbstractPBEWrapper.PBKDF2),
PBKDF_HMAC_SHA512("PBKDF2WithHmacSHA512", "", "", AbstractPBEWrapper.PBKDF2);
final String baseAlgo;
final String mode;
final String padding;
final String type;
PBEAlgorithm(String alg, String mode, String padding, String type) {
this.baseAlgo = alg;
this.mode = mode;
this.padding = padding;
this.type = type;
}
public String getTransformation() {
StringJoiner sj = new StringJoiner("/");
sj.add(baseAlgo);
if (!mode.equals("")) {
sj.add(this.mode);
}
if (!padding.equals("")) {
sj.add(this.padding);
}
return sj.toString();
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm.
*/
public class PBKDF2Wrapper extends AbstractPBEWrapper {
/**
* Default salt size.
*/
public static final int PBKDF2_SALT_SIZE = 64;
/**
* Default key length.
*/
public static final int PKDF2_DEFAULT_KEY_LEN = 128;
/**
* Default transformation.
*/
public static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
/**
* Algorithm name.
*/
public static final String KEY_ALGORITHM = "AES";
/**
* Initialization vector length.
*/
private static final int IV_LENGTH = 16;
/**
* The buffer with the IV.
*/
private final byte[] iv;
/**
* PBKDF2Wrapper constructor. Instantiate Cipher using
* "AES/CBC/PKCS5Padding" transformation. Generate a secret key using PKDF2
* algorithms given in the "algo" parameter.
*
* @param algo AES-based PBE algorithm.
* @param passwd password phrase.
* @throws GeneralSecurityException all security exceptions are thrown.
*/
public PBKDF2Wrapper(PBEAlgorithm algo, String passwd)
throws GeneralSecurityException {
super(algo, passwd, PBKDF2_SALT_SIZE);
iv = TestUtilities.generateBytes(IV_LENGTH);
}
/**
* Initiate the Cipher object for PBKDF2 algorithm using given "mode".
*
* @param mode Cipher mode: encrypt or decrypt
* @return Cipher object for PBKDF2 algorithm
* @throws GeneralSecurityException all security exceptions are thrown.
*/
@Override
protected Cipher initCipher(int mode) throws GeneralSecurityException {
Provider provider = Security.getProvider("SunJCE");
if (provider == null) {
throw new RuntimeException("SunJCE provider does not exist.");
}
// Generate secret key
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(),
salt, DEFAULT_ITERATION, PKDF2_DEFAULT_KEY_LEN);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(baseAlgo);
SecretKey key = keyFactory.generateSecret(pbeKeySpec);
// get Cipher instance
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION, provider);
cipher.init(mode,
new SecretKeySpec(key.getEncoded(),KEY_ALGORITHM),
new IvParameterSpec(iv));
return cipher;
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
/**
* ReadModel provides different way to test
* CipherInputStream.read()/read(byte[])/read(byte[], int, int) and
* CipherOutputStream.write(int)/write(byte[], int, int)/read(byte[]) API
*/
enum ReadModel {
READ_BYTE {
@Override
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
Cipher ciIn, int inputLen) throws IOException {
int buffer0 = cInput.read();
while (buffer0 != -1) {
ciOutput.write(buffer0);
buffer0 = cInput.read();
}
}
},
READ_BUFFER {
@Override
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
Cipher ciIn, int inputLen) throws IOException {
byte[] buffer1 = new byte[20];
int len1;
while ((len1 = cInput.read(buffer1)) != -1) {
ciOutput.write(buffer1, 0, len1);
}
}
},
READ_BUFFER_OFFSET {
@Override
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
Cipher ciIn, int inputLen) throws IOException {
byte[] buffer2 = new byte[ciIn.getOutputSize(inputLen)];
int offset2 = 0;
int len2 = 0;
while (len2 != -1) {
len2 = cInput.read(buffer2, offset2, buffer2.length - offset2);
offset2 += len2;
}
ciOutput.write(buffer2);
}
};
abstract public void read(CipherInputStream cInput,
CipherOutputStream ciOutput, Cipher ciIn, int inputLen)
throws IOException;
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* utility class
*/
public class TestUtilities {
public static boolean equalsBlock(byte[] b1, byte[] b2, int len) {
for (int i = 0; i < len; i++) {
if (b1[i] != b2[i]) {
System.err.println("b1[" + i + "] : " + b1[i]
+ " b2[" + i + "] : " + b2[i]);
return false;
}
}
return true;
}
public static boolean equals(byte[] b1, byte[] b2) {
if (b2.length != b1.length) {
System.err.println("b1.length = " + b1.length
+ " b2.length = " + b2.length );
return false;
}
return equalsBlock(b1, b2, b1.length);
}
/**
* Verify b1's partial part is same as b2. compares b1 and b2 by chopping up
* b1 into blocks of b1BKSize and b2 into blocks of b2BKSize, and then
* compare the first b2BKSize bytes of each block, return true if they equal
* , otherwise return false.
* @param b1 byte array to be compared.
* @param b2 saved byte array.
* @param b1BKSize b1's block size.
* @param b2BKSize b2's block size.
* @return true is same. false otherwise.
*/
public static boolean equalsBlockPartial(byte[] b1, byte[] b2, int b1BKSize,
int b2BKSize) {
int numOfBlock = b1.length / b1BKSize;
for (int b = 0; b < numOfBlock; b++) {
for (int i = 0; i < b2BKSize; i++) {
int j1 = b * b1BKSize + i;
int j2 = b * b2BKSize + i;
if (b1[j1] != b2[j2]) {
System.err.println("Compare failed at b1[" + j1 + "]:" +
b1[j1] + " b2[" + j2 + "]:" + b2[j2]);
return false;
}
}
}
return true;
}
/**
* Generate a byte block by given length. The content of byte block
* is determined by the index.
* @param length length of byte array
* @return a byte array
*/
public static byte[] generateBytes(int length) {
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = (byte) (i & 0xff);
}
return bytes;
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
/*
* @test
* @bug 8048596
* @summary AEAD encryption/decryption test
*/
/*
* The test does the following:
* - create an input text and additional data
* - generate a secret key
* - instantiate a cipher according to the GCM transformation
* - generate an outputText using a single-part encryption/decryption
* in AEAD mode
* - perform 16 different combinations of multiple-part encryption/decryption
* operation in AEAD mode (in encryption mode new Cipher object is created
* and initialized with the same secret key and parameters)
* - check that all 17 results are equal
*
* Combinations:
*
* combination #1
* updateAAD(byte[] src)
* update(byte[], int, int)
* doFinal(byte[], int, int)
*
* combination #2
* updateAAD(byte[] src)
* update(byte[], int, int)
* doFinal(byte[], int, int, byte[], int)
*
* combination #3
* updateAAD(byte[] src)
* update(byte[], int, int, byte[], int)
* doFinal(byte[], int, int)
*
* combination #4
* updateAAD(byte[] src)
* update(byte[], int, int, byte[], int)
* doFinal(byte[], int, int, byte[], int)
*
* combination #5 - #8 are similar to #1 -#4,
* but with updateAAD(byte[] src, int offset, int len)
*
* combination #9 - #12 are similar to #1 - #4,
* but with updateAAD(ByteBuffer src)
*
* combination #13 - #16 are similar to #9 - #12 but with directly allocated
* ByteBuffer and update(ByteBuffer input, ByteBuffer output)
*
*/
public class Encrypt {
private static final String ALGORITHMS[] = { "AES", "Rijndael" };
private static final int KEY_STRENGTHS[] = { 128, 192, 256 };
private static final int TEXT_LENGTHS[] = { 0, 256, 1024 };
private static final int AAD_LENGTHS[] = { 0, 8, 128, 256, 1024 };
private static final int ARRAY_OFFSET = 8;
private final String transformation;
private final Provider provider;
private final SecretKey key;
private final int textLength;
private final int AADLength;
/**
* @param provider Security provider
* @param algorithm Security algorithm to test
* @param mode The mode (GCM is only expected)
* @param padding Algorithm padding
* @param keyStrength key length
* @param textLength Plain text length
* @param AADLength Additional data length
*/
public Encrypt(Provider provider, String algorithm, String mode,
String padding, int keyStrength, int textLength, int AADLength)
throws Exception {
// init a secret Key
KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider);
kg.init(keyStrength);
key = kg.generateKey();
this.provider = provider;
this.transformation = algorithm + "/" + mode + "/" + padding;
this.textLength = textLength;
this.AADLength = AADLength;
}
public static void main(String[] args) throws Exception {
Provider p = Security.getProvider("SunJCE");
for (String alg : ALGORITHMS) {
for (int keyStrength : KEY_STRENGTHS) {
if (keyStrength > Cipher.getMaxAllowedKeyLength(alg)) {
// skip this if this key length is larger than what's
// configured in the JCE jurisdiction policy files
continue;
}
for (int textLength : TEXT_LENGTHS) {
for (int AADLength : AAD_LENGTHS) {
Encrypt test = new Encrypt(p, alg,
"GCM", "NoPadding", keyStrength, textLength,
AADLength);
Cipher cipher = test.createCipher(Cipher.ENCRYPT_MODE,
null);
AlgorithmParameters params = cipher.getParameters();
test.doTest(params);
System.out.println("Test " + alg + ":"
+ keyStrength + ":" + textLength + ":"
+ AADLength + " passed");
}
}
}
}
}
public void doTest(AlgorithmParameters params) throws Exception {
System.out.println("Test transformation = " + transformation
+ ", textLength = " + textLength
+ ", AADLength = " + AADLength);
byte[] input = Helper.generateBytes(textLength);
byte[] AAD = Helper.generateBytes(AADLength);
byte[] result = execute(Cipher.ENCRYPT_MODE, AAD, input, params);
result = execute(Cipher.DECRYPT_MODE, AAD, result, params);
if (!Arrays.equals(input, result)) {
throw new RuntimeException("Test failed");
}
System.out.println("Test passed");
}
/**
* Create a Cipher object for the requested encryption/decryption mode.
*
* @param mode encryption or decryption mode
* @return Cipher object initiated to perform requested mode operation
*/
private Cipher createCipher(int mode, AlgorithmParameters params)
throws Exception {
Cipher ci;
if (Cipher.ENCRYPT_MODE == mode) {
// create a new Cipher object for encryption
ci = Cipher.getInstance(transformation, provider);
// initiate it with the saved parameters
if (params != null) {
ci.init(Cipher.ENCRYPT_MODE, key, params);
} else {
// initiate the cipher without parameters
ci.init(Cipher.ENCRYPT_MODE, key);
}
} else {
// it is expected that parameters already generated
// before decryption
ci = Cipher.getInstance(transformation, provider);
ci.init(Cipher.DECRYPT_MODE, key, params);
}
return ci;
}
/**
* Test AEAD combinations
*
* @param mode decryption or encryption
* @param AAD additional data for AEAD operations
* @param inputText plain text to decrypt/encrypt
* @return output text after encrypt/decrypt
*/
public byte[] execute(int mode, byte[] AAD, byte[] inputText,
AlgorithmParameters params) throws Exception {
Cipher cipher = createCipher(mode, params);
// results of each combination will be saved in the outputTexts
List<byte[]> outputTexts = new ArrayList<>();
// generate a standard outputText using a single-part en/de-cryption
cipher.updateAAD(AAD);
byte[] output = cipher.doFinal(inputText);
// execute multiple-part encryption/decryption combinations
combination_1(outputTexts, mode, AAD, inputText, params);
combination_2(outputTexts, mode, AAD, inputText, params);
combination_3(outputTexts, mode, AAD, inputText, params);
combination_4(outputTexts, mode, AAD, inputText, params);
combination_5(outputTexts, mode, AAD, inputText, params);
combination_6(outputTexts, mode, AAD, inputText, params);
combination_7(outputTexts, mode, AAD, inputText, params);
combination_8(outputTexts, mode, AAD, inputText, params);
combination_9(outputTexts, mode, AAD, inputText, params);
combination_10(outputTexts, mode, AAD, inputText, params);
combination_11(outputTexts, mode, AAD, inputText, params);
combination_12(outputTexts, mode, AAD, inputText, params);
combination_13(outputTexts, mode, AAD, inputText, params);
combination_14(outputTexts, mode, AAD, inputText, params);
combination_15(outputTexts, mode, AAD, inputText, params);
combination_16(outputTexts, mode, AAD, inputText, params);
for (int k = 0; k < outputTexts.size(); k++) {
if (!Arrays.equals(output, outputTexts.get(k))) {
throw new RuntimeException("Combination #" + k + " failed");
}
}
return output;
}
/*
* Execute multiple-part encryption/decryption combination #1:
* updateAAD(byte[] src)
* update(byte[], int, int)
* doFinal(byte[], int, int)
*/
private void combination_1(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
c.updateAAD(AAD);
byte[] part11 = c.update(plainText, 0, plainText.length);
int part11_length = part11 == null ? 0 : part11.length;
byte[] part12 = c.doFinal();
byte[] outputText1 = new byte[part11_length + part12.length];
if (part11 != null) {
System.arraycopy(part11, 0, outputText1, 0, part11_length);
}
System.arraycopy(part12, 0, outputText1, part11_length, part12.length);
results.add(outputText1);
}
/*
* Execute multiple-part encryption/decryption combination #2:
* updateAAD(byte[] src)
* update(byte[], int, int)
* doFinal(byte[], int, int, byte[], int)
*/
private void combination_2(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
c.updateAAD(AAD);
int t = 0;
int offset = 0;
if (plainText.length > ARRAY_OFFSET) {
t = plainText.length - ARRAY_OFFSET;
offset = ARRAY_OFFSET;
}
byte[] part21 = c.update(plainText, 0, t);
byte[] part22 = new byte[c.getOutputSize(plainText.length)];
int len2 = c.doFinal(plainText, t, offset, part22, 0);
int part21Length = part21 != null ? part21.length : 0;
byte[] outputText2 = new byte[part21Length + len2];
if (part21 != null) {
System.arraycopy(part21, 0, outputText2, 0, part21Length);
}
System.arraycopy(part22, 0, outputText2, part21Length, len2);
results.add(outputText2);
}
/*
* Execute multiple-part encryption/decryption combination #3
* updateAAD(byte[] src)
* update(byte[], int, int, byte[], int)
* doFinal(byte[], int, int)
*/
private void combination_3(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher ci = createCipher(mode, params);
ci.updateAAD(AAD);
byte[] part31 = new byte[ci.getOutputSize(plainText.length)];
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
int len = ci.update(plainText, 0, plainText.length - offset, part31, 0);
byte[] part32 = ci.doFinal(plainText, plainText.length - offset,
offset);
byte[] outputText3 = new byte[len + part32.length];
System.arraycopy(part31, 0, outputText3, 0, len);
System.arraycopy(part32, 0, outputText3, len, part32.length);
results.add(outputText3);
}
/*
* Execute multiple-part encryption/decryption combination #4:
* updateAAD(byte[] src)
* update(byte[], int, int, byte[], int)
* doFinal(byte[], int, int, byte[], int)
*/
private void combination_4(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher ci = createCipher(mode, params);
ci.updateAAD(AAD);
byte[] part41 = new byte[ci.getOutputSize(plainText.length)];
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
int len = ci.update(plainText, 0, plainText.length - offset, part41, 0);
int rest4 = ci.doFinal(plainText, plainText.length - offset, offset,
part41, len);
byte[] outputText4 = new byte[len + rest4];
System.arraycopy(part41, 0, outputText4, 0, outputText4.length);
results.add(outputText4);
}
/*
* Execute multiple-part encryption/decryption combination #5:
* updateAAD(byte[] src, int offset, int len)
* update(byte[], int, int)
* doFinal(byte[], int, int)
*/
private void combination_5(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
c.updateAAD(AAD, 0, AAD.length);
byte[] part51 = c.update(plainText, 0, plainText.length);
byte[] part52 = c.doFinal();
int part51Length = part51 != null ? part51.length : 0;
byte[] outputText5 = new byte[part51Length + part52.length];
if (part51 != null) {
System.arraycopy(part51, 0, outputText5, 0, part51Length);
}
System.arraycopy(part52, 0, outputText5, part51Length, part52.length);
results.add(outputText5);
}
/*
* Execute multiple-part encryption/decryption combination #6:
* updateAAD(byte[] src, int offset, int len)
* updateAAD(byte[] src, int offset, int len)
* update(byte[], int, int) doFinal(byte[], int, int, byte[], int)
*/
private void combination_6(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
c.updateAAD(AAD, 0, AAD.length / 2);
c.updateAAD(AAD, AAD.length / 2, AAD.length - AAD.length / 2);
int t = 0;
int offset = 0;
if (plainText.length > ARRAY_OFFSET) {
t = plainText.length - ARRAY_OFFSET;
offset = ARRAY_OFFSET;
}
byte[] part61 = c.update(plainText, 0, t);
byte[] part62 = new byte[c.getOutputSize(plainText.length)];
int len = c.doFinal(plainText, t, offset, part62, 0);
int part61Length = part61 != null ? part61.length : 0;
byte[] outputText6 = new byte[part61Length + len];
if (part61 != null) {
System.arraycopy(part61, 0, outputText6, 0, part61Length);
}
System.arraycopy(part62, 0, outputText6, part61Length, len);
results.add(outputText6);
}
/*
* Execute multiple-part encryption/decryption combination #7
* updateAAD(byte[] src, int offset, int len)
* updateAAD(byte[] src, src.length, 0)
* update(byte[], int, int, byte[], int) doFinal(byte[],int, int)
*/
private void combination_7(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher ci = createCipher(mode, params);
ci.updateAAD(AAD, 0, AAD.length);
ci.updateAAD(AAD, AAD.length, 0);
byte[] part71 = new byte[ci.getOutputSize(plainText.length)];
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
int len = ci.update(plainText, 0, plainText.length - offset, part71, 0);
byte[] part72 = ci.doFinal(plainText, plainText.length - offset, offset);
byte[] outputText7 = new byte[len + part72.length];
System.arraycopy(part71, 0, outputText7, 0, len);
System.arraycopy(part72, 0, outputText7, len, part72.length);
results.add(outputText7);
}
/*
* Execute multiple-part encryption/decryption combination #8:
* updateAAD(byte[] src, 0, 0)
* updateAAD(byte[] src, 0, src.length)
* update(byte[], int, int, byte[], int)
* doFinal(byte[], int, int, byte[], int)
*/
private void combination_8(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher ci = createCipher(mode, params);
ci.updateAAD(AAD, 0, 0);
ci.updateAAD(AAD, 0, AAD.length);
byte[] part81 = new byte[ci.getOutputSize(plainText.length)];
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
int len = ci.update(plainText, 0, plainText.length - offset, part81, 0);
int rest = ci.doFinal(plainText, plainText.length - offset, offset,
part81, len);
byte[] outputText8 = new byte[len + rest];
System.arraycopy(part81, 0, outputText8, 0, outputText8.length);
results.add(outputText8);
}
/*
* Execute multiple-part encryption/decryption combination #9:
* updateAAD(ByteBuffer src)
* update(byte[], int, int) doFinal(byte[], int, int)
*/
private void combination_9(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
// prepare ByteBuffer to test
ByteBuffer buf = ByteBuffer.allocate(AAD.length);
buf.put(AAD);
buf.position(0);
buf.limit(AAD.length);
// Get Cipher object and do the combination
Cipher c = createCipher(mode, params);
c.updateAAD(buf);
byte[] part91 = c.update(plainText, 0, plainText.length);
int part91_length = part91 == null ? 0 : part91.length;
byte[] part92 = c.doFinal();
byte[] outputText9 = new byte[part91_length + part92.length];
// form result of the combination
if (part91 != null) {
System.arraycopy(part91, 0, outputText9, 0, part91_length);
}
System.arraycopy(part92, 0, outputText9, part91_length, part92.length);
results.add(outputText9);
}
/*
* Execute multiple-part encryption/decryption combination #10:
* updateAAD(ByteBuffer src)
* updateAAD(ByteBuffer src) update(byte[], int, int)
* doFinal(byte[], int, int, byte[], int)
*/
private void combination_10(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
// prepare ByteBuffer to test
ByteBuffer buf = ByteBuffer.allocate(AAD.length);
buf.put(AAD);
buf.position(0);
buf.limit(AAD.length / 2);
// get a Cipher object and do the combination
Cipher c = createCipher(mode, params);
// process the first half of AAD data
c.updateAAD(buf);
// process the rest of AAD data
buf.limit(AAD.length);
c.updateAAD(buf);
// prapare variables for the combination
int t = 0;
int offset = 0;
if (plainText.length > ARRAY_OFFSET) {
t = plainText.length - ARRAY_OFFSET;
offset = ARRAY_OFFSET;
}
// encrypt the text
byte[] part10_1 = c.update(plainText, 0, t);
int part10_1_Length = part10_1 != null ? part10_1.length : 0;
byte[] part10_2 = new byte[c.getOutputSize(plainText.length)];
int len2 = c.doFinal(plainText, t, offset, part10_2, 0);
// form the combination's result
byte[] outputText10 = new byte[part10_1_Length + len2];
if (part10_1 != null) {
System.arraycopy(part10_1, 0, outputText10, 0, part10_1_Length);
}
System.arraycopy(part10_2, 0, outputText10, part10_1_Length, len2);
results.add(outputText10);
}
/*
* Execute multiple-part encryption/decryption combination #11
* updateAAD(ByteBuffer src1)
* updateAAD(ByteBuffer src2)
* update(byte[],int, int, byte[], int)
* doFinal(byte[], int, int)
*/
private void combination_11(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
// prepare ByteBuffer1 to test
ByteBuffer buf1 = ByteBuffer.allocate(AAD.length / 2);
buf1.put(AAD, 0, AAD.length / 2);
buf1.position(0);
buf1.limit(AAD.length / 2);
// get a Cipher object and do combination
Cipher ci = createCipher(mode, params);
// process the first half of AAD data
ci.updateAAD(buf1);
// prepare ByteBuffer2 to test
ByteBuffer buf2 = ByteBuffer.allocate(AAD.length - AAD.length / 2);
buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2);
buf2.position(0);
buf2.limit(AAD.length - AAD.length / 2);
// process the rest of AAD data
ci.updateAAD(buf2);
// encrypt plain text
byte[] part11_1 = new byte[ci.getOutputSize(plainText.length)];
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
int len_11 = ci.update(plainText, 0, plainText.length - offset,
part11_1, 0);
byte[] part11_2 = ci.doFinal(plainText, plainText.length - offset,
offset);
byte[] outputText11 = new byte[len_11 + part11_2.length];
System.arraycopy(part11_1, 0, outputText11, 0, len_11);
System.arraycopy(part11_2, 0, outputText11, len_11, part11_2.length);
results.add(outputText11);
}
/*
* Execute multiple-part encryption/decryption combination #12:
* updateAAD(ByteBuffer src)
* updateAAD(ByteBuffer emptyByteBuffer)
* update(byte[], int, int, byte[], int)
* doFinal(byte[], int, int, byte[], int)
*/
private void combination_12(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
// prepare ByteBuffer to test
ByteBuffer buf = ByteBuffer.allocate(AAD.length);
buf.put(AAD);
buf.position(0);
buf.limit(AAD.length);
Cipher ci = createCipher(mode, params);
ci.updateAAD(buf);
// prepare an empty ByteBuffer
ByteBuffer emptyBuf = ByteBuffer.allocate(0);
emptyBuf.put(new byte[0]);
ci.updateAAD(emptyBuf);
byte[] part12_1 = new byte[ci.getOutputSize(plainText.length)];
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
int len12 = ci.update(plainText, 0, plainText.length - offset,
part12_1, 0);
int rest12 = ci.doFinal(plainText, plainText.length - offset, offset,
part12_1, len12);
byte[] outputText12 = new byte[len12 + rest12];
System.arraycopy(part12_1, 0, outputText12, 0, outputText12.length);
results.add(outputText12);
}
/*
* Execute multiple-part encryption/decryption combination #13:
* updateAAD(ByteBuffer src), where src is directly allocated
* update(ByteBuffer input, ByteBuffer out)
* doFinal(ByteBuffer input, ByteBuffer out)
*/
private void combination_13(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
// prepare ByteBuffer to test
ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);
buf.put(AAD);
buf.position(0);
buf.limit(AAD.length);
c.updateAAD(buf);
// prepare buffers to encrypt/decrypt
ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);
in.put(plainText);
in.position(0);
in.limit(plainText.length);
ByteBuffer output = ByteBuffer.allocateDirect(
c.getOutputSize(in.limit()));
output.position(0);
output.limit(c.getOutputSize(in.limit()));
// process input text
c.update(in, output);
c.doFinal(in, output);
int resultSize = output.position();
byte[] result13 = new byte[resultSize];
output.position(0);
output.limit(resultSize);
output.get(result13, 0, resultSize);
results.add(result13);
}
/*
* Execute multiple-part encryption/decryption combination #14:
* updateAAD(ByteBuffer src) updateAAD(ByteBuffer src),
* where src is directly allocated
* update(ByteBuffer input, ByteBuffer out)
* doFinal(ByteBuffer input, ByteBuffer out)
*/
private void combination_14(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
// prepare ByteBuffer to test
ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);
buf.put(AAD);
// process the first half of AAD data
buf.position(0);
buf.limit(AAD.length / 2);
c.updateAAD(buf);
// process the rest of AAD data
buf.limit(AAD.length);
c.updateAAD(buf);
// prepare buffers to encrypt/decrypt
ByteBuffer in = ByteBuffer.allocate(plainText.length);
in.put(plainText);
in.position(0);
in.limit(plainText.length);
ByteBuffer out = ByteBuffer.allocate(c.getOutputSize(in.limit()));
out.position(0);
out.limit(c.getOutputSize(in.limit()));
// process input text
c.update(in, out);
c.doFinal(in, out);
int resultSize = out.position();
byte[] result14 = new byte[resultSize];
out.position(0);
out.limit(resultSize);
out.get(result14, 0, resultSize);
results.add(result14);
}
/*
* Execute multiple-part encryption/decryption combination #15
* updateAAD(ByteBuffer src1), where src1 is directly allocated
* updateAAD(ByteBuffer src2), where src2 is directly allocated
* doFinal(ByteBuffer input, ByteBuffer out)
*/
private void combination_15(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
// prepare ByteBuffer1 to test
ByteBuffer buf1 = ByteBuffer.allocateDirect(AAD.length / 2);
buf1.put(AAD, 0, AAD.length / 2);
buf1.position(0);
buf1.limit(AAD.length / 2);
// process the first half of AAD data
c.updateAAD(buf1);
// prepare ByteBuffer2 to test
ByteBuffer buf2 = ByteBuffer.allocateDirect(
AAD.length - AAD.length / 2);
buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2);
buf2.position(0);
buf2.limit(AAD.length - AAD.length / 2);
// process the rest of AAD data
c.updateAAD(buf2);
// prepare buffers to encrypt/decrypt
ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);
in.put(plainText);
in.position(0);
in.limit(plainText.length);
ByteBuffer output = ByteBuffer.allocateDirect(
c.getOutputSize(in.limit()));
output.position(0);
output.limit(c.getOutputSize(in.limit()));
// process input text
c.doFinal(in, output);
int resultSize = output.position();
byte[] result15 = new byte[resultSize];
output.position(0);
output.limit(resultSize);
output.get(result15, 0, resultSize);
results.add(result15);
}
/*
* Execute multiple-part encryption/decryption combination #16:
* updateAAD(ByteBuffer src)
* updateAAD(ByteBuffer emptyByteBuffer)
* update(ByteBuffer input, ByteBuffer out)
* doFinal(EmptyByteBuffer, ByteBuffer out)
*/
private void combination_16(List<byte[]> results, int mode, byte[] AAD,
byte[] plainText, AlgorithmParameters params) throws Exception {
Cipher c = createCipher(mode, params);
// prepare ByteBuffer to test
ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);
buf.put(AAD);
buf.position(0);
buf.limit(AAD.length);
c.updateAAD(buf);
// prepare empty ByteBuffer
ByteBuffer emptyBuf = ByteBuffer.allocateDirect(0);
emptyBuf.put(new byte[0]);
c.updateAAD(emptyBuf);
// prepare buffers to encrypt/decrypt
ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);
in.put(plainText);
in.position(0);
in.limit(plainText.length);
ByteBuffer output = ByteBuffer.allocateDirect(
c.getOutputSize(in.limit()));
output.position(0);
output.limit(c.getOutputSize(in.limit()));
// process input text with an empty buffer
c.update(in, output);
ByteBuffer emptyBuf2 = ByteBuffer.allocate(0);
emptyBuf2.put(new byte[0]);
c.doFinal(emptyBuf2, output);
int resultSize = output.position();
byte[] result16 = new byte[resultSize];
output.position(0);
output.limit(resultSize);
output.get(result16, 0, resultSize);
results.add(result16);
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.GCMParameterSpec;
/*
* @test
* @bug 8048596
* @summary Check if GCMParameterSpec works as expected
*/
public class GCMParameterSpecTest {
private static final int[] IV_LENGTHS = { 96, 8, 1024 };
private static final int[] KEY_LENGTHS = { 128, 192, 256 };
private static final int[] DATA_LENGTHS = { 0, 128, 1024 };
private static final int[] AAD_LENGTHS = { 0, 128, 1024 };
private static final int[] TAG_LENGTHS = { 128, 120, 112, 104, 96 };
private static final int[] OFFSETS = { 0, 2, 5, 99 };
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private static final String TEMPLATE = "Test:\n tag = %d\n"
+ " IV length = %d\n data length = %d\n"
+ " AAD length = %d\n offset = %d\n keylength = %d\n";
private final byte[] IV;
private final byte[] IVO;
private final byte[] data;
private final byte[] AAD;
private final SecretKey key;
private final int tagLength;
private final int IVlength;
private final int offset;
/**
* Initialize IV, IV with offset, plain text, AAD and SecretKey
*
* @param keyLength length of a secret key
* @param tagLength tag length
* @param IVlength IV length
* @param offset offset in a buffer for IV
* @param textLength plain text length
* @param AADLength AAD length
*/
public GCMParameterSpecTest(int keyLength, int tagLength, int IVlength,
int offset, int textLength, int AADLength)
throws NoSuchAlgorithmException, NoSuchProviderException {
this.tagLength = tagLength; // save tag length
this.IVlength = IVlength; // save IV length
this.offset = offset; // save IV offset
// prepare IV
IV = Helper.generateBytes(IVlength);
// prepare IV with offset
IVO = new byte[this.IVlength + this.offset];
System.arraycopy(IV, 0, IVO, offset, this.IVlength);
// prepare data
data = Helper.generateBytes(textLength);
// prepare AAD
AAD = Helper.generateBytes(AADLength);
// init a secret key
KeyGenerator kg = KeyGenerator.getInstance("AES", "SunJCE");
kg.init(keyLength);
key = kg.generateKey();
}
/*
* Run the test for each key length, tag length, IV length, plain text
* length, AAD length and offset.
*/
public static void main(String[] args) throws Exception {
boolean success = true;
for (int k : KEY_LENGTHS) {
if (k > Cipher.getMaxAllowedKeyLength(TRANSFORMATION)) {
// skip this if this key length is larger than what's
// allowed in the jce jurisdiction policy files
continue;
}
for (int t : TAG_LENGTHS) {
for (int n : IV_LENGTHS) {
for (int p : DATA_LENGTHS) {
for (int a : AAD_LENGTHS) {
for (int o : OFFSETS) {
System.out.printf(TEMPLATE, t, n, p, a, o, k);
success &= new GCMParameterSpecTest(
k, t, n, o, p, a).doTest();
}
}
}
}
}
}
if (!success) {
throw new RuntimeException("At least one test case failed");
}
}
/*
* Run the test:
* - check if result of encryption of plain text is the same
* when parameters constructed with different GCMParameterSpec
* constructors are used
* - check if GCMParameterSpec.getTLen() is equal to actual tag length
* - check if ciphertext has the same length as plaintext
*/
private boolean doTest() throws Exception {
GCMParameterSpec spec1 = new GCMParameterSpec(tagLength, IV);
GCMParameterSpec spec2 = new GCMParameterSpec(tagLength, IVO, offset,
IVlength);
byte[] cipherText1 = getCipherTextBySpec(spec1);
if (cipherText1 == null) {
return false;
}
byte[] cipherText2 = getCipherTextBySpec(spec2);
if (cipherText2 == null) {
return false;
}
if (!Arrays.equals(cipherText1, cipherText2)) {
System.out.println("Cipher texts are different");
return false;
}
if (spec1.getTLen() != spec2.getTLen()) {
System.out.println("Tag lengths are not equal");
return false;
}
byte[] recoveredText1 = recoverCipherText(cipherText1, spec2);
if (recoveredText1 == null) {
return false;
}
byte[] recoveredText2 = recoverCipherText(cipherText2, spec1);
if (recoveredText2 == null) {
return false;
}
if (!Arrays.equals(recoveredText1, recoveredText2)) {
System.out.println("Recovered texts are different");
return false;
}
if (!Arrays.equals(recoveredText1, data)) {
System.out.println("Recovered and original texts are not equal");
return false;
}
return true;
}
/*
* Encrypt a plain text, and check if GCMParameterSpec.getIV()
* is equal to Cipher.getIV()
*/
private byte[] getCipherTextBySpec(GCMParameterSpec spec) throws Exception {
// init a cipher
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE, spec);
cipher.updateAAD(AAD);
byte[] cipherText = cipher.doFinal(data);
// check IVs
if (!Arrays.equals(cipher.getIV(), spec.getIV())) {
System.out.println("IV in parameters is incorrect");
return null;
}
if (spec.getTLen() != (cipherText.length - data.length) * 8) {
System.out.println("Tag length is incorrect");
return null;
}
return cipherText;
}
private byte[] recoverCipherText(byte[] cipherText, GCMParameterSpec spec)
throws Exception {
// init a cipher
Cipher cipher = createCipher(Cipher.DECRYPT_MODE, spec);
// check IVs
if (!Arrays.equals(cipher.getIV(), spec.getIV())) {
System.out.println("IV in parameters is incorrect");
return null;
}
cipher.updateAAD(AAD);
return cipher.doFinal(cipherText);
}
private Cipher createCipher(int mode, GCMParameterSpec spec)
throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION, "SunJCE");
cipher.init(mode, key, spec);
return cipher;
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class Helper {
public static byte[] generateBytes(int length) {
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = (byte) (i % 256);
}
return bytes;
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.AlgorithmParameters;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
/*
* @test
* @bug 8048596
* @summary Check if a key wrapper works properly with GCM mode
*/
public class KeyWrapper {
static final String AES = "AES";
static final String TRANSFORMATION = "AES/GCM/NoPadding";
static final String PROVIDER = "SunJCE";
static final int KEY_LENGTH = 128;
public static void main(String argv[]) throws Exception {
doTest(PROVIDER, TRANSFORMATION);
}
private static void doTest(String provider, String algo) throws Exception {
SecretKey key;
SecretKey keyToWrap;
// init a secret Key
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
kg.init(KEY_LENGTH);
key = kg.generateKey();
keyToWrap = kg.generateKey();
// initialization
Cipher cipher = Cipher.getInstance(algo, provider);
cipher.init(Cipher.WRAP_MODE, key);
AlgorithmParameters params = cipher.getParameters();
// wrap the key
byte[] keyWrapper = cipher.wrap(keyToWrap);
try {
// check if we can't wrap it again with the same key/IV
keyWrapper = cipher.wrap(keyToWrap);
throw new RuntimeException(
"FAILED: expected IllegalStateException hasn't "
+ "been thrown ");
} catch (IllegalStateException ise) {
System.out.println(ise.getMessage());
System.out.println("Expected exception");
}
// unwrap the key
cipher.init(Cipher.UNWRAP_MODE, key, params);
cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
// check if we can unwrap second time
Key unwrapKey = cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
if (!Arrays.equals(keyToWrap.getEncoded(), unwrapKey.getEncoded())) {
throw new RuntimeException(
"FAILED: original and unwrapped keys are not equal");
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/*
* @test
* @bug 8048596
* @summary Test CICO AEAD read/write/skip operations
*/
public class ReadWriteSkip {
static enum BufferType {
BYTE_ARRAY_BUFFERING, INT_BYTE_BUFFERING
}
static final int KEY_LENGTHS[] = {128, 192, 256};
static final int TXT_LENGTHS[] = {800, 0};
static final int AAD_LENGTHS[] = {0, 100};
static final int BLOCK = 50;
static final int SAVE = 45;
static final int DISCARD = BLOCK - SAVE;
static final String PROVIDER = "SunJCE";
static final String AES = "AES";
static final String GCM = "GCM";
static final String PADDING = "NoPadding";
static final String TRANSFORM = AES + "/" + GCM + "/" + PADDING;
final SecretKey key;
final byte[] plaintext;
final byte[] AAD;
final int textLength;;
final int keyLength;
Cipher encryptCipher;
Cipher decryptCipher;
CipherInputStream ciInput;
public static void main(String[] args) throws Exception {
boolean success = true;
for (int keyLength : KEY_LENGTHS) {
if (keyLength > Cipher.getMaxAllowedKeyLength(TRANSFORM)) {
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
continue;
}
for (int textLength : TXT_LENGTHS) {
for (int AADLength : AAD_LENGTHS) {
System.out.println("Key length = " + keyLength
+ ", text length = " + textLength
+ ", AAD length = " + AADLength);
try {
run(keyLength, textLength, AADLength);
System.out.println("Test case passed");
} catch (Exception e) {
System.out.println("Test case failed: " + e);
success = false;
}
}
}
}
if (!success) {
throw new RuntimeException("At least one test case failed");
}
System.out.println("Test passed");
}
ReadWriteSkip(int keyLength, int textLength, int AADLength)
throws Exception {
this.keyLength = keyLength;
this.textLength = textLength;
// init AAD
this.AAD = Helper.generateBytes(AADLength);
// init a secret Key
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
kg.init(this.keyLength);
this.key = kg.generateKey();
this.plaintext = Helper.generateBytes(textLength);
}
final void doTest(BufferType type) throws Exception {
// init ciphers
encryptCipher = createCipher(Cipher.ENCRYPT_MODE);
decryptCipher = createCipher(Cipher.DECRYPT_MODE);
// init cipher input stream
ciInput = new CipherInputStream(new ByteArrayInputStream(plaintext),
encryptCipher);
runTest(type);
}
void runTest(BufferType type) throws Exception {}
private Cipher createCipher(int mode) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance(TRANSFORM, PROVIDER);
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, key);
} else {
if (encryptCipher != null) {
cipher.init(Cipher.DECRYPT_MODE, key,
encryptCipher.getParameters());
} else {
throw new RuntimeException("Can't create a cipher");
}
}
cipher.updateAAD(AAD);
return cipher;
}
/*
* Run test cases
*/
static void run(int keyLength, int textLength, int AADLength)
throws Exception {
new ReadWriteTest(keyLength, textLength, AADLength)
.doTest(BufferType.BYTE_ARRAY_BUFFERING);
new ReadWriteTest(keyLength, textLength, AADLength)
.doTest(BufferType.INT_BYTE_BUFFERING);
new SkipTest(keyLength, textLength, AADLength)
.doTest(BufferType.BYTE_ARRAY_BUFFERING);
new SkipTest(keyLength, textLength, AADLength)
.doTest(BufferType.INT_BYTE_BUFFERING);
}
static void check(byte[] first, byte[] second) {
if (!Arrays.equals(first, second)) {
throw new RuntimeException("Arrays are not equal");
}
}
/*
* CICO AEAD read/write functional test.
*
* Check if encrypt/decrypt operations work correctly.
*
* Test scenario:
* - initializes plain text
* - for given AEAD algorithm instantiates encrypt and decrypt Ciphers
* - instantiates CipherInputStream with the encrypt Cipher
* - instantiates CipherOutputStream with the decrypt Cipher
* - performs reading from the CipherInputStream (encryption data)
* and writing to the CipherOutputStream (decryption). As a result,
* output of the CipherOutputStream should be equal
* with original plain text
* - check if the original plain text is equal to output
* of the CipherOutputStream
* - if it is equal the test passes, otherwise it fails
*/
static class ReadWriteTest extends ReadWriteSkip {
public ReadWriteTest(int keyLength, int textLength, int AADLength)
throws Exception {
super(keyLength, textLength, AADLength);
}
@Override
public void runTest(BufferType bufType) throws IOException,
GeneralSecurityException {
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
decryptCipher)) {
if (bufType == BufferType.BYTE_ARRAY_BUFFERING) {
doByteTest(ciOutput);
} else {
doIntTest(ciOutput);
}
}
check(plaintext, baOutput.toByteArray());
}
/*
* Implements byte array buffering type test case
*/
public void doByteTest(CipherOutputStream out) throws IOException {
byte[] buffer = Helper.generateBytes(textLength + 1);
int len = ciInput.read(buffer);
while (len != -1) {
out.write(buffer, 0, len);
len = ciInput.read(buffer);
}
}
/*
* Implements integer buffering type test case
*/
public void doIntTest(CipherOutputStream out) throws IOException {
int buffer = ciInput.read();
while (buffer != -1) {
out.write(buffer);
buffer = ciInput.read();
}
}
}
/*
* CICO AEAD SKIP functional test.
*
* Checks if the encrypt/decrypt operations work correctly
* when skip() method is used.
*
* Test scenario:
* - initializes a plain text
* - initializes ciphers
* - initializes cipher streams
* - split plain text to TEXT_SIZE/BLOCK blocks
* - read from CipherInputStream2 one block at time
* - the last DISCARD = BLOCK - SAVE bytes are skipping for each block
* - therefore, plain text data go through CipherInputStream1 (encrypting)
* and CipherInputStream2 (decrypting)
* - as a result, output should equal to the original text
* except DISCART byte for each block
* - check result buffers
*/
static class SkipTest extends ReadWriteSkip {
private final int numberOfBlocks;
private final byte[] outputText;
public SkipTest(int keyLength, int textLength, int AADLength)
throws Exception {
super(keyLength, textLength, AADLength);
numberOfBlocks = this.textLength / BLOCK;
outputText = new byte[numberOfBlocks * SAVE];
}
private void doByteTest(int blockNum, CipherInputStream cis)
throws IOException {
int index = blockNum * SAVE;
int len = cis.read(outputText, index, SAVE);
index += len;
int read = 0;
while (len != SAVE && read != -1) {
read = cis.read(outputText, index, SAVE - len);
len += read;
index += read;
}
}
private void doIntTest(int blockNum, CipherInputStream cis)
throws IOException {
int i = blockNum * SAVE;
for (int j = 0; j < SAVE && i < outputText.length; j++, i++) {
int b = cis.read();
if (b != -1) {
outputText[i] = (byte) b;
}
}
}
@Override
public void runTest(BufferType type) throws IOException,
NoSuchAlgorithmException {
try (CipherInputStream cis = new CipherInputStream(ciInput,
decryptCipher)) {
for (int i = 0; i < numberOfBlocks; i++) {
if (type == BufferType.BYTE_ARRAY_BUFFERING) {
doByteTest(i, cis);
} else {
doIntTest(i, cis);
}
if (cis.available() >= DISCARD) {
cis.skip(DISCARD);
} else {
for (int k = 0; k < DISCARD; k++) {
cis.read();
}
}
}
}
byte[] expectedText = new byte[numberOfBlocks * SAVE];
for (int m = 0; m < numberOfBlocks; m++) {
for (int n = 0; n < SAVE; n++) {
expectedText[m * SAVE + n] = plaintext[m * BLOCK + n];
}
}
check(expectedText, outputText);
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.Provider;
import java.security.Security;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.GCMParameterSpec;
/*
* @test
* @bug 8048596
* @summary Check if AEAD operations work correctly when buffers used
* for storing plain text and cipher text are overlapped or the same
*/
public class SameBuffer {
private static final String PROVIDER = "SunJCE";
private static final String AES = "AES";
private static final String GCM = "GCM";
private static final String PADDING = "NoPadding";
private static final int OFFSET = 2;
private static final int OFFSETS = 4;
private static final int KEY_LENGTHS[] = { 128, 192, 256 };
private static final int TEXT_LENGTHS[] = { 0, 1024 };
private static final int AAD_LENGTHS[] = { 0, 1024 };
private final Provider provider;
private final SecretKey key;
private final String transformation;
private final int textLength;
private final int AADLength;
/**
* Constructor of the test
*
* @param provider security provider
* @param keyStrength key length
* @param textLength length of data
* @param AADLength AAD length
*/
public SameBuffer(Provider provider, String algorithm, String mode,
String padding, int keyStrength, int textLength, int AADLength)
throws Exception {
// init a secret key
KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider);
kg.init(keyStrength);
key = kg.generateKey();
this.transformation = algorithm + "/" + mode + "/" + padding;
this.provider = provider;
this.textLength = textLength;
this.AADLength = AADLength;
}
public static void main(String[] args) throws Exception {
Provider p = Security.getProvider(PROVIDER);
for (int keyLength : KEY_LENGTHS) {
for (int textLength : TEXT_LENGTHS) {
for (int AADLength : AAD_LENGTHS) {
for (int i = 0; i < OFFSETS; i++) {
// try different offsets
int offset = i * OFFSET;
runTest(p, AES, GCM, PADDING, keyLength, textLength,
AADLength, offset);
}
}
}
}
}
/*
* Run single test case with given parameters
*/
static void runTest(Provider p, String algo, String mode,
String padding, int keyLength, int textLength, int AADLength,
int offset) throws Exception {
System.out.println("Testing " + keyLength + " key length; "
+ textLength + " text lenght; " + AADLength + " AAD length; "
+ offset + " offset");
if (keyLength > Cipher.getMaxAllowedKeyLength(algo)) {
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
return;
}
SameBuffer test = new SameBuffer(p, algo, mode,
padding, keyLength, textLength, AADLength);
/*
* There are four test cases:
* 1. AAD and text are placed in separated byte arrays
* 2. AAD and text are placed in the same byte array
* 3. AAD and text are placed in separated byte buffers
* 4. AAD and text are placed in the same byte buffer
*/
Cipher ci = test.createCipher(Cipher.ENCRYPT_MODE, null);
AlgorithmParameters params = ci.getParameters();
test.doTestWithSeparateArrays(offset, params);
test.doTestWithSameArrays(offset, params);
test.doTestWithSeparatedBuffer(offset, params);
test.doTestWithSameBuffer(offset, params);
}
/*
* Run the test in case when AAD and text are placed in separated byte
* arrays.
*/
private void doTestWithSeparateArrays(int offset,
AlgorithmParameters params) throws Exception {
// prepare buffers to test
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
int outputLength = c.getOutputSize(textLength);
int outputBufSize = outputLength + offset * 2;
byte[] inputText = Helper.generateBytes(outputBufSize);
byte[] AAD = Helper.generateBytes(AADLength);
// do the test
runGCMWithSeparateArray(Cipher.ENCRYPT_MODE, AAD, inputText, offset * 2,
textLength, offset, params);
int tagLength = c.getParameters()
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
runGCMWithSeparateArray(Cipher.DECRYPT_MODE, AAD, inputText, offset,
textLength + tagLength, offset, params);
}
/**
* Run the test in case when AAD and text are placed in the same byte
* array.
*/
private void doTestWithSameArrays(int offset, AlgorithmParameters params)
throws Exception {
// prepare buffers to test
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
int outputLength = c.getOutputSize(textLength);
int outputBufSize = AADLength + outputLength + offset * 2;
byte[] AAD_and_text = Helper.generateBytes(outputBufSize);
// do the test
runGCMWithSameArray(Cipher.ENCRYPT_MODE, AAD_and_text, AADLength + offset,
textLength, params);
int tagLength = c.getParameters()
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
runGCMWithSameArray(Cipher.DECRYPT_MODE, AAD_and_text, AADLength + offset,
textLength + tagLength, params);
}
/*
* Run the test in case when AAD and text are placed in separated ByteBuffer
*/
private void doTestWithSeparatedBuffer(int offset,
AlgorithmParameters params) throws Exception {
// prepare AAD byte buffers to test
byte[] AAD = Helper.generateBytes(AADLength);
ByteBuffer AAD_Buf = ByteBuffer.allocate(AADLength);
AAD_Buf.put(AAD, 0, AAD.length);
AAD_Buf.flip();
// prepare text byte buffer to encrypt/decrypt
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
int outputLength = c.getOutputSize(textLength);
int outputBufSize = outputLength + offset;
byte[] inputText = Helper.generateBytes(outputBufSize);
ByteBuffer plainTextBB = ByteBuffer.allocateDirect(inputText.length);
plainTextBB.put(inputText);
plainTextBB.position(offset);
plainTextBB.limit(offset + textLength);
// do test
runGCMWithSeparateBuffers(Cipher.ENCRYPT_MODE, AAD_Buf, plainTextBB, offset,
textLength, params);
int tagLength = c.getParameters()
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
plainTextBB.position(offset);
plainTextBB.limit(offset + textLength + tagLength);
runGCMWithSeparateBuffers(Cipher.DECRYPT_MODE, AAD_Buf, plainTextBB, offset,
textLength + tagLength, params);
}
/*
* Run the test in case when AAD and text are placed in the same ByteBuffer
*/
private void doTestWithSameBuffer(int offset, AlgorithmParameters params)
throws Exception {
// calculate output length
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
int outputLength = c.getOutputSize(textLength);
// prepare byte buffer contained AAD and plain text
int bufSize = AADLength + offset + outputLength;
byte[] AAD_and_Text = Helper.generateBytes(bufSize);
ByteBuffer AAD_and_Text_Buf = ByteBuffer.allocate(bufSize);
AAD_and_Text_Buf.put(AAD_and_Text, 0, AAD_and_Text.length);
// do test
runGCMWithSameBuffer(Cipher.ENCRYPT_MODE, AAD_and_Text_Buf, offset,
textLength, params);
int tagLength = c.getParameters()
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
AAD_and_Text_Buf.limit(AADLength + offset + textLength + tagLength);
runGCMWithSameBuffer(Cipher.DECRYPT_MODE, AAD_and_Text_Buf, offset,
textLength + tagLength, params);
}
/*
* Execute GCM encryption/decryption of a text placed in a byte array.
* AAD is placed in the separated byte array.
* Data are processed twice:
* - in a separately allocated buffer
* - in the text buffer
* Check if two results are equal
*/
private void runGCMWithSeparateArray(int mode, byte[] AAD, byte[] text,
int txtOffset, int lenght, int offset, AlgorithmParameters params)
throws Exception {
// first, generate the cipher text at an allocated buffer
Cipher cipher = createCipher(mode, params);
cipher.updateAAD(AAD);
byte[] outputText = cipher.doFinal(text, txtOffset, lenght);
// new cipher for encrypt operation
Cipher anotherCipher = createCipher(mode, params);
anotherCipher.updateAAD(AAD);
// next, generate cipher text again at the same buffer of plain text
int myoff = offset;
int off = anotherCipher.update(text, txtOffset, lenght, text, myoff);
anotherCipher.doFinal(text, myoff + off);
// check if two resutls are equal
if (!isEqual(text, myoff, outputText, 0, outputText.length)) {
throw new RuntimeException("Two results not equal, mode:" + mode);
}
}
/*
* Execute GCM encrption/decryption of a text. The AAD and text to process
* are placed in the same byte array. Data are processed twice:
* - in a separetly allocated buffer
* - in a buffer that shares content of the AAD_and_Text_BA
* Check if two results are equal
*/
private void runGCMWithSameArray(int mode, byte[] array, int txtOffset,
int length, AlgorithmParameters params) throws Exception {
// first, generate cipher text at an allocated buffer
Cipher cipher = createCipher(mode, params);
cipher.updateAAD(array, 0, AADLength);
byte[] outputText = cipher.doFinal(array, txtOffset, length);
// new cipher for encrypt operation
Cipher anotherCipher = createCipher(mode, params);
anotherCipher.updateAAD(array, 0, AADLength);
// next, generate cipher text again at the same buffer of plain text
int off = anotherCipher.update(array, txtOffset, length,
array, txtOffset);
anotherCipher.doFinal(array, txtOffset + off);
// check if two results are equal or not
if (!isEqual(array, txtOffset, outputText, 0,
outputText.length)) {
throw new RuntimeException(
"Two results are not equal, mode:" + mode);
}
}
/*
* Execute GCM encryption/decryption of textBB. AAD and text to process are
* placed in different byte buffers. Data are processed twice:
* - in a separately allocated buffer
* - in a buffer that shares content of the textBB
* Check if results are equal
*/
private void runGCMWithSeparateBuffers(int mode, ByteBuffer buffer,
ByteBuffer textBB, int txtOffset, int dataLength,
AlgorithmParameters params) throws Exception {
// take offset into account
textBB.position(txtOffset);
textBB.mark();
// first, generate the cipher text at an allocated buffer
Cipher cipher = createCipher(mode, params);
cipher.updateAAD(buffer);
buffer.flip();
ByteBuffer outBB = ByteBuffer.allocateDirect(
cipher.getOutputSize(dataLength));
cipher.doFinal(textBB, outBB);// get cipher text in outBB
outBB.flip();
// restore positions
textBB.reset();
// next, generate cipher text again in a buffer that shares content
Cipher anotherCipher = createCipher(mode, params);
anotherCipher.updateAAD(buffer);
buffer.flip();
ByteBuffer buf2 = textBB.duplicate(); // buf2 shares textBuf context
buf2.limit(txtOffset + anotherCipher.getOutputSize(dataLength));
int dataProcessed2 = anotherCipher.doFinal(textBB, buf2);
buf2.position(txtOffset);
buf2.limit(txtOffset + dataProcessed2);
if (!buf2.equals(outBB)) {
throw new RuntimeException(
"Two results are not equal, mode:" + mode);
}
}
/*
* Execute GCM encryption/decryption of text. AAD and a text to process are
* placed in the same buffer. Data is processed twice:
* - in a separately allocated buffer
* - in a buffer that shares content of the AAD_and_Text_BB
*/
private void runGCMWithSameBuffer(int mode, ByteBuffer buffer,
int txtOffset, int length, AlgorithmParameters params)
throws Exception {
// allocate a separate buffer
Cipher cipher = createCipher(mode, params);
ByteBuffer outBB = ByteBuffer.allocateDirect(
cipher.getOutputSize(length));
// first, generate the cipher text at an allocated buffer
buffer.flip();
buffer.limit(AADLength);
cipher.updateAAD(buffer);
buffer.limit(AADLength + txtOffset + length);
buffer.position(AADLength + txtOffset);
cipher.doFinal(buffer, outBB);
outBB.flip(); // cipher text in outBB
// next, generate cipherText again in the same buffer
Cipher anotherCipher = createCipher(mode, params);
buffer.flip();
buffer.limit(AADLength);
anotherCipher.updateAAD(buffer);
buffer.limit(AADLength + txtOffset + length);
buffer.position(AADLength + txtOffset);
// share textBuf context
ByteBuffer buf2 = buffer.duplicate();
buf2.limit(AADLength + txtOffset + anotherCipher.getOutputSize(length));
int dataProcessed2 = anotherCipher.doFinal(buffer, buf2);
buf2.position(AADLength + txtOffset);
buf2.limit(AADLength + txtOffset + dataProcessed2);
if (!buf2.equals(outBB)) {
throw new RuntimeException(
"Two results are not equal, mode:" + mode);
}
}
private boolean isEqual(byte[] A, int offsetA, byte[] B, int offsetB,
int bytesToCompare) {
System.out.println("offsetA: " + offsetA + " offsetB: " + offsetA
+ " bytesToCompare: " + bytesToCompare);
for (int i = 0; i < bytesToCompare; i++) {
int setA = i + offsetA;
int setB = i + offsetB;
if (setA > A.length - 1 || setB > B.length - 1
|| A[setA] != B[setB]) {
return false;
}
}
return true;
}
/*
* Creates a Cipher object for testing: for encryption it creates new Cipher
* based on previously saved parameters (it is prohibited to use the same
* Cipher twice for encription during GCM mode), or returns initiated
* existing Cipher.
*/
private Cipher createCipher(int mode, AlgorithmParameters params)
throws Exception {
Cipher cipher = Cipher.getInstance(transformation, provider);
if (Cipher.ENCRYPT_MODE == mode) {
// initiate it with the saved parameters
if (params != null) {
cipher.init(Cipher.ENCRYPT_MODE, key, params);
} else {
// intiate the cipher and save parameters
cipher.init(Cipher.ENCRYPT_MODE, key);
}
} else if (cipher != null) {
cipher.init(Cipher.DECRYPT_MODE, key, params);
} else {
throw new RuntimeException("Can't create cipher");
}
return cipher;
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.AlgorithmParameters;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
/*
* @test
* @bug 8048596
* @summary Check if the seal/unseal feature works properly in AEAD/GCM mode.
*/
public class SealedObjectTest {
private static final String AES = "AES";
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private static final String PROVIDER = "SunJCE";
private static final int KEY_LENGTH = 128;
public static void main(String[] args) throws Exception {
doTest();
}
/*
* Run the test:
* - init a cipher with AES/GCM/NoPadding transformation
* - seal an object
* - check if we can't seal it again with the same key/IV
* - unseal the object using different methods of SealedObject class
* - check if the original and sealed objects are equal
*/
static void doTest() throws Exception {
// init a secret Key
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
kg.init(KEY_LENGTH);
SecretKey key = kg.generateKey();
// initialization
Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
cipher.init(Cipher.ENCRYPT_MODE, key);
AlgorithmParameters params = cipher.getParameters();
// seal an object
SealedObject so = new SealedObject(key, cipher);
try {
// check if we can't seal it again with the same key/IV
so = new SealedObject(key, cipher);
throw new RuntimeException(
"FAILED: expected IllegalStateException hasn't "
+ "been thrown");
} catch (IllegalStateException ise) {
System.out.println("Expected exception when seal it again with"
+ " the same key/IV: " + ise);
}
// unseal the object using getObject(Cipher) and compare
cipher.init(Cipher.DECRYPT_MODE, key, params);
SecretKey unsealedKey = (SecretKey) so.getObject(cipher);
assertKeysSame(unsealedKey, key, "SealedObject.getObject(Cipher)");
// unseal the object using getObject(Key) and compare
unsealedKey = (SecretKey) so.getObject(key);
assertKeysSame(unsealedKey, key, "SealedObject.getObject(Key)");
// unseal the object using getObject(Key, String) and compare
unsealedKey = (SecretKey) so.getObject(key, PROVIDER);
assertKeysSame(unsealedKey, key,
"SealedObject.getObject(Key, String)");
}
/**
* Compare two SecretKey objects.
*
* @param key1 first key
* @param key2 second key
* @param meth method that was used for unsealing the SecretKey object
* @return true if key1 and key2 are the same, false otherwise.
*/
static void assertKeysSame(SecretKey key1, SecretKey key2, String meth) {
if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
throw new RuntimeException(
"FAILED: original and unsealed objects aren't the same for "
+ meth);
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
/*
* @test
* @bug 8048596
* @summary Check if wrong or empty AAD is rejected
*/
public class WrongAAD {
private static final String PROVIDER = "SunJCE";
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private static final int TEXT_SIZE = 800;
private static final int KEY_SIZE = 128;
private static final int AAD_SIZE = 128;
private final SecretKey key;
private final byte[] plainText;
private final Cipher encryptCipher;
public WrongAAD() throws Exception {
// init a secret key
KeyGenerator kg = KeyGenerator.getInstance("AES", PROVIDER);
kg.init(KEY_SIZE);
key = kg.generateKey();
// generate a plain text
plainText = Helper.generateBytes(TEXT_SIZE);
// init AADs
byte[] AAD = Helper.generateBytes(AAD_SIZE);
// init a cipher
encryptCipher = createCipher(Cipher.ENCRYPT_MODE, null);
encryptCipher.updateAAD(AAD);
}
public static void main(String[] args) throws Exception {
WrongAAD test = new WrongAAD();
test.decryptWithEmptyAAD();
test.decryptWithWrongAAD();
}
/*
* Attempt to decrypt a cipher text using Cipher object
* initialized without AAD used for encryption.
*/
private void decryptWithEmptyAAD() throws Exception {
System.out.println("decryptWithEmptyAAD() started");
// initialize it with empty AAD to get exception during decryption
Cipher decryptCipher = createCipher(Cipher.DECRYPT_MODE,
encryptCipher.getParameters());
try (ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
decryptCipher)) {
if (decrypt(ciOutput, baOutput)) {
throw new RuntimeException(
"Decryption has been perfomed successfully in"
+ " spite of the decrypt Cipher has NOT been"
+ " initialized with AAD");
}
}
System.out.println("decryptWithEmptyAAD() passed");
}
/*
* Attempt to decrypt the cipher text using Cipher object
* initialized with some fake AAD.
*/
private void decryptWithWrongAAD() throws Exception {
System.out.println("decrypt with wrong AAD");
// initialize it with wrong AAD to get an exception during decryption
Cipher decryptCipher = createCipher(Cipher.DECRYPT_MODE,
encryptCipher.getParameters());
byte[] someAAD = Helper.generateBytes(AAD_SIZE + 1);
decryptCipher.updateAAD(someAAD);
// init output stream
try (ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
decryptCipher);) {
if (decrypt(ciOutput, baOutput)) {
throw new RuntimeException(
"A decryption has been perfomed successfully in"
+ " spite of the decrypt Cipher has been"
+ " initialized with fake AAD");
}
}
System.out.println("Passed");
}
private boolean decrypt(CipherOutputStream ciOutput,
ByteArrayOutputStream baOutput) throws IOException {
try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
CipherInputStream ciInput = new CipherInputStream(baInput,
encryptCipher)) {
byte[] buffer = new byte[TEXT_SIZE];
int len = ciInput.read(buffer);
while (len != -1) {
ciOutput.write(buffer, 0, len);
len = ciInput.read(buffer);
}
ciOutput.flush();
byte[] recoveredText = baOutput.toByteArray();
System.out.println("recoveredText: " + new String(recoveredText));
/*
* See bug 8012900, AEADBadTagException is swalloed by CI/CO streams
* If recovered text is empty, than decryption failed
*/
if (recoveredText.length == 0) {
return false;
}
return Arrays.equals(plainText, recoveredText);
} catch (IllegalStateException e) {
System.out.println("Expected IllegalStateException: "
+ e.getMessage());
e.printStackTrace(System.out);
return false;
}
}
private Cipher createCipher(int mode, AlgorithmParameters params)
throws NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
if (params != null) {
cipher.init(mode, key, params);
} else {
cipher.init(mode, key);
}
return cipher;
}
}
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8048604
* @summary This test checks boundary conditions for testing
* ShortBufferException.
*/
import static java.lang.System.out;
import java.security.AlgorithmParameters;
import java.security.Provider;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class TextPKCS5PaddingTest {
/**
* Test plain text.
*/
private static final byte[] PLAIN_TEXT = {
0b10001, 0b10001, 0b10001, 0b10001,
0b10001, 0b10001, 0b11, 0b11
};
public static void main(String[] args) throws Exception {
Provider provider = Security.getProvider("SunJCE");
if (provider == null) {
throw new RuntimeException("SunJCE provider not exist");
}
// generate no-padding cipher with secret key
Cipher c = Cipher.getInstance("DES/CBC/NoPadding", provider);
KeyGenerator kgen = KeyGenerator.getInstance("DES", provider);
SecretKey skey = kgen.generateKey();
// this is the improperly padded plaintext
c.init(Cipher.ENCRYPT_MODE, skey);
// encrypt plaintext
byte[] cipher = c.doFinal(PLAIN_TEXT);
AlgorithmParameters params = c.getParameters();
// generate cipher that enforces PKCS5 padding
c = Cipher.getInstance("DES/CBC/PKCS5Padding", provider);
c.init(Cipher.DECRYPT_MODE, skey, params);
try {
c.doFinal(cipher);
throw new RuntimeException(
"ERROR: Expected BadPaddingException not thrown");
} catch (BadPaddingException expected) {
out.println("Expected BadPaddingException thrown");
}
}
}
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.String;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import static java.lang.System.out;
/*
* @test
* @bug 4686632 8048610
* @summary To verify Cipher.init will throw InvalidKeyException with
* Non-empty message when create SecretKeySpec with invalid DES key
* @author Kevin Liu
*/
public class Empty {
public static void main(String[] args) throws Exception {
try {
byte master[] = {
0, 1, 2, 3, 4
};
SecretKey key = new SecretKeySpec(master, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
throw new RuntimeException("InvalidKeyException not thrown");
} catch (java.security.InvalidKeyException ike) {
ike.printStackTrace();
if (ike.getMessage() != null) {
out.println("Status -- Passed");
} else {
throw new RuntimeException("Error message is not expected when"
+ " InvalidKeyException is thrown");
}
}
}
}
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8048819
* @summary This test stressful verifies the assertion of "The secret keys generated
* by all involved parties should be the same." for javax.crypto.KeyAgreement
* @run main SameDHKeyStressTest
*/
import java.security.AlgorithmParameterGenerator;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.spec.DHGenParameterSpec;
import javax.crypto.spec.DHParameterSpec;
public class SameDHKeyStressTest {
static final String[] ALGORITHMS = {"DH", "DiffieHellman", "dh", "diffieHELLMAN"};
static final String[] SECRET_ALOGRITHMS = {"DES", "DESede", "blowfish"};
static final int[] NUMBER_OF_PARTIES = {2, 3, 4};
static final String[] PA_NAMES = {"Alice", "Bob", "Carol", "David"};
public static void main(String args[]) {
int failedCnt = 0;
StringBuilder failedList = new StringBuilder("Failed List:");
for (String algorithm : ALGORITHMS) {
for (int numOfParties : NUMBER_OF_PARTIES) {
for (String secretAlgorithm : SECRET_ALOGRITHMS) {
if (!runTest(algorithm, numOfParties, secretAlgorithm)) {
failedCnt++;
failedList.append("\n Altorightm = ").append(algorithm).
append(" Number of Parties = ").append(numOfParties).
append(" Secret Algorithm = ").append(secretAlgorithm);
}
}
}
} //end of for loop
if (failedCnt > 0) {
System.out.println(failedList);
throw new RuntimeException("SameDHKeyStressTest Failed");
}
}
public static boolean runTest(String algo, int numParties, String secretAlgo) {
KAParticipant[] parties = new KAParticipant[numParties];
Key[] keyArchives = new Key[numParties];
try {
// generate AlogirhtmParameterSpec
AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH","SunJCE");
AlgorithmParameterSpec aps = new DHGenParameterSpec(512, 64);
apg.init(aps);
DHParameterSpec spec = apg.generateParameters().
getParameterSpec(DHParameterSpec.class);
//initilize all KeyAgreement participants
for (int i = 0; i < numParties; i++) {
parties[i] = new KAParticipant(PA_NAMES[i], algo);
parties[i].initialize(spec);
keyArchives[i] = parties[i].getPublicKey();
}
// Do all phases in the KeyAgreement for all participants
Key[] keyBuffer = new Key[numParties];
boolean lastPhase = false;
for (int j = 0; j < numParties - 1; j++) {
if (j == numParties - 2) {
lastPhase = true;
}
for (int k = 0; k < numParties; k++) {
if (k == numParties - 1) {
keyBuffer[k] = parties[k].doPhase(keyArchives[0], lastPhase);
} else {
keyBuffer[k] = parties[k].doPhase(keyArchives[k + 1], lastPhase);
}
}
System.arraycopy(keyBuffer, 0, keyArchives, 0, numParties);
}
//Comparison: The secret keys generated by all involved parties should be the same
SecretKey[] sKeys = new SecretKey[numParties];
for (int n = 0; n < numParties; n++) {
sKeys[n] = parties[n].generateSecret(secretAlgo);
}
for (int q = 0; q < numParties - 1; q++) {
if (!Arrays.equals(sKeys[q].getEncoded(), sKeys[q + 1].getEncoded())) {
return false;
}
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
}
class KAParticipant {
private String name = null;
private String algorithm = null;
private KeyPairGenerator keyGen = null;
private KeyPair keys = null;
private KeyAgreement ka = null;
public KAParticipant(String pName, String algo) throws NoSuchAlgorithmException, NoSuchProviderException {
name = pName;
algorithm = algo;
keyGen = KeyPairGenerator.getInstance(algo,"SunJCE");
ka = KeyAgreement.getInstance(algo,"SunJCE");
}
public void initialize(AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException, InvalidKeyException {
keyGen.initialize(spec);
keys = keyGen.generateKeyPair();
ka.init(keys.getPrivate());
}
public Key doPhase(Key key, boolean lastPhase) throws InvalidKeyException {
return ka.doPhase(key, lastPhase);
}
public Key getPublicKey() {
return keys.getPublic();
}
public byte[] generateSecret() {
return ka.generateSecret();
}
public SecretKey generateSecret(String algo) throws java.lang.IllegalStateException,
java.security.NoSuchAlgorithmException,
java.security.InvalidKeyException {
return ka.generateSecret(algo);
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static javax.crypto.Cipher.ENCRYPT_MODE;
import static javax.crypto.Cipher.getMaxAllowedKeyLength;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
/*
* @test
* @bug 8075286
* @summary Test the AES algorithm OIDs in JDK.
* OID and Algorithm transformation string should match.
* Both could be able to be used to generate the algorithm instance.
* @run main TestAESOids
*/
public class TestAESOids {
private static final String PROVIDER_NAME = "SunJCE";
private static final byte[] INPUT = "1234567890123456".getBytes();
private static final List<DataTuple> DATA = Arrays.asList(
new DataTuple("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding",
128, "ECB"),
new DataTuple("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding",
128, "CBC"),
new DataTuple("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding",
128, "OFB"),
new DataTuple("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding",
128, "CFB"),
new DataTuple("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding",
192, "ECB"),
new DataTuple("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding",
192, "CBC"),
new DataTuple("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding",
192, "OFB"),
new DataTuple("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding",
192, "CFB"),
new DataTuple("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding",
256, "ECB"),
new DataTuple("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding",
256, "CBC"),
new DataTuple("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding",
256, "OFB"),
new DataTuple("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding",
256, "CFB"));
public static void main(String[] args) throws Exception {
for (DataTuple dataTuple : DATA) {
int maxAllowedKeyLength =
getMaxAllowedKeyLength(dataTuple.algorithm);
boolean supportedKeyLength =
maxAllowedKeyLength >= dataTuple.keyLength;
try {
runTest(dataTuple, supportedKeyLength);
System.out.println("passed");
} catch (InvalidKeyException ike) {
if (supportedKeyLength) {
throw new RuntimeException(String.format(
"The key length %d is supported, but test failed.",
dataTuple.keyLength), ike);
} else {
System.out.printf(
"Catch expected InvalidKeyException due "
+ "to the key length %d is greater than "
+ "max supported key length %d%n",
dataTuple.keyLength, maxAllowedKeyLength);
}
}
}
}
private static void runTest(DataTuple dataTuple,
boolean supportedKeyLength) throws NoSuchAlgorithmException,
NoSuchProviderException, NoSuchPaddingException,
InvalidKeyException, ShortBufferException,
IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
Cipher algorithmCipher = Cipher.getInstance(dataTuple.algorithm,
PROVIDER_NAME);
Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME);
if (algorithmCipher == null) {
throw new RuntimeException(
String.format("Test failed: algorithm string %s getInstance"
+ " failed.%n", dataTuple.algorithm));
}
if (oidCipher == null) {
throw new RuntimeException(
String.format("Test failed: OID %s getInstance failed.%n",
dataTuple.oid));
}
if (!algorithmCipher.getAlgorithm().equals(dataTuple.algorithm)) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance "
+ "doesn't generate expected algorithm.%n",
dataTuple.algorithm));
}
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(dataTuple.keyLength);
SecretKey key = kg.generateKey();
// encrypt
algorithmCipher.init(ENCRYPT_MODE, key);
if (!supportedKeyLength) {
throw new RuntimeException(String.format(
"The key length %d is not supported, so the initialization "
+ "of algorithmCipher should fail.%n",
dataTuple.keyLength));
}
byte[] cipherText = new byte[algorithmCipher.getOutputSize(INPUT.length)];
int offset = algorithmCipher.update(INPUT, 0, INPUT.length,
cipherText, 0);
algorithmCipher.doFinal(cipherText, offset);
AlgorithmParameterSpec aps = null;
if (!dataTuple.mode.equalsIgnoreCase("ECB")) {
aps = new IvParameterSpec(algorithmCipher.getIV());
}
oidCipher.init(Cipher.DECRYPT_MODE, key, aps);
if (!supportedKeyLength) {
throw new RuntimeException(String.format(
"The key length %d is not supported, so the "
+ "initialization of oidCipher should fail.%n",
dataTuple.keyLength));
}
byte[] recoveredText = new byte[oidCipher.getOutputSize(cipherText.length)];
oidCipher.doFinal(cipherText, 0, cipherText.length, recoveredText);
// Comparison
if (!Arrays.equals(INPUT, recoveredText)) {
throw new RuntimeException(
"Decrypted data is not the same as the original text");
}
}
private static class DataTuple {
private final String oid;
private final String algorithm;
private final int keyLength;
private final String mode;
private DataTuple(String oid, String algorithm, int keyLength,
String mode) {
this.oid = oid;
this.algorithm = algorithm;
this.keyLength = keyLength;
this.mode = mode;
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static javax.crypto.Cipher.getMaxAllowedKeyLength;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
/*
* @test
* @bug 8075286
* @summary Test the AESWrap algorithm OIDs in JDK.
* OID and Algorithm transformation string should match.
* Both could be able to be used to generate the algorithm instance.
* @run main TestAESWrapOids
*/
public class TestAESWrapOids {
private static final String PROVIDER_NAME = "SunJCE";
private static final List<DataTuple> DATA = Arrays.asList(
new DataTuple("2.16.840.1.101.3.4.1.5", "AESWrap_128", 128),
new DataTuple("2.16.840.1.101.3.4.1.25", "AESWrap_192", 192),
new DataTuple("2.16.840.1.101.3.4.1.45", "AESWrap_256", 256));
public static void main(String[] args) throws Exception {
for (DataTuple dataTuple : DATA) {
int maxAllowedKeyLength = getMaxAllowedKeyLength(
dataTuple.algorithm);
boolean supportedKeyLength =
maxAllowedKeyLength >= dataTuple.keyLength;
try {
runTest(dataTuple, supportedKeyLength);
System.out.println("passed");
} catch (InvalidKeyException ike) {
if (supportedKeyLength) {
throw new RuntimeException(String.format(
"The key length %d is supported, but test failed.",
dataTuple.keyLength), ike);
} else {
System.out.printf(
"Catch expected InvalidKeyException "
+ "due to the key length %d is greater "
+ "than max supported key length %d%n",
dataTuple.keyLength, maxAllowedKeyLength);
}
}
}
}
private static void runTest(DataTuple dataTuple, boolean supportedKeyLength)
throws NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException {
Cipher algorithmCipher = Cipher.getInstance(
dataTuple.algorithm, PROVIDER_NAME);
Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME);
if (algorithmCipher == null) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance failed.%n",
dataTuple.algorithm));
}
if (oidCipher == null) {
throw new RuntimeException(
String.format("Test failed: OID %s getInstance failed.%n",
dataTuple.oid));
}
if (!algorithmCipher.getAlgorithm().equals(
dataTuple.algorithm)) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance "
+ "doesn't generate expected algorithm.%n",
dataTuple.oid));
}
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(dataTuple.keyLength);
SecretKey key = kg.generateKey();
// Wrap the key
algorithmCipher.init(Cipher.WRAP_MODE, key);
if (!supportedKeyLength) {
throw new RuntimeException(String.format(
"The key length %d is not supported, so the initialization"
+ " of algorithmCipher should fail.%n",
dataTuple.keyLength));
}
// Unwrap the key
oidCipher.init(Cipher.UNWRAP_MODE, key);
if (!supportedKeyLength) {
throw new RuntimeException(String.format(
"The key length %d is not supported, so the initialization"
+ " of oidCipher should fail.%n",
dataTuple.keyLength));
}
byte[] keyWrapper = algorithmCipher.wrap(key);
Key unwrappedKey = oidCipher.unwrap(keyWrapper, "AES",
Cipher.SECRET_KEY);
// Comparison
if (!Arrays.equals(key.getEncoded(), unwrappedKey.getEncoded())) {
throw new RuntimeException("Key comparison failed");
}
}
private static class DataTuple {
private final String oid;
private final String algorithm;
private final int keyLength;
private DataTuple(String oid, String algorithm, int keyLength) {
this.oid = oid;
this.algorithm = algorithm;
this.keyLength = keyLength;
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import java.util.List;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
/*
* @test
* @bug 8075286
* @summary Test the HmacSHA algorithm OIDs in JDK.
* OID and Algorithm transformation string should match.
* Both could be able to be used to generate the algorithm instance.
* @run main TestHmacSHAOids
*/
public class TestHmacSHAOids {
private static final String PROVIDER_NAME = "SunJCE";
private static final byte[] INPUT = "1234567890".getBytes();
private static final List<DataTuple> DATA = Arrays.asList(
new DataTuple("1.2.840.113549.2.7", "HmacSHA1"),
new DataTuple("1.2.840.113549.2.8", "HmacSHA224"),
new DataTuple("1.2.840.113549.2.9", "HmacSHA256"),
new DataTuple("1.2.840.113549.2.10", "HmacSHA384"),
new DataTuple("1.2.840.113549.2.11", "HmacSHA512"));
public static void main(String[] args) throws Exception {
for (DataTuple dataTuple : DATA) {
runTest(dataTuple);
System.out.println("passed");
}
System.out.println("All tests passed");
}
private static void runTest(DataTuple dataTuple)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException {
Mac mcAlgorithm = Mac.getInstance(dataTuple.algorithm,
PROVIDER_NAME);
Mac mcOid = Mac.getInstance(dataTuple.oid, PROVIDER_NAME);
if (mcAlgorithm == null) {
throw new RuntimeException(String.format(
"Test failed: Mac using algorithm "
+ "string %s getInstance failed.%n",
dataTuple.algorithm));
}
if (mcOid == null) {
throw new RuntimeException(String.format(
"Test failed: Mac using OID %s getInstance failed.%n",
dataTuple.oid));
}
if (!mcAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) {
throw new RuntimeException(String.format(
"Test failed: Mac using algorithm string %s getInstance "
+ "doesn't generate expected algorithm.%n",
dataTuple.algorithm));
}
KeyGenerator kg = KeyGenerator.getInstance(dataTuple.algorithm,
PROVIDER_NAME);
SecretKey key = kg.generateKey();
mcAlgorithm.init(key);
mcAlgorithm.update(INPUT);
mcOid.init(key);
mcOid.update(INPUT);
// Comparison
if (!Arrays.equals(mcAlgorithm.doFinal(), mcOid.doFinal())) {
throw new RuntimeException("Digest comparison failed: "
+ "the two MACs are not the same");
}
}
private static class DataTuple {
private final String oid;
private final String algorithm;
private DataTuple(String oid, String algorithm) {
this.oid = oid;
this.algorithm = algorithm;
}
}
}
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
/* @test /* @test
* @summary test access checking by java.lang.invoke.MethodHandles.Lookup * @summary test access checking by java.lang.invoke.MethodHandles.Lookup
* @library ../../../.. * @compile AccessControlTest.java AccessControlTest_subpkg/Acquaintance_remote.java
* @build test.java.lang.invoke.AccessControlTest
* @build test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote
* @run testng/othervm test.java.lang.invoke.AccessControlTest * @run testng/othervm test.java.lang.invoke.AccessControlTest
*/ */
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8048052
* @summary Test a series of methods which requires "setFactory" runtime permission
* @run main SetFactoryPermission success
* @run main/othervm/policy=policy.fail SetFactoryPermission fail
* @run main/othervm/policy=policy.success SetFactoryPermission success
*/
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.rmi.server.RMISocketFactory;
import java.security.AccessControlException;
public class SetFactoryPermission {
static boolean success = false;
interface Runner {
public void run() throws Exception;
}
public static void main (String[] args) throws Exception {
if (args.length > 0) {
success = System.getSecurityManager() == null || args[0].equals("success");
}
doTest(()->{
System.out.println("Verify URLConnection.setContentHandlerFactor()");
URLConnection.setContentHandlerFactory(null);
});
doTest(()->{
System.out.println("Verify URL.setURLStreamHandlerFactory()");
URL.setURLStreamHandlerFactory(null);
});
doTest(()->{
System.out.println("Verify ServerSocket.setSocketFactory()");
ServerSocket.setSocketFactory(null);
});
doTest(()->{
System.out.println("Verify Socket.setSocketImplFactory()");
Socket.setSocketImplFactory(null);
});
doTest(()->{
System.out.println("Verify RMISocketFactory.setSocketFactory()");
RMISocketFactory.setSocketFactory(null);
});
}
static void doTest(Runner func) throws Exception {
try {
func.run();
if (!success) {
throw new RuntimeException("AccessControlException is not thrown. Test failed");
}
} catch (SecurityException e) {
if (success) {
e.printStackTrace();
throw new RuntimeException("AccessControlException is thrown unexpectedly. Test failed");
}
}
}
}
grant {
permission java.lang.RuntimePermission "setFactory";
};
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.KeyStore;
import java.security.Security;
import static java.lang.System.out;
/**
* @test
* @bug 8048830
* @summary Set up keystore.type secure property and check that
* KeyStore.getDefaultType() value is related to property value. Expect a full
* match the value 'keystore.type' and the value of the
* KeyStore.getDefaultType()
* @run main/othervm CheckDefaults
*/
public class CheckDefaults {
private static final String DEFAULT_KEY_STORE_TYPE = "jks";
private static final String[] KEY_STORE_TYPES = {"jks", "pkcs12", "jceks",
"Unregistered_type_of_KS"};
private void runTest(String[] args) {
if (!KeyStore.getDefaultType().
equalsIgnoreCase(DEFAULT_KEY_STORE_TYPE)) {
throw new RuntimeException(String.format("Default keystore type "
+ "Expected '%s' . Actual: '%s' ", DEFAULT_KEY_STORE_TYPE,
KeyStore.getDefaultType()));
}
for (String ksDefaultType : KEY_STORE_TYPES) {
Security.setProperty("keystore.type", ksDefaultType);
if (!KeyStore.getDefaultType().equals(ksDefaultType)) {
throw new RuntimeException(String.format(
"Keystore default type value: '%s' cannot be set up via"
+ " keystore.type "
+ "security property, Actual: '%s'",
ksDefaultType, KeyStore.getDefaultType()));
}
}
out.println("Test Passed");
}
public static void main(String[] args) {
CheckDefaults checkDefaultsTest = new CheckDefaults();
checkDefaultsTest.runTest(args);
}
}
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.System.out;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.util.Arrays;
import java.util.Base64;
import java.util.Enumeration;
/*
* @test
* @bug 8048619
* @author Bill Situ
* @summary Test converting keystore from jceks to P12 and from P12 to other
* (jceks,jks). including following test cases:
* Read jceks key store and convert to the p12 key store, then compare entries
* in the two key stores.
* Read p12 key store and convert to the jceks key store, then compare entries
* in the two key stores.
* Read p12 key store (contains only private key and a self-signed certificate)
* and convert to the jceks key store, then compare entries of two key stores.
* Read p12 key store (contains 2 entries) and convert to the jceks key store,
* then compare entries in the two key stores.
* Read p12 key store (entry password and key store password are different) and
* convert to the jceks key store, then compare entries in the two key stores.
* Read p12 key store and convert to the jks key store, then compare entries
* in the two key stores.
* Read p12 key store (contains only private key and a self-signed certificate)
* and convert to the jks key store, then compare entries in the two key stores.
* Read p12 key store (contains 2 entries) and convert to the jks key store,
* then compare entries in the two key stores.
* Read p12 key store (entry password and key store password are different) and
* convert to the jks key store, then compare entries in the two key stores.
*/
public class ConvertP12Test {
private static final String SUN_JSSE = "SunJSSE";
private static final String SUN_JCE = "SunJCE";
private static final String SUN = "SUN";
private static final String PKCS12 = "pkcs12";
private static final String JCE_KS = "JceKS";
private static final String JKS = "JKS";
public static void main(String args[]) throws Exception {
ConvertP12Test jstest = new ConvertP12Test();
jstest.driver("JceksToP12", "keystoreCA.jceks.data", JCE_KS, SUN_JCE,
"storepass", "keypass", PKCS12, SUN_JSSE);
jstest.driver("P12ToJceks_Chain", "ie_jceks_chain.pfx.data", PKCS12,
SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE);
jstest.driver("P12ToJceks_SelfSigned", "jdk_jceks_selfsigned.p12.data",
PKCS12, SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE);
jstest.driver("P12ToJceks_TwoEntry", "jdk_jceks_twoentry.p12.data",
PKCS12, SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE);
jstest.driver("P12ToJceks_TwoPass", "jdk_jceks_twopass.p12.data",
PKCS12, SUN_JSSE, "storepass", "keypass", JCE_KS, SUN_JCE);
jstest.driver("P12ToJks_Chain", "ie_jks_chain.pfx.data", PKCS12,
SUN_JSSE, "pass", "pass", JKS, SUN);
jstest.driver("P12ToJks_SelfSigned", "jdk_jks_selfsigned.p12.data",
PKCS12, SUN_JSSE, "pass", "pass", JKS, SUN);
jstest.driver("P12ToJks_TwoEntry", "jdk_jks_twoentry.p12.data", PKCS12,
SUN_JSSE, "pass", "pass", JKS, SUN);
jstest.driver("P12ToJks_TwoPass", "jdk_jks_twopass.p12.data", PKCS12,
SUN_JSSE, "storepass", "keypass", JKS, SUN);
}
private void driver(String testCase, String inKeyStore,
String inKeyStoreType, String inKeyStoreTypePrv,
String inStorePass, String inKeyPass, String outKeyStoreType,
String outKeyStorePrv) throws Exception {
String outStorePass = "pass";
String outKeyPass = "pass";
KeyStore inputKeyStore, outputKeyStore;
out.println("Testing " + testCase);
String keystorePath = System.getProperty("test.src", ".")
+ File.separator + "certs" + File.separator + "convertP12";
out.println("Output KeyStore : " + inKeyStore + ".out");
String outKeyStoreName = inKeyStore + ".out";
try (FileOutputStream fout = new FileOutputStream(outKeyStoreName);) {
inputKeyStore = KeyStore.getInstance(inKeyStoreType,
inKeyStoreTypePrv);
// KeyStore have encoded by Base64.getMimeEncoder().encode(),need
// decode first.
byte[] input = Files.readAllBytes(Paths.get(keystorePath,
inKeyStore));
ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64
.getMimeDecoder().decode(input));
out.println("Input KeyStore : " + inKeyStore);
inputKeyStore.load(arrayIn, inStorePass.toCharArray());
outputKeyStore = KeyStore.getInstance(outKeyStoreType,
outKeyStorePrv);
outputKeyStore.load(null, null);
run(inputKeyStore, outputKeyStore, inKeyPass, outKeyPass);
outputKeyStore.store(fout, outStorePass.toCharArray());
// for P12ToJks_TwoEntry test case will test includes each other,
// others just test compareKeystore
if (testCase.contains("TwoEntry")) {
compareKeyStore(inputKeyStore, outputKeyStore, inKeyPass,
outKeyPass, 2);
compareKeyStore(outputKeyStore, inputKeyStore, outKeyPass,
inKeyPass, 2);
} else {
compareKeyStore(inputKeyStore, outputKeyStore, inKeyPass,
outKeyPass, 1);
}
out.println("Test " + testCase + " STATUS: Pass!!");
} catch (Exception ex) {
out.println("Test " + testCase + " STATUS: failed with exception: "
+ ex.getMessage());
throw ex;
}
}
private void run(KeyStore inputKeyStore, KeyStore outputKeyStore,
String inKeyPass, String outKeyPass) throws Exception {
Enumeration<String> e = inputKeyStore.aliases();
String alias;
while (e.hasMoreElements()) {
alias = e.nextElement();
Certificate[] certs = inputKeyStore.getCertificateChain(alias);
boolean isCertEntry = inputKeyStore.isCertificateEntry(alias);
// Test KeyStore only contain key pair entries.
if (isCertEntry == true) {
throw new RuntimeException(
"inputKeystore should not be certEntry because test"
+ " keystore only contain key pair entries"
+ " for alias:" + alias);
}
boolean isKeyEntry = inputKeyStore.isKeyEntry(alias);
Key key = null;
if (isKeyEntry) {
key = inputKeyStore.getKey(alias, inKeyPass.toCharArray());
} else {
throw new RuntimeException("Entry type unknown for alias:"
+ alias);
}
outputKeyStore.setKeyEntry(alias, key, outKeyPass.toCharArray(),
certs);
}
}
private void compareKeyStore(KeyStore a, KeyStore b, String inKeyPass,
String outKeyPass, int keyStoreSize) throws Exception {
if (a.size() != keyStoreSize || b.size() != keyStoreSize) {
throw new RuntimeException("size not match or size not equal to "
+ keyStoreSize);
}
Enumeration<String> eA = a.aliases();
while (eA.hasMoreElements()) {
String aliasA = eA.nextElement();
if (!b.containsAlias(aliasA)) {
throw new RuntimeException("alias not match for alias:"
+ aliasA);
}
compareKeyEntry(a, b, inKeyPass, outKeyPass, aliasA);
}
}
private void compareKeyEntry(KeyStore a, KeyStore b, String aPass,
String bPass, String alias) throws KeyStoreException,
UnrecoverableKeyException, NoSuchAlgorithmException {
Certificate[] certsA = a.getCertificateChain(alias);
Certificate[] certsB = b.getCertificateChain(alias);
if (!Arrays.equals(certsA, certsB)) {
throw new RuntimeException("Certs don't match for alias:" + alias);
}
Key keyA = a.getKey(alias, aPass.toCharArray());
Key keyB = b.getKey(alias, bPass.toCharArray());
if (!keyA.equals(keyB)) {
throw new RuntimeException(
"Key don't match for alias:" + alias);
}
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import static java.lang.System.err;
import java.security.*;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.crypto.spec.PBEParameterSpec;
import jdk.testlibrary.RandomFactory;
import static java.lang.System.out;
import java.util.Arrays;
/**
* @test
* @bug 8048830
* @summary Test for feature 'support stronger entry protection'. An entry is
* stored to keystore with different PasswordProtection objects which are
* specified by different PBE algorithms (use -Dseed=X to set PRNG seed)
* @library /lib/testlibrary ../
*/
public class EntryProtectionTest {
private static final char[] PASSWORD = "passwd".toCharArray();
private static final String ALIAS = "testkey";
private static final byte[] SALT = new byte[8];
private static final int ITERATION_COUNT = 1024;
private static final List<KeyStore.PasswordProtection> PASSWORD_PROTECTION
= new ArrayList<>();
private static final String KEYSTORE_PATH = System.getProperty(
"test.classes" + File.separator + "ks.pkcs12",
"." + File.separator + "ks.pkcs12");
private void runTest() throws Exception {
KeyStore ksIn = Utils.loadKeyStore(KEYSTORE_PATH,
Utils.KeyStoreType.pkcs12, PASSWORD);
KeyStore ksTest = KeyStore
.getInstance(Utils.KeyStoreType.pkcs12.name());
ksTest.load(null);
Certificate cert = ksIn.getCertificate(ALIAS);
Key key = ksIn.getKey(ALIAS, PASSWORD);
KeyStore.Entry keyStoreEntry = new KeyStore.PrivateKeyEntry(
(PrivateKey) key, new Certificate[]{cert});
for (KeyStore.PasswordProtection passwordAlgorithm :
PASSWORD_PROTECTION) {
out.println("Try to use: " +
passwordAlgorithm.getProtectionAlgorithm());
ksTest.setEntry(ALIAS, keyStoreEntry, passwordAlgorithm);
KeyStore.Entry entryRead = ksTest.getEntry(ALIAS,
new KeyStore.PasswordProtection(PASSWORD));
if (!isPrivateKeyEntriesEqual((KeyStore.PrivateKeyEntry)
keyStoreEntry, (KeyStore.PrivateKeyEntry)entryRead)) {
err.println("Original entry in KeyStore: " + keyStoreEntry);
err.println("Enc/Dec entry : " + entryRead);
throw new RuntimeException(
String.format(
"Decrypted & original enities do "
+ "not match. Algo: %s, Actual: %s, "
+ "Expected: %s",
passwordAlgorithm.getProtectionAlgorithm(),
entryRead, keyStoreEntry));
}
ksTest.deleteEntry(ALIAS);
}
out.println("Test Passed");
}
public static void main(String args[]) throws Exception {
EntryProtectionTest entryProtectionTest = new EntryProtectionTest();
entryProtectionTest.setUp();
entryProtectionTest.runTest();
}
private void setUp() {
out.println("Using KEYSTORE_PATH:"+KEYSTORE_PATH);
Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS);
Random rand = RandomFactory.getRandom();
rand.nextBytes(SALT);
out.print("Salt: ");
for (byte b : SALT) {
out.format("%02X ", b);
}
out.println("");
PASSWORD_PROTECTION
.add(new KeyStore.PasswordProtection(PASSWORD,
"PBEWithMD5AndDES", new PBEParameterSpec(SALT,
ITERATION_COUNT)));
PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD,
"PBEWithSHA1AndDESede", null));
PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD,
"PBEWithSHA1AndRC2_40", null));
PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD,
"PBEWithSHA1AndRC2_128", null));
PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD,
"PBEWithSHA1AndRC4_40", null));
PASSWORD_PROTECTION.add(new KeyStore.PasswordProtection(PASSWORD,
"PBEWithSHA1AndRC4_128", null));
}
/**
* Checks whether given two KeyStore.PrivateKeyEntry parameters are equal
* The KeyStore.PrivateKeyEntry fields like {privateKey, certificateChain[]}
* are checked for equality and another field Set<attributes> is not checked
* as default implementation adds few PKCS12 attributes during read
* operation
* @param first
* parameter is of type KeyStore.PrivateKeyEntry
* @param second
* parameter is of type KeyStore.PrivateKeyEntry
* @return boolean
* true when both the KeyStore.PrivateKeyEntry fields are equal
*/
boolean isPrivateKeyEntriesEqual(KeyStore.PrivateKeyEntry first,
KeyStore.PrivateKeyEntry second) {
//compare privateKey
if (!Arrays.equals(first.getPrivateKey().getEncoded(),
second.getPrivateKey().getEncoded())) {
err.println("Mismatch found in privateKey!");
return false;
}
//compare certificateChain[]
if (!Arrays.equals(first.getCertificateChain(),
second.getCertificateChain())) {
err.println("Mismatch found in certificate chain!");
return false;
}
return true;
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Base64;
import jdk.testlibrary.OutputAnalyzer;
import static java.lang.System.out;
import java.nio.file.Paths;
import java.util.List;
/**
* @test
* @bug 8048830
* @summary Test for PKCS12 keystore list , export commands. Refer README for
* keystore files information
* @library /lib/testlibrary ../
* @run main KeytoolReaderP12Test
*/
public class KeytoolReaderP12Test {
private static final String WORKING_DIRECTORY = System.getProperty(
"test.classes", "."+ File.separator);
private static final String KS_PASSWD = "storepass";
private static final String CERT_CHAIN_PASSWD = "password";
private static final String SOURCE_DIRECTORY =
System.getProperty("test.src", "." + File.separator);
public static void main(String[] args) throws Exception {
List<String> expectedValues = null;
out.println("Self signed test");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"api_private_key.p12_expected.data"));
readTest("api_private_key.p12.data", KS_PASSWD, expectedValues);
out.println("Self signed test Passed");
out.println("private key with selfsigned cert, key pair not match");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"api_private_key_not_match.p12_expected.data"));
readTest("api_private_key_not_match.p12.data", KS_PASSWD,
expectedValues);
out.println("private key with selfsigned cert, key pair "
+ "not match passed");
out.println("cert chain test");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"api_cert_chain.p12_expected.data"));
readTest("api_cert_chain.p12.data", CERT_CHAIN_PASSWD, expectedValues);
out.println("cert chain test passed");
out.println("IE self test");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"ie_self.pfx.pem"));
exportTest("ie_self.pfx.data", "pkcs12testenduser1",
KS_PASSWD, expectedValues);
out.println("IE self test passed");
out.println("IE chain test");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"ie_chain.pfx.pem"));
exportTest("ie_chain.pfx.data", "servercert",
CERT_CHAIN_PASSWD, expectedValues);
out.println("IE chain test passed");
out.println("Netscape self");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"netscape_self.p12.pem"));
exportTest("netscape_self.p12.data", "pkcs12testenduser1",
KS_PASSWD, expectedValues);
out.println("Netscape self passed");
out.println("Mozilla self test");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"mozilla_self.p12.pem"));
exportTest("mozilla_self.p12.data", "pkcs12testenduser1",
KS_PASSWD, expectedValues);
out.println("Mozilla self test passed");
out.println("Openssl test");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"openssl.p12.pem"));
exportTest("openssl.p12.data", "servercert", CERT_CHAIN_PASSWD, expectedValues);
out.println("openssl test passed");
out.println("with different keystore and entrykey password");
expectedValues = Files.readAllLines(Paths.get(SOURCE_DIRECTORY,
"api_two_pass.p12_expected.data"));
readTest("api_two_pass.p12.data", KS_PASSWD,
expectedValues);
out.println("two pass test passed");
}
private static void readTest(String name, String password,
List<String> expectedValues)
throws IOException {
convertToPFX(name);
final String[] command = new String[]{"-debug", "-list", "-v",
"-keystore", WORKING_DIRECTORY + File.separator + name,
"-storetype", "pkcs12", "-storepass", password};
runAndValidate(command, expectedValues);
}
private static void exportTest(String name, String alias,
String password, List<String> expectedValues)
throws IOException {
convertToPFX(name);
final String[] command = new String[]{"-debug", "-export", "-alias",
alias, "-keystore", WORKING_DIRECTORY + File.separator + name,
"-storepass", password, "-storetype", "pkcs12", "-rfc"};
runAndValidate(command, expectedValues);
}
private static void runAndValidate(String[] command,
List<String> expectedValues) throws IOException {
OutputAnalyzer output = Utils.executeKeytoolCommand(command);
if (expectedValues != null) {
expectedValues.stream().forEach(line -> {
output.shouldContain(line);
});
}
}
/**
* Decodes the base64 encoded keystore and writes into new file
* @param name base64 encoded keystore name
*/
private static void convertToPFX(String name) throws IOException{
File base64File = new File(SOURCE_DIRECTORY, name);
File pkcs12File = new File(WORKING_DIRECTORY, name);
byte[] input = Files.readAllBytes(base64File.toPath());
Files.write(pkcs12File.toPath(), Base64.getMimeDecoder().
decode(input), StandardOpenOption.CREATE);
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import jdk.testlibrary.OutputAnalyzer;
import static java.lang.System.out;
/**
* @test
* @bug 8048830
* @summary Tests for creating pkcs12 keystore with various algorithms
* @library /lib/testlibrary ../
* @run main KeytoolWriteP12Test
*/
public class KeytoolWriteP12Test {
private static final String ALIAS = "pkcs12testCA";
private static final Utils.KeyStoreType PKCS12 = Utils.KeyStoreType.pkcs12;
private static final int FAILED_EXIT_CODE = 1;
private static final String CERT_FILE_NAME = "cert.data";
private static final String DNAME = "CN=PKCS12 Test CA, OU=Security SQE, "
+ "O=JavaSoft, C=US";
private static final String WORKING_DIRECTORY = System.
getProperty("test.classes", "." + File.separator);
private enum Algorithm {
DSA, RSA, ECC
};
private void run() {
out.println("Running DSA Test");
keytoolListTest("kt_DSA.p12", Algorithm.DSA);
out.println("DSA Test passed");
out.println("Running RSA Test");
final String rsaKeyStoreName = "kt_RSA_MD5.p12";
keytoolListTest(rsaKeyStoreName, Algorithm.RSA);
out.println("RSA Test passed");
out.println("Running RSA and Signing Algorithm SHA1withRSA Test");
keytoolListTest("kt_RSA_SHA1.p12", Algorithm.RSA,
"-sigalg", "SHA1withRSA");
out.println("RSA and Signing Algorithm SHA1withRSA Test Passed");
out.println("Running Keysize 256 Test");
keytoolListNegativeTest("kt_DSA_256.p12", Algorithm.DSA, "-keysize",
"256");
out.println("Keysize 256 Test Passed");
out.println("Running Keysize 1023 Test");
keytoolListTest("kt_RSA_MD5_1023.p12", Algorithm.RSA, "-keysize",
"1023");
out.println("Keysize 1023 Test Passed");
out.println("Running Export certificate Test");
exportTest(rsaKeyStoreName);
out.println("Export certificate Test Passed");
}
private void exportTest(String keyStore) {
final String keyStoreName = WORKING_DIRECTORY + File.separator
+ keyStore;
deleteKeyStoreFile(keyStoreName);
Utils.createKeyStore(DNAME, PKCS12, keyStore, ALIAS,
Algorithm.RSA.name());
final String certFilePath = WORKING_DIRECTORY + File.separator
+ CERT_FILE_NAME;
Utils.exportCert(PKCS12, keyStore,
ALIAS, certFilePath);
final String[] command = new String[]{"-debug", "-printcert", "-v",
"-file", certFilePath};
Utils.executeKeytoolCommand(command);
}
private void keytoolListTest(String keyStore, Algorithm algorithm,
String ...optionalArgs) {
final String keyStoreName = WORKING_DIRECTORY + File.separator
+ keyStore;
final String[] command = new String[]{"-debug", "-list", "-v", "-alias",
ALIAS, "-keystore", keyStoreName, "-storetype", "pkcs12",
"-storepass", Utils.DEFAULT_PASSWD};
deleteKeyStoreFile(keyStoreName);
Utils.createKeyStore(DNAME, PKCS12, keyStoreName, ALIAS,
algorithm.name(), optionalArgs);
OutputAnalyzer output = Utils.executeKeytoolCommand(command);
output.shouldContain(DNAME);
}
private void keytoolListNegativeTest(String keyStore, Algorithm algorithm,
String... optionalArgs) {
final String keyStoreName = WORKING_DIRECTORY + File.separator
+ keyStore;
deleteKeyStoreFile(keyStoreName);
Utils.createKeyStore(DNAME, PKCS12, keyStoreName, ALIAS,
algorithm.name(), optionalArgs, FAILED_EXIT_CODE);
}
public static void main(String[] args) {
KeytoolWriteP12Test test = new KeytoolWriteP12Test();
test.run();
out.println("Test Passed");
}
private void deleteKeyStoreFile(String fileName) {
File file = new File(fileName);
if (file.exists()) {
file.delete();
}
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.io.IOException;
import java.security.cert.CertificateException;
import static java.lang.System.out;
/**
* @test
* @bug 8048830
* @summary Entry's attribute set should be empty
* @library /lib/testlibrary ../
* @run main MetadataEmptyTest
*/
public class MetadataEmptyTest {
private static final char[] PASSWORD = "passwd".toCharArray();
private static final String ALIAS = "testkey";
private static final String KEYSTORE_PATH = System.getProperty(
"test.classes" + File.separator + "ks.pkcs12",
"." + File.separator + "ks.pkcs12");
private void runTest() throws IOException, KeyStoreException,
NoSuchAlgorithmException, CertificateException,
UnrecoverableKeyException {
KeyStore ks = Utils.loadKeyStore(KEYSTORE_PATH,
Utils.KeyStoreType.pkcs12, PASSWORD);
Key key = ks.getKey(ALIAS, PASSWORD);
Certificate cert = ks
.getCertificate(ALIAS);
KeyStore.Entry entry = new KeyStore.PrivateKeyEntry(
(PrivateKey) key,
new Certificate[]{cert});
if (!entry.getAttributes().isEmpty()) {
throw new RuntimeException("Entry's attributes set "
+ "must be empty");
}
out.println("Test Passed");
}
public static void main(String[] args) throws Exception{
MetadataEmptyTest test = new MetadataEmptyTest();
test.setUp();
test.runTest();
}
private void setUp() {
Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS);
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PKCS12Attribute;
import java.security.PrivateKey;
import java.security.UnrecoverableEntryException;
import java.security.cert.Certificate;
import java.util.Arrays;
import java.util.Set;
import static java.lang.System.out;
import java.util.HashSet;
/**
* @test
* @bug 8048830
* @summary Test store metadata attributes to PKCS12 keystore.
* @library /lib/testlibrary ../
* @run main MetadataStoreLoadTest
*/
public class MetadataStoreLoadTest {
private static final char[] PASSWORD = "passwd".toCharArray();
private static final char[] KEY_PASSWORD = "keypasswd".toCharArray();
private static final String ALIAS = "testkey_metadata";
private static final String KEYSTORE = "ks.pkcs12";
private static final String KESTORE_NEW = "ks-attr.pkcs12";
private static final int MAX_HUGE_SIZE = 2000000;
private static final String WORKING_DIRECTORY = System.getProperty(
"test.classes", "." + File.separator);
private static final String KEYSTORE_PATH = WORKING_DIRECTORY
+ File.separator + KEYSTORE;
private static KeyStore.Entry.Attribute[] ATTR_SET;
private void runTest() throws GeneralSecurityException,
UnrecoverableEntryException, NoSuchAlgorithmException,
KeyStoreException, IOException {
storeAttrs();
checkAttrs();
}
private void storeAttrs() throws UnrecoverableEntryException,
GeneralSecurityException, NoSuchAlgorithmException,
KeyStoreException, IOException {
KeyStore ksIn = Utils.loadKeyStore(KEYSTORE_PATH,
Utils.KeyStoreType.pkcs12, PASSWORD);
KeyStore ksAttr = KeyStore
.getInstance(Utils.KeyStoreType.pkcs12.name());
ksAttr.load(null);
Key key = ksIn.getKey(ALIAS, PASSWORD);
Certificate cert = ksIn.getCertificate(ALIAS);
Set<KeyStore.Entry.Attribute> attrs =
new HashSet<>(Arrays.asList(ATTR_SET));
KeyStore.Entry e = new KeyStore.PrivateKeyEntry((PrivateKey) key,
new Certificate[]{cert}, attrs);
ksAttr.setEntry(ALIAS, e, new KeyStore.PasswordProtection(
KEY_PASSWORD));
out.println("Attributes before store:");
e.getAttributes().stream().forEach((attr) -> {
out.println(attr.getName() + ", '" + attr.getValue() + "'");
});
Utils.saveKeyStore(ksAttr, WORKING_DIRECTORY + File.separator
+ KESTORE_NEW, PASSWORD);
}
private void checkAttrs() throws UnrecoverableEntryException,
GeneralSecurityException, NoSuchAlgorithmException,
KeyStoreException, IOException {
KeyStore ks = Utils.loadKeyStore(WORKING_DIRECTORY
+ File.separator
+ KESTORE_NEW, Utils.KeyStoreType.pkcs12, PASSWORD);
KeyStore.Entry keyStoreEntry = ks.getEntry(ALIAS,
new KeyStore.PasswordProtection(KEY_PASSWORD));
out.println("Attributes after store:");
//print attribute values
keyStoreEntry.getAttributes().stream().forEach((attr) -> {
out.println(attr.getName() + ", '" + attr.getValue() + "'");
});
Arrays.stream(ATTR_SET).forEach((attr) -> {
if (!keyStoreEntry.getAttributes().contains(attr)) {
throw new RuntimeException("Entry doesn't contain attribute: ("
+ attr.getName() + ", '" + attr.getValue() + "')");
}
});
}
public static void main(String[] args) throws Exception {
MetadataStoreLoadTest test = new MetadataStoreLoadTest();
test.setUp();
test.runTest();
out.println("Test Passed");
}
private void setUp() {
Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS);
final String allCharsString = "`1234567890-=qwertyuiop[]asdfghjkl;'\\zx"
+ "cvbnm,./!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:|>ZXCVBNM<>?\"";
StringBuilder sbPrintable = new StringBuilder();
while (sbPrintable.length() < MAX_HUGE_SIZE) {
sbPrintable.append(allCharsString);
}
final String hugePrintable = sbPrintable.toString();
final String binaryString = "00:11:22:33:44:55:66:77:88:99:AA:BB:DD:"
+ "EE:FF:";
StringBuilder sbBinary = new StringBuilder();
sbBinary.append(binaryString);
while (sbBinary.length() < MAX_HUGE_SIZE) {
sbBinary.append(":").append(binaryString);
}
sbBinary.insert(0, "[").append("]");
final String hugeBinary = sbBinary.toString();
ATTR_SET = new PKCS12Attribute[5];
ATTR_SET[0] = new PKCS12Attribute("1.2.840.113549.1.9.1",
"Test email addres attr <test@oracle.com>");
ATTR_SET[1] = new PKCS12Attribute("1.2.110.1", "not registered attr");
ATTR_SET[2] = new PKCS12Attribute("1.2.110.2", hugePrintable);
ATTR_SET[3] = new PKCS12Attribute("1.2.110.3", hugeBinary);
ATTR_SET[4] = new PKCS12Attribute("1.2.110.2", " ");
}
}
/*
* Copyright (c) 2003,2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.System.out;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Enumeration;
/*
* @test
* @bug 8048617
* @author Bill Situ
* @summary Read different types p12 key store to Check the read related APIs.
* including following test cases:
* ReadP12_IE_Chain: Read p12 key store (contains private key and associated
* certificate chain) from IE.
* ReadP12_IE_Self: Read p12 key store (contains only private key and
* self-signed certificate) from IE.
* ReadP12_JDK_Chain: Read p12 key store (contains private key and associated
* certificate chain) from JDK
* ReadP12_JDK_Self: Read p12 key store (contains only private key and
* self-signed certificate) from JDK.
* ReadP12_Mozilla_Self: Read p12 key store (contains only private key and
* self-signed certificate) from Mozilla.
* ReadP12_Mozilla_Chain: Read p12 key store (contains private key and
* associated certificate chain) from Mozilla.
* ReadP12_Mozilla_TwoEntries: Read p12 key store (contains 2 entries) from
* Mozilla.
* ReadP12_Netscape_Chain: Read p12 key store (contains private key and
* associated certificate chain) from Netscape.
* ReadP12_Netscape_Self: Read p12 key store (contains only private key and
* self-signed certificate) from Netscape.
* ReadP12_Netscape_TwoEntries: Read p12 key store (contains 2 entries) from
* Netscape.
* ReadP12_OpenSSL: Read p12 key store from OpenSSL.
*/
public class ReadP12Test {
private final static String IN_KETYSTORE_TYPE = "pkcs12";
private final static String IN_KEYSTORE_PRV = "SunJSSE";
private final static String IN_STORE_PASS = "pass";
public static void main(String args[]) throws Exception {
ReadP12Test jstest = new ReadP12Test();
String testCase = "";
try {
testCase = "ReadP12_IE_Chain";
jstest.readTest("ie_chain.pfx.data");
testCase = "ReadP12_IE_Self";
jstest.readTest("ie_self.pfx.data");
testCase = "ReadP12_JDK_Chain";
jstest.readTest("jdk_chain.p12.data");
testCase = "ReadP12_JDK_Self";
jstest.readTest("jdk_self.p12.data");
testCase = "ReadP12_Mozilla_Chain";
jstest.readTest("mozilla_chain.p12.data");
testCase = "ReadP12_Mozilla_Self";
jstest.readTest("mozilla_self.p12.data");
testCase = "ReadP12_Mozilla_TwoEntries";
jstest.readTest("mozilla_twoentries.p12.data");
testCase = "ReadP12_Netscape_Chain";
jstest.readTest("netscape_chain.p12.data");
testCase = "ReadP12_Netscape_Self";
jstest.readTest("netscape_self.p12.data");
testCase = "ReadP12_Netscape_TwoEntries";
jstest.readTest("netscape_twoentries.p12.data");
testCase = "ReadP12_openssl";
jstest.readTest("openssl.p12.data");
} catch (Exception e) {
System.err.println(testCase + ": failed with execption: "
+ e.getMessage());
throw e;
}
out.println(testCase + ": Pass!!");
}
private void readTest(String inKeyStore) throws Exception {
KeyStore inputKeyStore;
// Initialize KeyStore
String dir = System.getProperty("test.src", ".");
String keystorePath = dir + File.separator + "certs" + File.separator
+ "readP12";
inputKeyStore = KeyStore
.getInstance(IN_KETYSTORE_TYPE, IN_KEYSTORE_PRV);
// KeyStore have encoded by Base64.getMimeEncoder().encode(),need decode
// first.
byte[] input = Files.readAllBytes(Paths.get(keystorePath, inKeyStore));
ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64
.getMimeDecoder().decode(input));
inputKeyStore.load(arrayIn, IN_STORE_PASS.toCharArray());
out.println("Initialize KeyStore : " + inKeyStore + " success");
out.println("getProvider : " + inputKeyStore.getProvider());
out.println("getType : " + inputKeyStore.getType());
out.println("getDefaultType : " + KeyStore.getDefaultType());
int idx = 0;
Enumeration<String> e = inputKeyStore.aliases();
String alias;
while (e.hasMoreElements()) {
alias = e.nextElement();
out.println("Alias " + idx + " : " + alias);
if (inputKeyStore.containsAlias(alias) == false) {
throw new RuntimeException("Alias not found");
}
out.println("getCreationDate : "
+ inputKeyStore.getCreationDate(alias));
X509Certificate cert = (X509Certificate) inputKeyStore
.getCertificate(alias);
out.println("getCertificate : " + cert.getSubjectDN());
String retAlias = inputKeyStore.getCertificateAlias(cert);
if (!retAlias.equals(alias)) {
throw new RuntimeException("Alias mismatch");
}
out.println("getCertificateAlias : " + retAlias);
Certificate[] certs = inputKeyStore.getCertificateChain(alias);
for (int i = 0; i < certs.length; i++) {
out.println("getCertificateChain " + i + " : "
+ ((X509Certificate) certs[i]).getSubjectDN());
}
boolean isCertEntry = inputKeyStore.isCertificateEntry(alias);
// test KeyStore only contain key pair entries.
if (isCertEntry == true) {
throw new RuntimeException(
"inputKeystore should not be certEntry because test keystore only contain key pair entries.");
}
boolean isKeyEntry = inputKeyStore.isKeyEntry(alias);
if (isKeyEntry) {
Key key = inputKeyStore.getKey(alias,
IN_STORE_PASS.toCharArray());
out.println("Key : " + key.toString());
} else {
throw new RuntimeException("Entry type unknown\n");
}
idx++;
}
int size = inputKeyStore.size();
if (idx != size) {
throw new RuntimeException("Size not match");
}
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import static java.lang.System.err;
import static java.lang.System.out;
/**
* @test
* @bug 8048830
* @summary Test imports certificate from file to PKCS12 keystore store it as
* trusted certificate Check import errors (must be not errors) & check keystore
* content after import
* @library /lib/testlibrary ../
* @run main StoreTrustedCertAPITest
*/
public class StoreTrustedCertAPITest {
private static final char[] PASSWORD = "passwd".toCharArray();
private static final String ALIAS = "testkey_stcapi";
private static final String WORKING_DIRECTORY = System.getProperty(
"test.classes", "." + File.separator);
private static final String CERT_PATH = WORKING_DIRECTORY + File.separator
+ "cert.data";
private static final String KEYSTORE_PATH = WORKING_DIRECTORY
+ File.separator + "ks.pkcs12";
/**
* Test logic (environment has set up)
*/
private void runTest() throws FileNotFoundException, CertificateException,
KeyStoreException, IOException, NoSuchAlgorithmException {
Certificate cert;
CertificateFactory cf;
try (FileInputStream fi = new FileInputStream(CERT_PATH)) {
cf = CertificateFactory.getInstance("X.509");
cert = cf.generateCertificate(fi);
KeyStore ks = KeyStore.getInstance(
Utils.KeyStoreType.pkcs12.name());
ks.load(null, null);
ks.setCertificateEntry(ALIAS, cert);
Utils.saveKeyStore(ks, KEYSTORE_PATH, PASSWORD);
ks = Utils.loadKeyStore(KEYSTORE_PATH, Utils.KeyStoreType.pkcs12,
PASSWORD);
final Certificate ksCert = ks.getCertificate(ALIAS);
if (!ksCert.equals(cert)) {
err.println("Orig cert: " + cert.toString());
err.println("Cert from keystore: " + ksCert.toString());
throw new RuntimeException("Certificates don't match");
}
}
}
public static void main(String[] args) throws Exception {
StoreTrustedCertAPITest test = new StoreTrustedCertAPITest();
test.setUp();
test.runTest();
out.println("Test Passed");
}
private void setUp() {
Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS);
Utils.exportCert(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH,
ALIAS, CERT_PATH);
new File(KEYSTORE_PATH).delete();
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import jdk.testlibrary.OutputAnalyzer;
import static java.lang.System.out;
/**
* @test
* @bug 8048830
* @summary Tests keytool command imports certificate , list keystore, print
* certificate and import password help.
* @library /lib/testlibrary ../
* @run main StoreTrustedCertKeytool
*/
public class StoreTrustedCertKeytool {
private static final String PASSWORD = "passwd";
private static final String ALIAS = "testkey_stckey";
private static final String FILE_SEPARATOR = File.separator;
private static final String WORKING_DIRECTORY = System.getProperty(
"test.classes", "." + FILE_SEPARATOR);
private static final String CERT_PATH = WORKING_DIRECTORY
+ FILE_SEPARATOR
+ "cert.data";
private static final String KEYSTORE_PATH = WORKING_DIRECTORY
+ FILE_SEPARATOR + "ks.pkcs12";
protected void run() throws IOException, KeyStoreException,
NoSuchAlgorithmException, CertificateException {
setUp();
importCert();
out.println("Import Cert test passed");
listCerts();
out.println("listCerts test passed");
printCert();
out.println("print cert test passed");
helpImportPassword();
out.println("help import test passed");
}
private void importCert() {
final String[] command = new String[]{"-debug", "-importcert",
"-alias", ALIAS, "-file", CERT_PATH, "-noprompt", "-keystore",
KEYSTORE_PATH, "-storetype", "pkcs12", "-storepass", PASSWORD};
// If the keystore exists delete it.
File keystoreFile = new File(KEYSTORE_PATH);
if (keystoreFile.exists()) {
keystoreFile.delete();
}
Utils.executeKeytoolCommand(command);
}
private void listCerts() throws IOException, KeyStoreException,
NoSuchAlgorithmException, CertificateException {
final String[] command = new String[]{"-debug", "-list", "-v",
"-alias", ALIAS, "-keystore", KEYSTORE_PATH, "-storetype", "pkcs12",
"-storepass", PASSWORD};
OutputAnalyzer output = Utils.executeKeytoolCommand(command);
if (output == null) {
throw new RuntimeException("Keystore print fails");
}
X509Certificate ksCert = null;
final KeyStore ks = Utils.loadKeyStore(KEYSTORE_PATH,
Utils.KeyStoreType.pkcs12, PASSWORD.toCharArray());
ksCert = (X509Certificate) ks.getCertificate(ALIAS);
if (ksCert == null) {
throw new RuntimeException("Certificate " + ALIAS
+ " not found in Keystore " + KEYSTORE_PATH);
}
String serialNumber = ksCert.getSerialNumber().toString(16);
output.shouldContain(serialNumber);
}
private void printCert() {
final String[] command = new String[]{"-debug", "-printcert",
"-file", CERT_PATH};
Utils.executeKeytoolCommand(command);
}
private void helpImportPassword() {
final String[] command = new String[]{"-debug", "-help",
"-importpassword"};
Utils.executeKeytoolCommand(command);
}
public static void main(String[] args) throws Exception {
final StoreTrustedCertKeytool test = new StoreTrustedCertKeytool();
test.run();
out.println("Test Passed");
}
private void setUp() {
Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS);
Utils.exportCert(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS,
CERT_PATH);
new File(KEYSTORE_PATH).delete();
}
}
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.List;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.JDKToolFinder;
import static java.lang.System.out;
import java.util.ArrayList;
/**
* Helper class for creating keystore and executing keytool commands
*/
public class Utils {
public enum KeyStoreType {
jks, pkcs12;
}
public static final String DEFAULT_DNAME
= "CN=TestKey, T=FuncTestCertKey, O=Oracle, OU=JDKSQE, C=US";
public static final String DEFAULT_PASSWD = "passwd";
public static final String RSA = "rsa";
public static final String JAVA_HOME = System.getProperty("java.home");
public static final String KEYTOOL = "keytool";
private static final int SUCCESS_EXIT_CODE = 0;
public static OutputAnalyzer executeKeytoolCommand(String[] command) {
return executeKeytoolCommand(command, SUCCESS_EXIT_CODE);
}
public static OutputAnalyzer executeKeytoolCommand(String[] command,
int exitCode) {
String[] keytoolCmd = new String[command.length + 1];
OutputAnalyzer output = null;
try {
keytoolCmd[0] = JDKToolFinder.getJDKTool(KEYTOOL);
System.arraycopy(command, 0, keytoolCmd, 1, command.length);
output = ProcessTools.executeCommand(keytoolCmd);
output.shouldHaveExitValue(exitCode);
out.println("Executed keytool command sucessfully:"
+ Arrays.toString(keytoolCmd));
} catch (Throwable e) {
e.printStackTrace(System.err);
throw new RuntimeException("Keytool Command execution failed : "
+ Arrays.toString(keytoolCmd), e);
}
return output;
}
public static void createKeyStore(KeyStoreType type, String name,
String alias) {
createKeyStore(DEFAULT_DNAME, type, name, alias, RSA);
}
public static void createKeyStore(String dName, KeyStoreType type,
String name, String alias, String algorithm,
String... optionalArgs) {
createKeyStore(dName, type, name, alias, algorithm, optionalArgs,
SUCCESS_EXIT_CODE);
}
public static void createKeyStore(String dName, KeyStoreType type,
String name, String alias, String algorithm,
String[] optionalArgs, int exitCode) {
String[] command = new String[]{"-debug", "-genkeypair", "-alias",
alias, "-keystore", name, "-dname", dName, "-storepass",
DEFAULT_PASSWD, "-keypass", DEFAULT_PASSWD, "-validity", "7300",
"-keyalg", algorithm, "-storetype", type.name()};
if (optionalArgs != null && optionalArgs.length > 0) {
List<String> commandArgs = new ArrayList<>(Arrays.asList(command));
List<String> temp = Arrays.asList(optionalArgs);
commandArgs.addAll(temp);
if (!commandArgs.contains(("-keysize"))) {
commandArgs.add("-keysize");
commandArgs.add("1024");
}
command = commandArgs.toArray(new String[commandArgs.size()]);
}
executeKeytoolCommand(command, exitCode);
}
public static void exportCert(KeyStoreType type, String name,
String alias, String cert) {
String[] command = {"-debug", "-exportcert", "-keystore", name,
"-storetype", type.name(), "-storepass", DEFAULT_PASSWD, "-alias",
alias,"-file",cert,"-noprompt"};
executeKeytoolCommand(command);
}
public static KeyStore loadKeyStore(String file, KeyStoreType type,
char[] passwd)
throws IOException, KeyStoreException,
NoSuchAlgorithmException, CertificateException {
KeyStore ks = KeyStore.getInstance(type.name());
try (FileInputStream fin = new FileInputStream(file)) {
ks.load(fin, passwd);
}
return ks;
}
public static void saveKeyStore(KeyStore ks, String file, char[] passwd)
throws IOException, KeyStoreException, NoSuchAlgorithmException,
CertificateException {
try (FileOutputStream fout = new FileOutputStream(file)) {
ks.store(fout, passwd);
}
}
}
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.System.out;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Base64;
import java.util.Enumeration;
/*
* @test
* @bug 8048618
* @summary Write different types p12 key store to Check the write related
* APIs.
* @run main WriteP12Test
*/
public class WriteP12Test {
private static final String IN_KEYSTORE_TYPE = "jks";
private static final String IN_KEYSTORE_PRV = "SUN";
private static final String IN_KEYSTORE_ENDUSER = "keystoreEU.jks.data";
private static final String IN_KEYSTORE_CA = "keystoreCA.jks.data";
private static final String OUT_KEYSTORE = "outKeyStore.p12";
private static final String IN_STORE_PASS = "storepass";
private static final String IN_KEY_PASS = "keypass";
private static final String CERT_PATH = System.getProperty("test.src", ".")
+ File.separator + "certs" + File.separator + "writeP12"
+ File.separator;
private static final String CA_CERT_STR = "-----BEGIN CERTIFICATE-----\n"
+ "MIIDFzCCAf8CBD8+0nAwDQYJKoZIhvcNAQEFBQAwUDELMAkGA1UEBhMCV\n"
+ "VMxETAPBgNVBAoTCEphdmFTb2Z0MRUwEwYDVQQLEwxTZWN1cml0eSBTUU\n"
+ "UxFzAVBgNVBAMTDlBLQ1MxMiBUZXN0IENBMB4XDTAzMDgxNzAwNTUxMlo\n"
+ "XDTEzMDgxNDAwNTUxMlowUDELMAkGA1UEBhMCVVMxETAPBgNVBAoTCEph\n"
+ "dmFTb2Z0MRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxFzAVBgNVBAMTDlBLQ\n"
+ "1MxMiBUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ\n"
+ "EAk7Sh+K/yGsmJacZnjfkZfuWxGNJCPW0q69exwoRP+eBHMQwG00yi9aL\n"
+ "SsZAqNpJSCDvpgySOAUmBd+f8WFhHqJfRVREVfv3mradDKZCjhqtsUI7I\n"
+ "wRTYYy9clFkeeK4dHaxbuFMPpUu7yQfwSTXgvOA/UJ4kJuGtaYAdTJI4e\n"
+ "f1mUASo6+dea0UZA/FHCuV7O6z3hr5VHlyhJL2/o/8M5tGBTBISODJSnn\n"
+ "GNBvtQLNHnWYvs470UAE2BtuCGYh1V/3HAH1tRirS3MBBcb1XnIkiiXR3\n"
+ "tjaBSB+XhoCfuG8KtInXXFaAnvKfY9mYFw6VJt9JYQpY2VDC7281/Pbz0\n"
+ "dQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQBzXZ8zHWrnC8/E+N/n2Czhx\n"
+ "i18YQc2LPWBDLYTTxoFEazWmYLv1k/JT7Nta1qu1quvxXJ4uV1XHbd9NF\n"
+ "AJWKwtFQEpfv4o6I7qWUPoxnfA+jyqKXxv27z25tzt+Y4xOEhqvO03G0Q\n"
+ "imhkiNt9MF7L69y2U0/U73+uFNGzdAEDiI9EibvICiOnr1TeQ5GekK3Yb\n"
+ "k5qe3lviMZPkkSXepTJI8m0AiXCji+eXj97jVLeH+RxeBchBY+uELrqUr\n"
+ "sVOVWh7IBCqC/V7FqUTkmD1IFlzkkinatpl42s1MbhJId2yQkzaeBRc\n"
+ "suE63bDEtuRWp9ynMO3QA4Yu85uBRWGzQ1Di\n"
+ "-----END CERTIFICATE-----";
private static final String LEAD_CERT = "-----BEGIN CERTIFICATE-----\n"
+ "MIICwDCCAaigAwIBAgIEPz7S1jANBgkqhkiG9w0BAQQFADBQMQswCQYDV\n"
+ "QQGEwJVUzERMA8GA1UEChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaX\n"
+ "R5IFNRRTEXMBUGA1UEAxMOUEtDUzEyIFRlc3QgQ0EwHhcNMDAwODA5MDc\n"
+ "wMDAwWhcNMTAwODA3MDcwMDAwWjBSMQswCQYDVQQGEwJVUzERMA8GA1UE\n"
+ "ChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaXR5IFNRRTEZMBcGA1UEA\n"
+ "xMQUEtDUzEyIFRlc3QgTGVhZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgY\n"
+ "kCgYEAzq9X2USz/WjDhT+jUyZWqB5h4A33tS11YqH5qYvqjTXjcUI6gOp\n"
+ "moXMafDG9RHRlIccvp51xLp7Ap3WMrv411lWBttqtZi5c1/DEC1cEM/Sl\n"
+ "PCk1r2zFbkJu7QKieXeMcrjZEo6LcBHMwQjIpI+up9cr3VjuyqG/olQkU\n"
+ "mXVuS0CAwEAAaMkMCIwDwYDVR0PAQH/BAUDAweAADAPBgNVHRMBAf8EBT\n"
+ "ADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBhbuim98TWmtv9vSldRE7RvQ8\n"
+ "FlS0TyZVO7kcSNtfCUE4R76J1ElN74Koc5pQnUtduLeQJs2ao/mEcCZsE\n"
+ "zVcwI3mSZrSzPhc8s7w5gOQA4TUwVLSSjKgBCaZ7R3+qJ3QeqPJ5O6sFz\n"
+ "pvBYkgSa4MWptK41jbmT8cwZQJXFCi8WxFFJ+p97F1Ppm3LgmYmtiUP4M\n"
+ "ZQwOBvpTZWXU0WrqFXpzWQx0mg4SX19fZm4nLcJAerCEUphf8ILagtpQM\n"
+ "EErT3/jg6mfCdT3Rj055QXPfF4OiRFevPF5a1fZgrCePCukRQZcd7s8K5\n"
+ "OBIaryuM0MdFtlzxi6XWeUNpVFFHURcy\n"
+ "-----END CERTIFICATE-----";
private static final String END_CERT = "-----BEGIN CERTIFICATE-----\n"
+ "MIICNjCCAZ+gAwIBAgIEPz7WtzANBgkqhkiG9w0BAQQFADBSMQswCQYDV\n"
+ "QQGEwJVUzERMA8GA1UEChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaX\n"
+ "R5IFNRRTEZMBcGA1UEAxMQUEtDUzEyIFRlc3QgTGVhZDAeFw0wMDA4MDk\n"
+ "wNzAwMDBaFw0xMDA4MDcwNzAwMDBaMFgxCzAJBgNVBAYTAlVTMREwDwYD\n"
+ "VQQKEwhKYXZhU29mdDEVMBMGA1UECxMMU2VjdXJpdHkgU1FFMR8wHQYDV\n"
+ "QQDExZQS0NTMTIgVGVzdCBFbmQgVXNlciAxMIGfMA0GCSqGSIb3DQEBAQ\n"
+ "UAA4GNADCBiQKBgQDIKomSYomDzH/V63eDQEG7od0DLcnnVZ81pbWhDss\n"
+ "8gHV2m8pADdRqdihBmnSQEaMW4D3uZ4sFE1LtkQls6hjd7SdOsG5Y24L8\n"
+ "15jot9a2JcB73H8H0VKirrObL5BZdt7BtASPDnYtW4Spt++YjDoJFxyF0\n"
+ "HchkavzXaVTlexakwIDAQABoxMwETAPBgNVHQ8BAf8EBQMDB4AAMA0GCS\n"
+ "qGSIb3DQEBBAUAA4GBAIFA3JXEmb9AXn3RD7t+Mn6DoyVDIy5jsn6xOKT\n"
+ "JV25I0obpDUzgw4QaAMmM0ZvusOmZ2wZNS8MtyTUgdANyakbzn5SdxbTy\n"
+ "TLEqQsFbX8UVC38fx5ZM6ExA5YSAvgmXudZpOVC0ATccoZS3JFU8CxSfW\n"
+ "+Q3IC2MLh+QTg3hUJ5b\n-----END CERTIFICATE-----";
private final Certificate testerCert;
private final Certificate testLeadCert;
private final Certificate caCert;
WriteP12Test() throws CertificateException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
caCert = cf.generateCertificate(new ByteArrayInputStream(CA_CERT_STR
.getBytes()));
testLeadCert = cf.generateCertificate(new ByteArrayInputStream(
LEAD_CERT.getBytes()));
testerCert = cf.generateCertificate(new ByteArrayInputStream(END_CERT
.getBytes()));
}
public static void main(String[] args) throws CertificateException,
UnrecoverableKeyException, KeyStoreException,
NoSuchProviderException, NoSuchAlgorithmException, IOException {
WriteP12Test jstest = new WriteP12Test();
out.println("test WriteP12CertChain");
/*
* WriteP12CertChain: This test creates a p12 keystore contains one
* entry with private key and a certificate chains contains three
* certificates in the order of user->lead->ca. This case expects to
* pass.
*/
jstest.test(new Certificate[] { jstest.testerCert, jstest.testLeadCert,
jstest.caCert }, IN_KEYSTORE_ENDUSER, "pkcs12testenduser1",
"pass", "pass");
/*
* WriteP12CertChainBad: same as WriteP12CertChain but chains order is
* user-ca-lead, the order is wrong so expects to fail.
*/
out.println("test WriteP12CertChainBad");
try {
jstest.test(new Certificate[] { jstest.testerCert, jstest.caCert,
jstest.testLeadCert }, IN_KEYSTORE_ENDUSER,
"pkcs12testenduser1", "pass", "pass");
throw new RuntimeException(
" Certificate chain is not valid, test should not pass."
+ " Test failed.");
} catch (KeyStoreException e) {
e.printStackTrace();
out.println(" Certificate chain is not valid,exception is"
+ " expected. Test passed.");
}
/*
* WriteP12PrivateKey:This test creates a p12 contains a self-signed
* cert and private key,expects no exception
*/
out.println("test WriteP12PrivateKey");
jstest.test(null, IN_KEYSTORE_ENDUSER, "pkcs12testenduser1", "pass",
"pass");
/*
* WriteP12TwoEntry: This test creates a p12 keystore with different
* storepass and keypass, and contains two entries.
*/
out.println("test WriteP12TwoEntry");
jstest.testTwoEntry(IN_KEYSTORE_ENDUSER, IN_KEYSTORE_CA,
"pkcs12testenduser1", "pass", "pass");
/*
* WriteP12TwoPass: This test creates a p12 keystore with different
* storepass and keypass, and contains one entry with private key and a
* certificate
*/
out.println("test WriteP12TwoPass");
jstest.test(null, IN_KEYSTORE_CA, "pkcs12testCA", "storepass",
"keypass");
}
private void test(Certificate certs[], String inKeyStorePath,
String userAlias, String outStorePass, String outKeyPass)
throws KeyStoreException, NoSuchProviderException, IOException,
CertificateException, UnrecoverableKeyException,
NoSuchAlgorithmException {
// init output key store
KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "SunJSSE");
outputKeyStore.load(null, null);
try (FileOutputStream fout = new FileOutputStream(OUT_KEYSTORE)) {
// KeyStore have encoded by Base64.getMimeEncoder().encode(),need
// decode first.
byte[] input = Files.readAllBytes(Paths.get(CERT_PATH,
inKeyStorePath));
ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64
.getMimeDecoder().decode(input));
// input key store
KeyStore inputKeyStore = KeyStore.getInstance(IN_KEYSTORE_TYPE,
IN_KEYSTORE_PRV);
inputKeyStore.load(arrayIn, IN_STORE_PASS.toCharArray());
// add key/certificate to output key store
Key key = inputKeyStore
.getKey(userAlias, IN_KEY_PASS.toCharArray());
out.println("Input Key Algorithm " + key.getAlgorithm());
out.println("====Input Certs=====");
if (certs == null) {
certs = new Certificate[] { inputKeyStore
.getCertificate(userAlias) };
}
for (Certificate cert : certs) {
out.println(((X509Certificate) cert).getSubjectDN());
}
outputKeyStore.setKeyEntry(userAlias, key,
outKeyPass.toCharArray(), certs);
Certificate retCerts[] = outputKeyStore
.getCertificateChain(userAlias);
out.println("====Output Certs=====");
for (Certificate retCert : retCerts) {
out.println(((X509Certificate) retCert).getSubjectDN());
}
out.println("====Output Key Algorithm=====");
Key outKey = outputKeyStore.getKey(userAlias,
outKeyPass.toCharArray());
out.println(outKey.getAlgorithm());
if (!key.equals(outKey)) {
throw new RuntimeException("key don't match");
}
if (!Arrays.equals(certs, retCerts)) {
throw new RuntimeException("certs don't match");
}
// save output
outputKeyStore.store(fout, outStorePass.toCharArray());
// test output
testKeyStore(outputKeyStore, outKeyPass.toCharArray());
}
}
private void testTwoEntry(String inKeyStoreOnePath,
String inKeyStoreTwoPath, String userAlias, String outStorePass,
String outKeyPass) throws KeyStoreException,
NoSuchProviderException, NoSuchAlgorithmException,
CertificateException, IOException, UnrecoverableKeyException {
// initial KeyStore
KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "SunJSSE");
try (FileOutputStream fout = new FileOutputStream(OUT_KEYSTORE);) {
outputKeyStore.load(null, null);
KeyStore inputKeyStoreOne, inputKeyStoreTwo;
inputKeyStoreOne = KeyStore.getInstance(IN_KEYSTORE_TYPE,
IN_KEYSTORE_PRV);
// KeyStore have encoded by Base64.getMimeEncoder().encode(),need
// decode first.
byte[] inputBytes = Files.readAllBytes(Paths.get(CERT_PATH,
inKeyStoreOnePath));
ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64
.getMimeDecoder().decode(inputBytes));
// input key store
inputKeyStoreOne.load(arrayIn, IN_STORE_PASS.toCharArray());
inputBytes = Files.readAllBytes(Paths.get(CERT_PATH,
inKeyStoreTwoPath));
arrayIn = new ByteArrayInputStream(Base64.getMimeDecoder().decode(
inputBytes));
inputKeyStoreTwo = KeyStore.getInstance(IN_KEYSTORE_TYPE,
IN_KEYSTORE_PRV);
inputKeyStoreTwo.load(arrayIn, IN_STORE_PASS.toCharArray());
// add key/certificate to output key store
out.println("====First Entry=====");
Key inputKey = inputKeyStoreOne.getKey(userAlias,
IN_KEY_PASS.toCharArray());
Certificate cert = inputKeyStoreOne.getCertificate(userAlias);
Certificate certs[] = new Certificate[1];
certs[0] = cert;
out.println("====Input1 Key=====");
out.println(inputKey.getAlgorithm());
out.println("====Input1 Certs=====");
out.println("Certificate :");
out.println(((X509Certificate) cert).getSubjectDN());
outputKeyStore.setKeyEntry("USER", inputKey,
outKeyPass.toCharArray(), certs);
out.println("====Second Entry=====");
String caAlias = "pkcs12testca";
inputKey = inputKeyStoreTwo.getKey(caAlias,
IN_KEY_PASS.toCharArray());
cert = inputKeyStoreTwo.getCertificate(caAlias);
certs[0] = cert;
out.println("====Input2 Key=====");
out.println(inputKey.getAlgorithm());
out.println("====Input2 Certs=====");
out.println("Certificate :");
out.println(((X509Certificate) cert).getSubjectDN());
outputKeyStore.setKeyEntry("CA", inputKey,
outKeyPass.toCharArray(), certs);
// save output
outputKeyStore.store(fout, outStorePass.toCharArray());
// test output
testKeyStore(outputKeyStore, outKeyPass.toCharArray());
}
}
private void testKeyStore(KeyStore inputKeyStore, char[] keypass)
throws KeyStoreException, UnrecoverableKeyException,
NoSuchAlgorithmException {
out.println("========== Key Store ==========");
out.println("getProvider : " + inputKeyStore.getProvider());
out.println("getType : " + inputKeyStore.getType());
out.println("getDefaultType : " + KeyStore.getDefaultType());
int idx = 0;
Enumeration<String> e = inputKeyStore.aliases();
String alias;
while (e.hasMoreElements()) {
alias = e.nextElement();
if (!inputKeyStore.containsAlias(alias)) {
throw new RuntimeException("Alias not found");
}
out.println("Alias " + idx + " : " + alias);
out.println("getCreationDate : "
+ inputKeyStore.getCreationDate(alias));
X509Certificate cert = (X509Certificate) inputKeyStore
.getCertificate(alias);
out.println("getCertificate : " + cert.getSubjectDN());
String retAlias = inputKeyStore.getCertificateAlias(cert);
if (!retAlias.equals(alias)) {
throw new RuntimeException("Alias mismatch, actually "
+ retAlias + ", expected " + alias);
}
out.println("getCertificateAlias : " + retAlias);
Certificate[] certs = inputKeyStore.getCertificateChain(alias);
int i = 0;
for (Certificate certification : certs) {
out.println("getCertificateChain " + i
+ ((X509Certificate) certification).getSubjectDN());
i++;
}
if (inputKeyStore.isCertificateEntry(alias)) {
throw new RuntimeException(
"inputKeystore should not be certEntry because this"
+ " keystore only contain key pair entries.");
}
if (!inputKeyStore.isKeyEntry(alias)) {
throw new RuntimeException("Entry type unknown.");
}
idx++;
}
int size = inputKeyStore.size();
if (idx != size) {
throw new RuntimeException("Size not match, actually " + idx
+ ", expected " + size);
}
}
}
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
SHA1: 09:F1:08:B1:B3:28:22:23:22:F7:5F:6D:4A:8D:0E:0A:5E:6D:56:FB
SHA256: AD:57:47:67:20:96:49:86:53:E4:10:EF:BD:4D:D2:B0:81:C0:B0:BB:62:AE:BE:47:80:DC:00:F8:E3:E7:66:B5
SHA1: 2B:CE:0C:E1:35:B9:9D:FE:5A:6E:25:88:01:F7:E9:E5:7B:89:17:42
SHA256: 65:F3:0A:64:F2:52:B2:4E:F8:76:C5:D0:6D:53:7C:E8:00:AE:F4:95:3C:CC:CB:01:6B:22:AF:46:36:50:CF:FF
SHA1: 7D:48:4D:1C:F8:55:E8:79:6A:B0:19:E1:26:4F:AC:FD:57:6B:38:A0
SHA256: 0A:14:3F:88:8D:C2:D6:97:3E:02:0F:5F:17:E3:D9:FE:CF:93:10:2C:3C:8D:81:AC:06:2F:32:39:4D:0E:CB:6A
Alias name: servercert
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
SHA1: 48:22:E2:C2:47:9F:75:E3:52:56:9C:20:37:DF:03:7F:CD:9F:87:38
SHA256: 9B:DF:B9:EC:DB:3E:EF:BD:61:8F:C3:62:BD:3E:95:FE:E5:B6:A3:F9:94:3D:8D:C1:AE:E9:44:86:25:FA:C1:1B
Alias name: pkcs12testenduser1
MIIEpAIBAzCCBF4GCSqGSIb3DQEHAaCCBE8EggRLMIIERzCCBEMGCSqGSIb3DQEHBqCCBDQwggQw
AgEAMIIEKQYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQUgIXKrki/1oMI4cCRpYWa/iQtL0cC
AgQAgIID8L1nh0C0Gmm9/AbAYbiwBJeb5oCAHa5E6BXJO9DP+m7774lUoQFuAmHJRoqr9hRzJulD
FfdkmRO9JdCs1tRgmnik66ybBb2wqr9gsAhPHFhDWuYIQTJcYqYlBTS8hbg5stDYWCeyaqK3+Zyp
bV3nHZtCe0AO+Rd3derZ3qhluPhc2FWX05fIomTZNiJsbi5wp95ejH4tGX5OdQoWXBjDzlrxopUd
pmdmHfJvRRTEtMr45VPfuHOkAX8Fe2tPFUgkE2tUalUth90AuPXVlMm5Ne+OdKcj+V2EN2s5JxA6
28H1IL753Hov3R80/+Rzn+NIN/BCwLfHyTFa4Ur7Z2dyOJHvM5qeaz580RR8MwsEjqSpmXiyVhQW
3LNuziqs21woC7ueDW7TLiLhHp2Mt8BqFyfUYqBoS29lchRTHZbWTN2h66xycXlzbUCGIOHDXPXB
mqgxQWIltgluel+9Uf//D5yzIkXbtnW9dkMwKkybctAUs9VN8V44UBxv4+noSxepUs0iG+07c5Uu
dfvzwYtnKqKUrtTT8tA/MBNd4P1paYJR2Angx5tInyNKp8TwOaSrFUfg9stMYMh2fbWHLJFS9RDz
P7BDkrBgEO7jDu3O/XyyXzgUQRcQBv/Mw7sCFQ8BBMFzwf/dc6q277w+DJmwz2ex23iXQXQi/b6Y
iHbPwYHVwURWpVAq3P36pCTYjnUpPHMgRKo/9Iy+tL39H46SyGqBFlriM4jDEu7dbi7n1MuMxRYD
zocSkdsnlsJUBOhHLFFYIUIqx6jOgnOESKPWbG9XIHCTZJYnpasmP/VidrQMljzC7c3piePsI03D
8NcJq+BqCRrX+7Z5vPAU022hMryQqHesgnx0T0dWXaCyabzjjjOaWvacxRRCiJ4+EFZqAahMNQp/
XTNlpW1eI0oQ3YBlJl5FWuwhk6YuoNSoi8ya1wp42rFnTwXIG8enfa0wyx/ORAvfypW4wcohsCdP
oRjc9foQsdcjxv2e1yMn9TlgjTOemY81mFfaSMa+4OIhSgLnIYI96QztrY9n8WHJer1hxVdKrb+8
Mhf2vcNEToVF9ypst1C7fXSeOKdAYlNDskPAAm3prcuLMf1dzceIADr+4JOYxzdz6lLvjR+tpAHo
zWO1xh73P+p+Bo82wxnoWCopqOUCEoAYhsy+JBGZNM4AHvPAo4g0Sett3qixZhvbmw9kzKsiFAjf
wQHYPUfl0O02HvBizHK7dRDqJ94G/djGBhqfe34P0hKrCzW+n0u5nFmkFEdk50LpsTu0z3AaaaNh
E6485FDeW3R3/67pGXglNJHBWPsl2AYFimUTzxQqOfoCzBiw9St7hNvuCJBv5jA9MCEwCQYFKw4D
AhoFAAQUczIrgX5A0QTP7tpYDiY3MaSbEM8EFAprSM643ml+k9DGSQKZ7MG0UEhKAgIEAA==
SHA1: 2B:CE:0C:E1:35:B9:9D:FE:5A:6E:25:88:01:F7:E9:E5:7B:89:17:42
SHA256: 65:F3:0A:64:F2:52:B2:4E:F8:76:C5:D0:6D:53:7C:E8:00:AE:F4:95:3C:CC:CB:01:6B:22:AF:46:36:50:CF:FF
Alias name: pkcs12testenduser1
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
+FjQ0fq7d/D+Ilu6e2EBG1y/ngICBAA=
SHA1: 77:90:EC:65:C5:0C:FD:F2:1E:B0:3A:BD:43:21:1A:C6:FD:18:8C:AB
SHA256: 8E:C8:49:82:B8:4B:89:8E:61:2D:CD:F6:D6:34:96:04:91:6F:1B:08:F5:CD:BD:23:ED:94:22:5A:B4:7A:39:DD
Alias name: pkcs12testenduser1
MIINXgIBAzCCDRoGCSqGSIb3DQEHAaCCDQsEgg0HMIINAzCCA7wGCSqGSIb3DQEHAaCCA60EggOp
MIIDpTCCA6EGCyqGSIb3DQEMCgECoIICtjCCArIwHAYKKoZIhvcNAQwBAzAOBAipOP0AVsizDgIC
B9AEggKQIP/YI9/C2WYbIWxKuqXMD8WPCvqj1fhHmZJ0epCzgEdOR7GT/h2Fy4/wxrthPkj4JqkS
akQog3pjOFtj9D8QtkOw/b761qsyj17TYlQS9C6qVhcddMA+Ca2NcDhKlYofQMNTuYPXkXlpCh5R
CNFgQ+PLVZwNZjqoitjv0RLQqBudhTmJSvfDlW2w+CpbziEeRNzn0pX0/Ts7KxykDscOmUCGHKic
b6FqHoioElcmBp7ae3zdXuvI1x/1Y435qju2yODPpMXEZbdsD5iL07RZyL2vm6lfQbLc37TszDBx
ZZJ7ja5F4V/j/6/AVLkcqfZxFOnXz5Ki9rQblYJbkkTpJAyiNqi8Gx+zgPGtLWvV6KRD0zmxo6q/
OmdjKz4v9aG7MDSXenoy6tPAOvAQcQYaksvFZs1FjorJJpFzasfTUfy94JzrHUzRSPzNRDANHG/6
TgxC1FMNw+iQUY9L8j4xrWsr2JN5tAgYcWz1qZrp4cx0he9cbQeqYcjv7ZvIQbIe2zxdvxh7WByy
r8hNMe3RkMOM2yuP85JuWipq+9jt4/CrimKljN1ULPw+V9FZzY8kKcEiSPD+KXdJNkrMr77/lUJz
PGNYpFBFb4natmi31ZBH2VomTeKPpeanN/ghWojft1mGd1s1nD4NelrWATMVquH2Cq6nhKLRHi4c
KbQsMo+ftLvkDHHtpYenjGHbwEFfowkwn9slsZqmPEATV6caHNITCBbhQmvvhqPDPPViV+u1M1c7
vwf/ol7IjBlubwzBJAg6f5GW0tMNHxfg5E7O27AyREyvexk0IVakzIwUuP2anPTjPW0vyeePLtiG
TXNoUe+5UIzpshnLmSlerhVGoB+HBM1yoaaJHay7sdyQbVUxgdcwEwYJKoZIhvcNAQkVMQYEBAEA
AAAwWwYJKoZIhvcNAQkUMU4eTAB7ADcAMQA5AEIAQgA4ADkANAAtADMANQA2ADEALQA0AEMAMAA0
AC0AOQBCADIAMAAtADMAOQBCAEMARAAzADQANwAzADUAMQAwAH0wYwYJKwYBBAGCNxEBMVYeVABN
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
CxwCAgfQ
\ No newline at end of file
MIINXgIBAzCCDRoGCSqGSIb3DQEHAaCCDQsEgg0HMIINAzCCA7wGCSqGSIb3DQEHAaCCA60EggOp
MIIDpTCCA6EGCyqGSIb3DQEMCgECoIICtjCCArIwHAYKKoZIhvcNAQwBAzAOBAipOP0AVsizDgIC
B9AEggKQIP/YI9/C2WYbIWxKuqXMD8WPCvqj1fhHmZJ0epCzgEdOR7GT/h2Fy4/wxrthPkj4JqkS
akQog3pjOFtj9D8QtkOw/b761qsyj17TYlQS9C6qVhcddMA+Ca2NcDhKlYofQMNTuYPXkXlpCh5R
CNFgQ+PLVZwNZjqoitjv0RLQqBudhTmJSvfDlW2w+CpbziEeRNzn0pX0/Ts7KxykDscOmUCGHKic
b6FqHoioElcmBp7ae3zdXuvI1x/1Y435qju2yODPpMXEZbdsD5iL07RZyL2vm6lfQbLc37TszDBx
ZZJ7ja5F4V/j/6/AVLkcqfZxFOnXz5Ki9rQblYJbkkTpJAyiNqi8Gx+zgPGtLWvV6KRD0zmxo6q/
OmdjKz4v9aG7MDSXenoy6tPAOvAQcQYaksvFZs1FjorJJpFzasfTUfy94JzrHUzRSPzNRDANHG/6
TgxC1FMNw+iQUY9L8j4xrWsr2JN5tAgYcWz1qZrp4cx0he9cbQeqYcjv7ZvIQbIe2zxdvxh7WByy
r8hNMe3RkMOM2yuP85JuWipq+9jt4/CrimKljN1ULPw+V9FZzY8kKcEiSPD+KXdJNkrMr77/lUJz
PGNYpFBFb4natmi31ZBH2VomTeKPpeanN/ghWojft1mGd1s1nD4NelrWATMVquH2Cq6nhKLRHi4c
KbQsMo+ftLvkDHHtpYenjGHbwEFfowkwn9slsZqmPEATV6caHNITCBbhQmvvhqPDPPViV+u1M1c7
vwf/ol7IjBlubwzBJAg6f5GW0tMNHxfg5E7O27AyREyvexk0IVakzIwUuP2anPTjPW0vyeePLtiG
TXNoUe+5UIzpshnLmSlerhVGoB+HBM1yoaaJHay7sdyQbVUxgdcwEwYJKoZIhvcNAQkVMQYEBAEA
AAAwWwYJKoZIhvcNAQkUMU4eTAB7ADcAMQA5AEIAQgA4ADkANAAtADMANQA2ADEALQA0AEMAMAA0
AC0AOQBCADIAMAAtADMAOQBCAEMARAAzADQANwAzADUAMQAwAH0wYwYJKwYBBAGCNxEBMVYeVABN
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
CxwCAgfQ
\ No newline at end of file
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
\ No newline at end of file
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
\ No newline at end of file
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
1QoCAgQA
\ No newline at end of file
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
xp4CAgQA
\ No newline at end of file
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
\ No newline at end of file
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
1QoCAgQA
\ No newline at end of file
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
FgNW1MI40XfEdWafFXeJ+yQTHPyoNdk=
\ No newline at end of file
MIINXgIBAzCCDRoGCSqGSIb3DQEHAaCCDQsEgg0HMIINAzCCA7wGCSqGSIb3DQEHAaCCA60EggOp
MIIDpTCCA6EGCyqGSIb3DQEMCgECoIICtjCCArIwHAYKKoZIhvcNAQwBAzAOBAipOP0AVsizDgIC
B9AEggKQIP/YI9/C2WYbIWxKuqXMD8WPCvqj1fhHmZJ0epCzgEdOR7GT/h2Fy4/wxrthPkj4JqkS
akQog3pjOFtj9D8QtkOw/b761qsyj17TYlQS9C6qVhcddMA+Ca2NcDhKlYofQMNTuYPXkXlpCh5R
CNFgQ+PLVZwNZjqoitjv0RLQqBudhTmJSvfDlW2w+CpbziEeRNzn0pX0/Ts7KxykDscOmUCGHKic
b6FqHoioElcmBp7ae3zdXuvI1x/1Y435qju2yODPpMXEZbdsD5iL07RZyL2vm6lfQbLc37TszDBx
ZZJ7ja5F4V/j/6/AVLkcqfZxFOnXz5Ki9rQblYJbkkTpJAyiNqi8Gx+zgPGtLWvV6KRD0zmxo6q/
OmdjKz4v9aG7MDSXenoy6tPAOvAQcQYaksvFZs1FjorJJpFzasfTUfy94JzrHUzRSPzNRDANHG/6
TgxC1FMNw+iQUY9L8j4xrWsr2JN5tAgYcWz1qZrp4cx0he9cbQeqYcjv7ZvIQbIe2zxdvxh7WByy
r8hNMe3RkMOM2yuP85JuWipq+9jt4/CrimKljN1ULPw+V9FZzY8kKcEiSPD+KXdJNkrMr77/lUJz
PGNYpFBFb4natmi31ZBH2VomTeKPpeanN/ghWojft1mGd1s1nD4NelrWATMVquH2Cq6nhKLRHi4c
KbQsMo+ftLvkDHHtpYenjGHbwEFfowkwn9slsZqmPEATV6caHNITCBbhQmvvhqPDPPViV+u1M1c7
vwf/ol7IjBlubwzBJAg6f5GW0tMNHxfg5E7O27AyREyvexk0IVakzIwUuP2anPTjPW0vyeePLtiG
TXNoUe+5UIzpshnLmSlerhVGoB+HBM1yoaaJHay7sdyQbVUxgdcwEwYJKoZIhvcNAQkVMQYEBAEA
AAAwWwYJKoZIhvcNAQkUMU4eTAB7ADcAMQA5AEIAQgA4ADkANAAtADMANQA2ADEALQA0AEMAMAA0
AC0AOQBCADIAMAAtADMAOQBCAEMARAAzADQANwAzADUAMQAwAH0wYwYJKwYBBAGCNxEBMVYeVABN
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
CxwCAgfQ
\ No newline at end of file
MIIKRgIBAzCCCgIGCSqGSIb3DQEHAaCCCfMEggnvMIIJ6zCCBgwGCSqGSIb3DQEHAaCCBf0EggX5
MIIF9TCCBfEGCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAjnValj/qxAxQIC
B9AEggTYZZfhDgMBhoV+P+A4KJf/gnrbkgp4ZDWzXl8gOttjRXofhACETGpX5IHsE7UnXbRc4T70
ByZGlcGTDuT9VgiFnFN4VTs1tRIz2W4cs4EmogLX2sX4KP3U6lZiXugEJ36wPSSN8A1prsZsrTid
ff6bsi+sIO+OI6X8Y0degOU44huDhZe7Fmjed13aW6jLhr8SKRSoufDR/sjVnJK476qkYZc4/Dlr
sMmYftHdgxjfm1KdOVycWm+1ItRzniZemiYYYB+vkUBYPO/rMKCp717SWOQhs7SNQcG4KjdLs8vv
skiRPgRzfbt6vaEC4yKy27FDFqzx4unLRzGJ+ekbLzzZAu4TMS7j5g7Ngo0d7GS4+ZGHamOvDuXQ
x8/Itv1/0qzGMwLXyu1x4K1hTgFKD5NQoEk89qZMDVXi4ylGTWXE0x5azKCXP06LxP9/Pit/ufG9
CwUAIeDrZ4A6F0hyT4p7WMgaUqry54/YrjQBd632I7FacKnYojgcW+xQeRufxiYJ5x/6QIZ4dDmj
4rX7W4/0UOVlyFltmmoSq1HJRMaw95iUE+ft3q6vK/bvy6FZSd1CAbr0tut6HBmcW6BOdXFGmXGS
JnbwaK1IFU4c6KOVAwP16poGhOxaJqRaa4zMBaPcYg84rQ3aI00UHGKQvRb6UWYVGVayc13WYcGQ
Mm8GEjlmh4URRXaRL1qTKCjjYjG1mvTG+TOYUwGZUOGD+6fkGFKMkNXxLmaDyyT0cSoBeMl4whQx
obafWD8sMxCJb/E0eil/fbu114rmFfrrqP2evPEIuQoacNr+OUnfr+T6vbBpT79emxkgsKuG7eEt
4okYQTCp6aEpk7ZKppiZVOBvrN1lZfOH9s9qqtbx5Y+9uj5aGADHkhr6c4pYoIaa1BuUKgBiglE7
QdRFm98TFlC328BbUvBFXEAnshXeYHRPgevcapDBIqFz8ZBnJNMgY3KZ+mug0wg09vsFE8TkH86p
WwvgUzLlZDNt64OHh9E5Ql1MtnMlp0nunpLQyYcmCn8AJIcxSnaicjSlp+Z04hSWXAesbWie41H2
OA1CqsQdc9EePijdjX3QxDK9mBNhXY2ngWrvwkmlYatHdSFzXB4uzCsT5NKK0nKI/AmUN5vVVv01
CFCPHgyBBxF1wom2mA/QFv+7WX6c5Oj0WgOLe/3VySQ9xPoI53Cc1Jl7uOm6kXIMzMxCOiDDcScJ
i0LwyDtmVZlOqhiGCiguoptQnTT3zzp2uaDLVvyMy7bZP8T7G7ka7CSpWQNr0USldgpT8HOXJWgI
4il9iQlaajYO9ntwtYAlMTjsYy4NNoW0uYajdnjT1wO+0w1A0SKP7UrRnyaonf/G4z/VeNSh+yEn
7RkFErPhhvHQRFMG3Gkgw4ER+zo7Q7x2m5R7FOeCp4x0/wiI0e/SzyYxBqXSQfEWxQjb7IJVfd6a
gFT/heXJDvEGbLzUR9jhDptGggE2NlFyA4G+ol6XRRZKlBA0XUYJPHY+fyvcHikiJeMM/YRkrhCE
LOqfCNOafSSSLcQNzJjevq/cDpgybQZV+BrN3yPtQlZgZAy9jOZlULVQSak7K2dF355mEtPNQUIH
4U+GdMXitRVknz/dv7SF8tVzR/GYJEX51i0Qou+rzOFhmurxHyomRHnB5WTG8D/SbzGB3zATBgkq
hkiG9w0BCRUxBgQEAQAAADBbBgkqhkiG9w0BCRQxTh5MAHsAMwA4ADkARgA0AEMAMQA3AC0AMABC
ADQARgAtADQAOABFADYALQA5ADAARAA1AC0AMwAwAEMAMgA5AEYANAA4ADUAMAAwADUAfTBrBgkr
BgEEAYI3EQExXh5cAE0AaQBjAHIAbwBzAG8AZgB0ACAARQBuAGgAYQBuAGMAZQBkACAAQwByAHkA
cAB0AG8AZwByAGEAcABoAGkAYwAgAFAAcgBvAHYAaQBkAGUAcgAgAHYAMQAuADAwggPXBgkqhkiG
9w0BBwagggPIMIIDxAIBADCCA70GCSqGSIb3DQEHATAcBgoqhkiG9w0BDAEGMA4ECBHBi0p8N2Vx
AgIH0ICCA5A7JaVFBqZTQbSEJhtjKPmwteV230BLhKvw4qfM9vxcBNj8kBZGDJaWYZK5BatuKMu8
xd60lqzoKgUOHrN9etjMCe2h/z/RyyeVpBuEILJUQaj+SuSTSUUTpGKokKVnSQvCAD1UgJGFt/ac
elBlaIw9pRDnDZgFhzZ3AWO09vBz+GcowUlA77W173d6fHf26khicTalsdXbimnMt48/mdtKH9ep
pjgxJwhshPhgKKt5M87nEyaaGSEFfsrPgcIj79poWwj8WE6sAg+bVw3OfX9rvbpP2vWF/e6Vc2x/
QJPChQZs8LqJAUy2lI55gZgv+hTKkkBXoHG0c4248KdyvBT5DCiFufaj/dp1Eja02Qxo+BqZLJS7
EYE1YxB7Ty9CUxWvAt6aRLQ0ZLbrK28mwgCePctczxQa+tcCMCfL/JJvcZtiu5CaHObLzF7Ymbh7
/Q6u1+5u3/Im7aBdY5AksTz2Zn4JjzSAXKTdEgcadjGsxTd/lj4dUOreXN9rUgNyQzjQHpljnhxF
6ZAAbNC8FJwFIAm+ipmV7keCWT8s6MQeoQ5qr5RDhVhGUVM2CWoKRjhbKzWbnKetfmjAUnvn0+ZO
vSKmOShMG8QgyG8trDIH734jTG6u6yoe3Afjw52DtfOo1OVi0ZDsj5GviFDZYQX5Z/86N4Tx7Tol
e/Wz5918nziNoU3+07ZySsRRESuLj6p11sUmFFPj64W/CZ1YQB/H4+R+94uYyWiovHudC/69KnBg
Rfj0XpdSg0l+HKgTez7OuJrEu9/+5QF0M1unJSGxpdojVkACf+bxu2+4czzh80sL/3Yzcenvg/nt
AQGm+sX/K2oF2E0h/22RD4U2txDxORVGcF+wfNUHkl2m+rBkgsUMhECeWGwoI/y5ZBHWWcQP2ByZ
78fa8a9L1RWGvn51yLOe/cPZ0pmYBDZ9aiP1KucGBNMTzHefZiRXscXjB28u7/YxUb7fFPY3RjjO
p2Rm17rrFrvR9/oChO9ZVJrm8p2lQfKufz/t1USs8+gZPS+kLfE3wxZefo1nFmbkTWQT6hW+z4zh
0QoBNwGJVFYxPuGvyOmQ4ksEHe7G8fc7ihkiZ+A9fJROqOjVA/ThnWIuiLKbDFlW1rQbdlihQy7Z
oKbzbA9eOMUCaXMEti5CG/97pOCiElARHDactfiy0J7ykjCGLCkw1/3j5Qdr3feN4GWqOBTfn0cK
eq8RT0pBkT0wOzAfMAcGBSsOAwIaBBRW5H12kY01oB2hnm0lkT0yUbjP4wQUF7tfAlojMdSZIdKB
/FfU1hlVl8YCAgfQ
\ No newline at end of file
MIINqAIBAzCCDWIGCSqGSIb3DQEHAaCCDVMEgg1PMIINSzCCAzgGCSqGSIb3DQEHAaCCAykEggMl
MIIDITCCAx0GCyqGSIb3DQEMCgECoIICsjCCAq4wKAYKKoZIhvcNAQwBAzAaBBQj8/7sNqA6OGwS
O3nBO2jejhMCdgICBAAEggKA+SmvxFl8NlTv9TZf9YTiFOoUfLGNNxX+KaW9Qy+vBtAqU9rIqLeU
Wc7K5ovqYIcOHUYqjMECgfGWKEcT5XQljB9uPXh+L55glggXpJ6ZtgNjwOCGfXak+x2nV5ynIRD8
196Txb3tyGJrEEVvmm5UFMRnFbUiXmwRvV1nBAgAXFCpdv+cowKsY0SS9NIyYujzhObByV70Bd0Y
rOTV6Wvg/Pw/p9FpOskiLSgwxY0Eb+ryAUjMs+DXsH7okVQj5xriWKz2jyRSMvRlxj7qL+SvgTcQ
J+2dB1QO9y34AAP0eTypJhZ2aEZl7PiDJ2QigP7ahm2YCTpGLyR8drrRD4UNWZ6WVt+wp0giTkmd
QHYm/4XVqUDcYbXjOPapfQPDgWEDZdduGS/Lt+ELfeItRP+aPQxBaZoRjfXbUmv96WSbNl4YSEJE
hq3Ri+3xClzXDK08AB1g4ro9kQSMJb/zt5We+X9XLaDl2w4H23/MaMcuBbXb42eLIoSELcBYAlc+
ffoZ/5rXzRfAjVO0Po3qnB6DAa68DTa1goXvQy5C2j/Qf8G4BRKumB9pXm/CxqvQOJ/1tXZR9mMe
D5HALMI8G9Wm1wyf01FNDjNQR+BhDHM6tNNyjvc+ibt91ihtUWjGEPLyaenZbTwu7IwX/NXbGge6
xFhzG/NK1t8IdDCpOz/1u5OrCRuD+wUORDezg0XoU5AOSmXZoj8R/2nps8+u3jglyYWknwlid7B/
z/P3l0mScSHkWhm377flKwd4i2xq8epLmOdzjc3Hv6BJnj/SuLf1Zihlt9fPp17R48D6Diklwoci
pOJb6ktXjhcP9NYryYKC0jJkxONPImhStpS945brpjFYMDMGCSqGSIb3DQEJFDEmHiQAcABrAGMA
cwAxADIAdABlAHMAdABlAG4AZAB1AHMAZQByADEwIQYJKoZIhvcNAQkVMRQEElRpbWUgMTA2NTI4
ODkxODE4MTCCCgsGCSqGSIb3DQEHBqCCCfwwggn4AgEAMIIJ8QYJKoZIhvcNAQcBMCgGCiqGSIb3
DQEMAQYwGgQUQ/DkvP0s9CqcMXsf460GeDOK4AkCAgQAgIIJuHO3HSQsW9lR/QojhuvENOWLWOvW
RPdJsxTnWwAzpEBH3BRiv8zc1tkNs7N+U9CbIZJS6O4qDe5Is3PEQAkbxZeG+4IAAMUqataDtX3J
uZkFMbQEhpWYRfbwVAsM/boTMM2gd49VRj2FvtrplzZqZtkixhg+DqJDqtqeuWonWKjTuRP60CXe
Xj4v3ot9+tuRzSk61Iq3UcmiIH+0fvqdk1s5bVWAIrwfpRqptG6HVcob7gTrYUvL+AuVm68jUtFO
KjRbHL5OcJlnkNUU+dOkjH6eJWQKDPCTzJU/c4lwOJPjd/EuYVKhMfEC/4HoR2hmxeJn6GIosDGx
/R87K80NVQm+IQjXeDdQ/XJKwV+2CjSfJpN/Y6VcCq/74BYODl0OixG7TdsG0igvn2QtVEQyRyeW
f6A9+ZQphhyiZ1ZIGyfEdmgAgSgc1MX5m1xkeSZhKKBm7NMcBu3Ilrx/35drqNb+1mcFCqV6f5su
xnlzTKx96gy/Ug0E/4WbttwD7cCfXbpz58/8hOFDIeTGRbuvCpx+kkXRI0Dm7ifFkwNuV97G72n+
VxzlsYElAF5Ek7bQFbVYTqO0RhpxGkjhCC6qZLfd7pq432sD7j5+VcI1EG0SWu+4GzO2j4wUkACZ
u7k2Kt5dAUAQjH7rk4c6Y+Sv4aCBDraLnyi2fOHPlrhpPI3pGQ2YeV7949Kwz6RElf8cRFN0dQ+y
LamJu4ymgfvcQH/0ui6QKU03knPJJ/VK1DKOMUx75rjCQyNe3fENyo52Q/Q/2KgIHgzDR4OP0j1l
/xmSeeAsWRhFOFm3MPghykgMXe91VgdxgpXKP9MksxC+2B1UjQAXD36E6dn12fpjmRXGuD/CkTGb
trpNX7fIIauYfaXsISrXJQui5cTNSjWdjxZI7k/78IAtTCvhClPMaZ1Ru4sep2x7UylnvMSDO1+L
j1gfAyoCmm0uJyQAHU+9OBiDWZpdMChnol2fmF3JroUOAy/7FF/aOjTpWMKxB6lynS65d7uaclls
2rqzb3ENmHpuYjAe/dCLyn5Jv3WT43+hReMcFOszw0YdkBBOK04/6BlHAm9JV6yoxysORCRrih0n
ut7/p5pU8lSSTkszcmKbw3priHKlHa/A5mxkwHxIsVdQv7NMjR2iGrH/IHXHF4vo3lO3xMbuUl+C
7StCpA61Qgcy1+reuuYp9z+uA4+KGrPDjZbkqIa8UR7PdqIvGh3Wb48OySYWtenW2RF+Wq3rXj8P
98g6XZlB5SUdMNBQry1oaHGKGNorPP4uJkaOy7FiyujaMFPd+WOTBgfcMTishPTZrnA8eF41jAae
rA5qJA383RKxE1iopq255oJwdxt1bDv+ad9cnyY2nh9t26ASuoJ3SyAZrGTqTwaWq1jrx0Z6LnSn
k8Cas4Ig/J/Coqi8A+EibADDPxxJNXixyNwepFlplKsSBlsFFBMvij4dOu56yH21B6lwAmjxeYcD
sFcEuHu9Yjl9XhELiur0WuVUM8FpuPfD/I2KlsG6RjY7vXXuQ6nk19l5ylxFDNV5VweV+DnsfZI/
trQ/o31fLg7Y+KF7OHnNIclxpMiz7t8c4UXwHc2xV1vHDqJ70rHANt+1M3iydQDx+LS69iCbnFG8
kJRQgBR+prhs7dSA98vVdHLYa4/RRwGdzj8jeQ/YVEOOMfayL8EZ9uKbXPsN2ijLsieJHhDHDSmw
6GfikIxh8Q6pPjxmZWEwLh2gaSRX3VEYjFqg2FxAKrnCB21csVXc7bZSmuDOU07AiALfEQSj273F
LVZKa0HBjKzI4DlBMOhGYr3NusZvwk4/AK9Rti1kQl0DLOZ1VoNtBysefs3AyyT6Y2qZCsG3cFWI
TRy9xOrX7bjIjabmDWWWrcWmgu1UyN/5o5Jm0dhXR/6RIqbOWC56ahrHeGAxZfGfEal292nXM66v
/ptu26ap4mixi+hrHkt8gGUO/LkmVqINSDpwfiWiQpbGVYDoKZCKF2cNgK6d3I9EfsOEXmejTROR
86nVj3Uz1otQ50sxVu8zRaH5Kkys9EwVOQPHsqjWY4fkkUAbLFc2Xk+D3pnyZFyBijRjE05Xa2QL
tiOr+PH9tIBMgkn1AIddmg3f/zZIfLHxw0Gj9r8rqqyO+xwdokdzF3n5vq+uDZB+bMqY0UG/aDfa
0amrPqNOM4EKz3xhlpmN/wrVIdpSYshPMwgyWbX1fuHipBgm0Sff3lVq8ejO+VXnqNJ5Pi5NowxQ
4gVyE2OMtU7Ya73Sm1leWSRigI0MpLeVCccu8SxGriUTI0G5w1JSq1sqr6q16aL06/nlU486sQ54
LtU1EGpk6BW5GXvVjEqE+Dee4wEpoKf2UcftZ8TO4ya3BmEWYMBiDLIxWvxV/Ppm3pIBhyH0OfLY
RN1JPAe8CJn4mZ+TIWBVNMWfcSYKKu5Sk2s2sulU7aVRQp+xvuGC4s6EopbDY1XwKdc6cRyVUccA
/KD95goSlXcxux6xA5LnxI81QKCiNmnQk1gwGY1Y6P5igW5s1HVbdbthVc7yI9r60vLth+TQr4ec
AdnLOh6FTYHI+GWzcBDae/TiAU/24PJJfZDMEoZjvqfWni9x7Y50knH8qjnFb84IdLjb0E93+yj9
4nyrKtMp0egVsYA4bblyHL8O54J4aOGtg1CjuT1q/TkcTjd3Hheyu+kYbvFpdbltKjZ/m+Vob63G
fwoB0/JPIZseKLjSMMITogNVezAiHsJV4kYyMOmnbRBLA1OyIiV0gnAnX7KpUXg0DXsDO4H9uxGv
DVm9QyD832m7HbDe7vzJv5nrq0yxSJfxPiinq+5GmQUVwYFYsLwfvkUINF4CTeWvFGumOBTU5YNP
4G2NVbAgkNpBwJhljABNXChChAeesBvQ4fTK5L3WwDcCO4uDEIHlIQvd4QJQa+QWQ39voKIOnjz4
/jGwqFcssy+aXnlI6Ub9UpMkc4vcE3rVB0qanitlSVBszL97PSorJaoddKs+wMBwBiY5RlvRBaFT
EtWbiWfLEeAC4cNkEmDToMZNwE1fS+0ZqSoOYqEjAw2M4HXvmZqqS6bP9zEs9n4qCKaT2dYG6rQB
wpHy0WH9myqcgdY1JILfRpQK6PehDXLUMT8a44Fk9vxULare2dQ3uTTyBqfE+B+ainFQ/QBxP7t+
vsjPxPxxD22eWUT1v4xhT7mzurM83N+AJAaAU2QJ6vYwTGS2NNTDjmm8pMyoLjey0KJKud8isbAC
mqsZHEC0tqOkdVdikLEmcjq5yMl5qZpDYYHrWbth8/5bdRus+UWj7jXOMBW6h43eyKvs4/HEhWEd
KRyvXX7ylBPr+Ow1JYKcg9IwPTAhMAkGBSsOAwIaBQAEFEkDUNCE10mwzwFgzaDBuOaQNXMqBBQA
IsNed5PjTXd1/rQmWIcCDOy9lgICBAA=
\ No newline at end of file
MIIJzgIBAzCCCYgGCSqGSIb3DQEHAaCCCXkEggl1MIIJcTCCA/MGCSqGSIb3DQEHBqCCA+QwggPg
AgEAMIID2QYJKoZIhvcNAQcBMCgGCiqGSIb3DQEMAQYwGgQUAz+z63B0n0UriCxfGp3W/qYiuN4C
AgQAgIIDoH9ARpsBx2g6u9l+FNrXZa7dQZ+z2f2XhmM60HBm4m1eeZtQr2E/Yl4Yck33qT4L6cIp
6cR3cS+pHe1/jlgfP7QaWSDODj6QVU2PUZfL95/9fScYvp2DOWH9PD0qVBJVIZAh7zJb2/CXUXxF
NSSFbTMo3jaTqYHg3I4BIo5CgyN/Nj2bwrcLMBwhk6Le328bT2jApkIMUSfkWb8xTBom3PW72pLc
h7Vwgf5hrxSF29BIwGtzEnbVJMw45oDlsieQM+SICmXUh/uMNn94Z+17S0DDHZNwg//dRevbY7iF
IPSiNphFeiD3qEX+4GvZO8g3esbxUmbN7yssJ3WftOlfcAgMZClEYjXbtEnGtvFEOTIWCUuCIs5B
UgOO0ySzoXdwZx7tHfYqmkSK6APvzvUUro0ynwz4TlEL4M/+O4e/JaOKuv/O7g43wVZohS0GDu9a
S98ri5aEKm3+evPbnxclbsrGzoym7tOWCaq2RIKfbJB/ARJuIWUGWVr5LHw/ovANgGIFs0+Sla0g
sJMR06OoS+PFvvPBUoW2bEUXOf9ugposQuHIDuw8V3EP1yGuOYGTM7IZSf5cbKZ/2NAQe/oc8hkI
VqcJeYFCRwcFqacPJDa2IUaX0ZhR6WwGorzXPn3i9YDgTo55+WqOjujGlVnRW2aP6E3JbwJh3q0x
hHIlvg6rVa6MgqKFl8/mNEQPvUMiNojmo1GT1xQ6KhsIzJQee7ZyLFBg6pJU7aN5hxh6J32Y3SBd
VAauKllwSZ05jR0U+WYFF3NfTR3UgqSvtyKfLEWo4GFhEKpp5NwCTtTPHBs7Qt/CTr3QyNZ8ciRW
LpmXRIDe8UGschK30QNr1wh9DrK4LU0Rsl7oYhFUDEGE3dxIqgUifb0X5IpX4kjpK7NODmO3iUr3
IT77Mukk8LJk2pfCyerPh9NdXS4fN1r1coTWcNwXt+FF5pzC8Jw0goV8TWCk4izmpmroi64UKfam
h/4/dt+fZLRpP8joBMxXmyvPRECtTF2Osz6WxOenRnqT8CdqxOITwsuypk1ZZqIc1zbQc53ddmOQ
IWZp3EopTM6NUem4J70yiZS24Eve4UsyrkzINvKTiuGGWbiAAgJlegi7YDmkbH8nsNvDtMRgvst3
uYXazCGii7CJSNFrOSKebi1LPxISJmYWzuqiS3b/VO5VkRp0w21n+Yh4gOTsn8tTkZoWV9kOuZzt
odHgt47FwoprVX0bwJ5jk29fWsw2z9UwggV2BgkqhkiG9w0BBwGgggVnBIIFYzCCBV8wggVbBgsq
hkiG9w0BDAoBAqCCBPowggT2MCgGCiqGSIb3DQEMAQMwGgQUEyyUrMkExJyP55CaARyqFL7stccC
AgQABIIEyFyuDycIN0LU8HtRhDr3dbX0+fkXmgPAHX4CyJTS8YzV5U4r6knRH2EFx/EbJq2/ql82
OfXFg2BBvnlDdf9H1XVq6e3yr6exxRyOc6xSQiKWU1RpF8AsYIpiYfYd3MErRK/Qp2OnPAU++5S3
wog/Qda0a5tRSrxs/1M6Ts5aBDaO4YiQIu/J9VaU+FMWx8F0UmeEfm21DNUgrTQxzdB6m0dHGcXE
XHiba7VT4t4f0qPuBBji8tHziipvCer4m6KQJxPN0UhheJvhsqO9AQHSrUXeKkHBzhqojP5gPc5f
HJMGhi5zIVUgBtA9PRB/IEUZ02TFOLoMu5pTRGrVSoSjvJTDhjrutV9w1v6ILyJiqAUA1Acza9Lg
stVAA/sALJhHDXn6HcQqyT9vIG+GhswOvRWnxnDHHxTbK9dy2RyhpBgGkBA07pqmB1pOyPvoJHfj
Ix9fi2g7K1bdgERYehSfWoDPt9joYnWfg2TtpYduDD5hnJA3bqb3+pARFKe8G/4Y7WCILQKCFvQB
p48a5sq+Dd5dWlyhUNr5fxZPsVpaMa5nA/iFog/ILocBsGmCkOA/fXeO5uzTX/ze+BohE+d2Y5rp
//LZyvfxSIM90odzUNRvKowbRHKx1tKReOKXLE9UkwFCraMOXqX4DhFbuiXvLYjqs45mbfZodQ96
J+lJvPvS0w1xl7okRhvD8E5sUATgIeIAapU7sSZLfsYXoSFndNBgUfZ+7bm574sM6y2tC3Fd2Ytt
jw3/avfk3V0L4ddAfpYMCK1vJSgNiGdAwPOe8ieihn/kg3pY6glQXkXKHZHVIwg4MlGHfw7KBqry
W2rnh9TwdxUC8Z8CzEaT/8fKxYkF9ZJa8bCP5l4vyKOYdy+m4WZMb5hwZ9GxHodcuDzagRvQ5RZd
VwC1SQwXO6ad34eSizBZmHVeYJCA6JrixBRbtXfA6frk8nmKvqSO8WxM0ma+2MBS40wLvWWAPs7y
P2xKKOJJpUuNlDeRTtSbogUnB40KO5IYLqzad9LlU9V5dfluZ3GgI4fWBNZa2ykK2Q77jVTda2a5
kgiK+/OQYZuLo3gO+3Y5zAxEZ91gqibI9yRv4/XiyxGSiOBY+EUmJLTw8R9j9BJLrMckf22BUYNm
wpcHZVILWmBi7L45loni7DGvsxzibLNMn1NHL6zWZHYHEayI/HqfrRRhadPnizvTwkZOF9XYOrlv
BdVcQuhyigPbOlpplLzJQ5DPmnet216FSVk4nn82CvWZr02RlRP426elooMhABVnKgFhGWH1VtuW
ewja9X+/wznDyP0yzmPldwKn7w1UXkCwI3AdBhzDlkwOAMU1QqunDXnchDvwg0BGR8M23obINGiH
6JwQ/iWl6nUG7EVSqJcZvWnz1jQO0tCgr30YBl31jZ584bW743vANF3tFFo4bacdJlOqGkb7rNdj
KxoGE2XLyVd2rzjdLrcnr4ViwrJRZl+1XB62DVH7cr5+86lF1V7/2UJR3XzjdLV5SfSoBzexLxiA
1gPov8RE8UnVbqhZbqeaR+tQkoeuZy8vyP545+brD1BkV+b2QGJaGMP2DDJC74CpVITyiVm4C08u
2ay6G+tblKuBOVM70xBmbiwq8inFiBd3vl7aObMyj1AgPjFOMCcGCSqGSIb3DQEJFDEaHhgAcABr
AGMAcwAxADIAdABlAHMAdABjAGEwIwYJKoZIhvcNAQkVMRYEFAxeTobq6DehjSbiylxISkcqQqH6
MD0wITAJBgUrDgMCGgUABBR8ZwGkxtDxkXoUy1JndD2dkf+Q5wQUlDj7Q1RzRmooVNZ+0cEv+M/q
I6oCAgQA
\ No newline at end of file
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
\ No newline at end of file
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
0AQQxrOtDDKIzjpW4+rATcwNPAAA
\ No newline at end of file
MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZIhvcNAQcBBAGgBAGA
BAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCBVoEAQQEAQEEATAEAQQEAQMEA4IFVgQBBAQBAQQBBgQB
BAQBAQQBCwQBBAQBCwQLKoZIhvcNAQwKAQIEAQQEAQEEAaAEAQQEAQMEA4IE9QQBBAQBAQQBMAQB
BAQBAwQDggTxBAEEBAEBBAEwBAEEBAEBBAEjBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoqhkiG
9w0BDAEDBAEEBAEXBBcwFQQQ6T2lKjQK0wo/cjrjNyb0CwIBAQQBBAQBAQQBBAQBBAQBAwQDggTI
BAEEBAOCBMgEggTIiZ+WxZhkj+CjQo4+eTTGf/tSoJMtp85VFwcFUy2+Bz2+WIOf7abQ3yVRmkSc
MUeb/1vQDS+NXMimZDLoIIN9M1ql3Mq5Qtr++kURQeZAVh9q2ZJNDAmw2rvAWGJxdbqPrMA2WgQc
oGZVLiN2eIdWXxJkjLdNzjMWtpsh+6Yw52lwq8ZEIKgu7v23my8+HCemGCL87wf7qU0nQjq+I5jf
QZujYJL5iDNvosZLFLzBuOZKG7voDY2gJtbl+yiOUMOPBQYdDE8qiF+eHqu8WZ/JwlA/3EtnuIDz
i/9f9mIHMINC5vpvPXuo9TE0nF9PvxtL8mGmRcxG0vVro0sPEzu1f13OsN4qwDUVWJ6Xr154zkU8
9wMi8SAY+gbETvbZZQpxgHWsaEjG9r7fCjiLE/x+5VZCaPeNK8zB+cb0Z2wPGPlojV6Ggcqt/7dI
pZtRMyeSNpSCTncgZlBwh6JLKRCLFSEjZhGzKIsCjT9TpU+IzoD9Niue1cWo2ciZIuTMaSwnqYhO
KzJ/Wivqx9tjhEVI9cCuLf/JPpmFvsmrdMurjD6s4WQPMc7prK8aMJy5W3vcN32wuEQyR6KcqhDn
QxsX7KPavuIi3dTe8I4pNaMJlZ3Ubif4qvt5qJe6I3rxuie2Q1ux7clXk99W5ZvU06tCYTv/3GP4
M3TjupaWAtmgWZRLsjbTW2NBnxVP40o0AthzYCElyrqhlQPTRU/p1y3RPXyVyssZXwCtvQJe4cxb
V38+kjVSrYL+WGjVkuCQAs4KSdmsH97ShclgAAsrqhDi4+DNhaVIuoFMhkwp4DngxiWMNHWYMjAC
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
AoiyQ6u3imI281gAAA==
\ No newline at end of file
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
\ No newline at end of file
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
HwQQ6Vxq63yfCeamza5PZKytWQAA
\ No newline at end of file
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
LK2fdlxrCGzUHTgAAA==
\ No newline at end of file
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
\ No newline at end of file
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
\ No newline at end of file
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
VL+NWQOgtME=
\ No newline at end of file
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
fAQEFPL7KYm4NrHpQSKpto5+pPs7NgLWAgIEAA==
-----BEGIN CERTIFICATE-----
MIID7DCCAtSgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJJTjEL
MAkGA1UECAwCS0ExDDAKBgNVBAcMA2JscjEPMA0GA1UECgwGT3JhY2xlMQ0wCwYD
VQQLDARKYXZhMQ0wCwYDVQQDDARMZWFkMB4XDTE1MDUyODAzNDMwN1oXDTI1MDUy
NTAzNDMwN1owSzELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQ8wDQYDVQQKDAZP
cmFjbGUxDTALBgNVBAsMBEphdmExDzANBgNVBAMMBk1lbWJlcjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAMr07JoRV0kR5mNKgLFKLYeUQ2eFEyV8alkC
3OL2Ew9tP9CT+60kqlbyLfxa8+8XU/SClch6yf7R4majR85PgfJuZKRvyUdWgw5y
K0wbxWkRVqRAgSo0Zp8hkhV9BDe1R7s4r4XBI/rSVTQmDsMVZdigDtIDYKMS0BtW
DnW4ueWbZHdNHyxlTEJc6trsvU2KH5pY69VgGZzonNuMa9p17aQpOnVbWNhS6Mcs
mHonU5d19Xh543T8ovbA8cj0osdYgcOQ42FEBqON4Lih8SyhqZQyi4UvkiHek3Pu
i5Q0dwwVT1lnorUwH3bXp4boMaUmh7bvKMe/BQ5T18wkXlgYuVECAwEAAaOBzjCB
yzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUWDsl+9vHtuuQRhb+Zyd//f6qSXEwcQYDVR0j
BGowaKFbpFkwVzELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMQwwCgYDVQQHDANi
bHIxDzANBgNVBAoMBk9yYWNsZTENMAsGA1UECwwESmF2YTENMAsGA1UEAwwETGVh
ZIIJAIQbGsfQ2qikMA0GCSqGSIb3DQEBCwUAA4IBAQABEg/vV+ckqMwwA6QLdk6i
Q+oaYcjz2C7wcZmvmrdYGHUrtlf4aWQd4G/TDBtqKZ6MfA2AaciDe7lAI2agdKCM
MFG6XeqtjElCa77b8KrE3Ha+N07pmYnU42vZrqMpayjj/Eey9bOuSaTgLVTA00BI
5wiTbLokTrYW3lhMityeFyvGw7bEvfGbXLs/7hyZ6wEXindgaGT9adL9jz2LT2Tt
YorRvxRSRMbBWCc6o+ICfawU226ZOetGVfdTSYgL3a9AQ+zAMhgdJq+ac077G1vA
HzKZgygYAHIr1G0DxwEPOAHBQFtbTbAQURpjzKWFYeGiZuCEBwwsKgDIT0kGF76E
-----END CERTIFICATE-----
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
qHeo0noP26ViWalg3FeT8Lk+AgIEAA==
-----BEGIN CERTIFICATE-----
MIICRTCCAa6gAwIBAgIEFjfyzjANBgkqhkiG9w0BAQQFADBWMQswCQYDVQQGEwJV
UzEPMA0GA1UEChMGT3JhY2xlMRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxHzAdBgNV
BAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2VyIDEwHhcNMTUwNTI3MDUyMTUyWhcNMzUw
MjExMDUyMTUyWjBWMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGT3JhY2xlMRUwEwYD
VQQLEwxTZWN1cml0eSBTUUUxHzAdBgNVBAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2Vy
IDEwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAUPl3dSLSQd+ocj4oDJI6qdt+
iIamUd6aDHllX/vNfguuX5G1/NO/aas5XofV9Zfy+XCdqGI/rUE294vod1BkBOiP
UmsgHl30nWCwEq5FuFWLwLWgm2DkNMGVJnvvCVLDzuYhvkymNbOoppHywIMVAryP
Xi2082vRKvW677VqcT0CAwEAAaMhMB8wHQYDVR0OBBYEFLpLVS5KZoGIDGmden5r
AK3/D9+5MA0GCSqGSIb3DQEBBAUAA4GBAEomR40Sj+BvNYiL8Lfr2vMadCF23R3X
fjPd3TCGuMJtI78N9lSTnrZCnrxn4ep7FuVl59jqEX7mBQcVtUNPqw/xrFI/sv4z
Nwxa18TG78i85OXapvVsX1fWx0GeeK2XTKetHLMEc8zcW8IHcukSX+5Z6Y/pg+lB
mqEx9bvLCJTW
-----END CERTIFICATE-----
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
-----BEGIN CERTIFICATE-----
MIICRTCCAa6gAwIBAgIEL8ZaXTANBgkqhkiG9w0BAQQFADBWMQswCQYDVQQGEwJV
UzEPMA0GA1UEChMGT3JhY2xlMRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxHzAdBgNV
BAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2VyIDEwHhcNMTUwNTI3MDUzNTI1WhcNMzUw
MjExMDUzNTI1WjBWMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGT3JhY2xlMRUwEwYD
VQQLEwxTZWN1cml0eSBTUUUxHzAdBgNVBAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2Vy
IDEwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGARub+B5xAEtoE2Sv9+oRnKYIC
AZZ5dpTdMUWiExsXBcK6KQ61X5GftMz4a5io7PoxJxsDkPyTPNaHov2dzOBblbn2
Gd0YgRdI3jcmm6ELDN7CqzsO7FK48L8maLeIj/0hYPBZPxKohjChi2GUNKn97OMf
Y0LTeDqpO6+oc2E25XECAwEAAaMhMB8wHQYDVR0OBBYEFLC2ChLxDu/yacB3s0ON
NNDusz2SMA0GCSqGSIb3DQEBBAUAA4GBADhG2wSf4KHMspsKv8bkjWrDA6wTjwnx
pQES8E2dMmmp/LybH0CerpcShGGw35uh8wnCaWA1hBgMAs1mfghTt9X8tZCG5MmA
VmkR7VPu1lNbdB1sswXAy3/423ncWbPJKIvbXBLJrzvC3Ri6d/AiH/0Tud0H15IN
YQ+ThBRF5iQC
-----END CERTIFICATE-----
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
-----BEGIN CERTIFICATE-----
MIICRTCCAa6gAwIBAgIECrE+nTANBgkqhkiG9w0BAQQFADBWMQswCQYDVQQGEwJV
UzEPMA0GA1UEChMGT3JhY2xlMRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxHzAdBgNV
BAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2VyIDEwHhcNMTUwNTI3MDUzMDEyWhcNMzUw
MjExMDUzMDEyWjBWMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGT3JhY2xlMRUwEwYD
VQQLEwxTZWN1cml0eSBTUUUxHzAdBgNVBAMTFlBLQ1MxMiBUZXN0IEVuZCBVc2Vy
IDEwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAUJKwuZJOuG+EZ9d8L4BDYOzv
2sFCyCTrDbw6lH/vaG/kkhJgZdYMV1pwqxmsspUrSYwATx3usPElv+OOjEJlwuLo
wj+/6Ob9LirwUAHb9LbcF5r9dRxLBcFUaTnDlqzgOuS1gn9dnD9z4CugId9t9IjF
tLiump5zXNcZw/+/JKMCAwEAAaMhMB8wHQYDVR0OBBYEFOKLf8ckktSBUTDRoYxV
b56vtgd8MA0GCSqGSIb3DQEBBAUAA4GBACgrbEqfqtgKx0iLiQEgKb4K+O4Gg8Td
wuSjtXn9WQR5Fux7XNoM8f3xRw95CROg1/JEYhsH7fzeG/Aq6BbFooyHZsQ7yGXJ
ujJ3O7hl0MuFZRChf9QP7YQjYb4toj1wdE0EvA9lNWomr2Ox9b3+QFTdxPcBElv6
+ImhOPtF6/lt
-----END CERTIFICATE-----
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
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIBAzANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJJTjEL
MAkGA1UECAwCS0ExDzANBgNVBAoMBk9yYWNsZTENMAsGA1UECwwESmF2YTEQMA4G
A1UEAwwHQ2xpZW50MTAeFw0xNTA1MjYyMjE3MThaFw0yNTA1MjMyMjE3MThaMEwx
CzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEPMA0GA1UECgwGT3JhY2xlMQ0wCwYD
VQQLDARKYXZhMRAwDgYDVQQDDAdDbGllbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA2HADVMaKPd7xAYK0BTsCcQzglk8H2qp0Sg5nDYgb7KqB/1cb
RyMB3g3FG4Isv6L0Lp2GLAeHVn35YljHNrcBUU5fG/+DNJPNiM+srevblMeksOcA
frPnxmog+GMgiO97O2/3Xtgl0ailsOHidPH9hBXr+WikNu7ITPXkJiYi0d1n8p2N
e/p4W4cBitxIUlZm2OTSW4d3EDW86saf657kSpTlb2zBT/r9fjWluHlTg+jGnGIz
UdpYP7sSnye8oym5PxT2IMPU6vRgF9Gzwg+6bPaZnrYNURifGJIuQH+/wDaqA+Ix
g2Q2Ij8SiDhkNrCoeLf77Aot9d5ZPtledJPSRQIDAQABo3sweTAJBgNVHRMEAjAA
MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
BgNVHQ4EFgQUhxNmvHpNjpjnl/vMVkEnyF5Msk0wHwYDVR0jBBgwFoAUHyFP2xAx
0GeDCQPTzfxG7M8di7QwDQYJKoZIhvcNAQELBQADggEBAD4rXzKq8PdSK7rzuwfu
q+RzeYZnNM7OsoBGhMfHQKnnI3LH5bgyttuCoV665X2mgy6+LZcrXqom/ZrLXQ6x
JVtGxNHr7rqbnC/9tB2/s9HHN3YiRs966shWHGkhCubsUGre7Z25Pq55K6Pyl+nU
hb+K8aQ54z4oDt+raAdbuILq91fUjw5j1qex3d62fHvf4IO3spcKY4HhnwBPifg2
YZCiZRZOoVysi2FTdsvW2NfQCYgtUftbkfNrKglkRuIa9rQEduhDy1cwn4fc9S1f
6WTvuJNoIp3o1nQppFjfO7fzfIDCrlaEkkXU7O54KQ5HTKu62tZp9xKW71oolOnZ
bZQ=
-----END CERTIFICATE-----
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Random;
import static java.lang.System.out;
/**
* @test
* @bug 8050370
* @summary MessageDigest tests with DigestIOStream
* @author Kevin Liu
*/
enum ReadModel {
READ, BUFFER_READ, MIX_READ
}
public class TestDigestIOStream {
private static final int[] DATA_LEN_ARRAY = {
1, 50, 2500, 125000, 6250000
};
private static final String[] ALGORITHM_ARRAY = {
"MD2", "MD5", "SHA1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"
};
private static byte[] data;
private static MessageDigest md = null;
public static void main(String argv[]) throws Exception {
TestDigestIOStream test = new TestDigestIOStream();
test.run();
}
public void run() throws Exception {
for (String algorithm: ALGORITHM_ARRAY) {
md = MessageDigest.getInstance(algorithm);
for (int length: DATA_LEN_ARRAY) {
Random rdm = new Random();
data = new byte[length];
rdm.nextBytes(data);
if (!testMDChange(algorithm, length)) {
throw new RuntimeException("testMDChange failed at:"
+ algorithm + "/" + length);
}
if (!testMDShare(algorithm, length)) {
throw new RuntimeException("testMDShare failed at:"
+ algorithm + "/" + length);
}
for (ReadModel readModel: ReadModel.values()) {
// test Digest function when digest switch on
if (!testDigestOnOff(algorithm, readModel, true, length)) {
throw new RuntimeException("testDigestOn failed at:"
+ algorithm + "/" + length + "/" + readModel);
}
// test Digest function when digest switch off
if (!testDigestOnOff(algorithm, readModel, false, length)) {
throw new RuntimeException("testDigestOff failed at:"
+ algorithm + "/" + length + "/" + readModel);
}
}
}
}
int testNumber = ALGORITHM_ARRAY.length * ReadModel.values().length
* DATA_LEN_ARRAY.length * 2 + ALGORITHM_ARRAY.length
* DATA_LEN_ARRAY.length * 2;
out.println("All " + testNumber + " Tests Passed");
}
/**
* Test DigestInputStream and DigestOutputStream digest function when digest
* set on and off
*
* @param algo
* Message Digest algorithm
* @param readModel
* which read method used(READ, BUFFER_READ, MIX_READ)
* @param on
* digest switch(on and off)
* @param dataLength
* plain test data length.
* @exception Exception
* throw unexpected exception
*/
public boolean testDigestOnOff(String algo, ReadModel readModel,
boolean on, int dataLength) throws Exception {
// Generate the DigestInputStream/DigestOutputStream object
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
DigestInputStream dis = new DigestInputStream(bais,
MessageDigest.getInstance(algo));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DigestOutputStream dos = new DigestOutputStream(baos,
MessageDigest.getInstance(algo));
ByteArrayOutputStream baOut = new ByteArrayOutputStream();) {
// Perform the update using all available/possible update methods
int k = 0;
byte[] buffer = new byte[5];
boolean enDigest = true;
// Make sure the digest function is on (default)
dis.on(enDigest);
dos.on(enDigest);
switch (readModel) {
case READ: // use only read()
while ((k = dis.read()) != -1) {
if (on) {
dos.write(k);
} else {
dos.write(k);
if (enDigest) {
baOut.write(k);
}
enDigest = !enDigest;
dos.on(enDigest);
dis.on(enDigest);
}
}
break;
case BUFFER_READ: // use only read(byte[], int, int)
while ((k = dis.read(buffer, 0, buffer.length)) != -1) {
if (on) {
dos.write(buffer, 0, k);
} else {
dos.write(buffer, 0, k);
if (enDigest) {
baOut.write(buffer, 0, k);
}
enDigest = !enDigest;
dis.on(enDigest);
dos.on(enDigest);
}
}
break;
case MIX_READ: // use both read() and read(byte[], int, int)
while ((k = dis.read()) != -1) {
if (on) {
dos.write(k);
if ((k = dis.read(buffer, 0, buffer.length)) != -1) {
dos.write(buffer, 0, k);
}
} else {
dos.write(k);
if (enDigest) {
baOut.write(k);
}
enDigest = !enDigest;
dis.on(enDigest);
dos.on(enDigest);
if ((k = dis.read(buffer, 0, buffer.length)) != -1) {
dos.write(buffer, 0, k);
if (enDigest) {
baOut.write(buffer, 0, k);
}
enDigest = !enDigest;
dis.on(enDigest);
dos.on(enDigest);
}
}
}
break;
default:
out.println("ERROR: Invalid read/write combination choice!");
return false;
}
// Get the output and the "correct" digest values
byte[] output1 = dis.getMessageDigest().digest();
byte[] output2 = dos.getMessageDigest().digest();
byte[] standard;
if (on) {
standard = md.digest(data);
} else {
byte[] dataDigested = baOut.toByteArray();
standard = md.digest(dataDigested);
}
// Compare the output byte array value to the input data
if (!MessageDigest.isEqual(data, baos.toByteArray())) {
out.println("ERROR of " + readModel
+ ": output and input data unexpectedly changed");
return false;
}
// Compare generated digest values
if (!MessageDigest.isEqual(output1, standard)
|| !MessageDigest.isEqual(output2, standard)) {
out.println("ERROR" + readModel
+ ": generated digest data unexpectedly changed");
return false;
}
return true;
} catch (Exception ex) {
out.println("testDigestOnOff failed at:" + algo + "/" + readModel
+ "/" + dataLength + " with unexpected exception");
throw ex;
}
}
/**
* Test DigestInputStream and DigestOutputStream digest function when Swap
* the message digest engines between DigestIn/OutputStream
*
* @param algo
* Message Digest algorithm
* @param dataLength
* plain test data length.
* @exception Exception
* throw unexpected exception
*/
public boolean testMDChange(String algo, int dataLength) throws Exception {
// Generate the DigestInputStream/DigestOutputStream object
MessageDigest mdIn = MessageDigest.getInstance(algo);
MessageDigest mdOut = MessageDigest.getInstance(algo);
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
DigestInputStream dis = new DigestInputStream(bais, mdIn);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DigestOutputStream dos = new DigestOutputStream(baos, mdOut);) {
// Perform the update using all available/possible update methods
int k = 0;
byte[] buffer = new byte[10];
// use both read() and read(byte[], int, int)
while ((k = dis.read()) != -1) {
dos.write(k);
if ((k = dis.read(buffer, 0, buffer.length)) != -1) {
dos.write(buffer, 0, k);
}
// Swap the message digest engines between
// DigestIn/OutputStream objects
dis.setMessageDigest(mdOut);
dos.setMessageDigest(mdIn);
mdIn = dis.getMessageDigest();
mdOut = dos.getMessageDigest();
}
// Get the output and the "correct" digest values
byte[] output1 = mdIn.digest();
byte[] output2 = mdOut.digest();
byte[] standard = md.digest(data);
// Compare generated digest values
return MessageDigest.isEqual(output1, standard)
&& MessageDigest.isEqual(output2, standard);
} catch (Exception ex) {
out.println("testMDChange failed at:" + algo + "/" + dataLength
+ " with unexpected exception");
throw ex;
}
}
/**
* Test DigestInputStream and DigestOutputStream digest function when use
* same message digest object.
*
* @param algo
* Message Digest algorithm
* @param dataLength
* plain test data length.
* @exception Exception
* throw unexpected exception
*/
public boolean testMDShare(String algo, int dataLength) throws Exception {
MessageDigest mdCommon = MessageDigest.getInstance(algo);
// Generate the DigestInputStream/DigestOutputStream object
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
DigestInputStream dis = new DigestInputStream(bais, mdCommon);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DigestOutputStream dos = new DigestOutputStream(baos, mdCommon);) {
// Perform the update using all available/possible update methods
int k = 0;
byte[] buffer = new byte[10];
// use both read() and read(byte[], int, int)
while (k < data.length) {
int len = dis.read(buffer, 0, buffer.length);
if (len != -1) {
k += len;
if (k < data.length) {
dos.write(data[k]);
k++;
dis.skip(1);
}
}
}
// Get the output and the "correct" digest values
byte[] output = mdCommon.digest();
byte[] standard = md.digest(data);
// Compare generated digest values
return MessageDigest.isEqual(output, standard);
} catch (Exception ex) {
out.println("TestMDShare failed at:" + algo + "/" + dataLength
+ " with unexpected exception");
throw ex;
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import jdk.testlibrary.ProcessTools;
/**
* @test
* @bug 8048360
* @summary test policy entry with signedBy alias
* @library /lib/testlibrary
* @run main/othervm SignedJarTest
*/
public class SignedJarTest {
private static final String FS = File.separator;
private static final String JAVA_HOME = System.getProperty("test.jdk");
private static final String TESTCLASSES = System.getProperty("test.classes", "");
private static final String TESTSRC = System.getProperty("test.src", "");
private static final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
private static final String JAR = JAVA_HOME + FS + "bin" + FS + "jar";
private static final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
private static final String PASSWORD = "password";
private static final String PWDFILE = "keypass";
private static final String POLICY1 = "SignedJarTest_1.policy";
private static final String POLICY2 = "SignedJarTest_2.policy";
private static final String KEYSTORE1 = "both.jks";
private static final String KEYSTORE2 = "first.jks";
public static void main(String args[]) throws Throwable {
//copy PrivilegeTest.class, policy files and keystore password file into current direcotry
Files.copy(Paths.get(TESTCLASSES, "PrivilegeTest.class"), Paths.get("PrivilegeTest.class"));
Files.copy(Paths.get(TESTSRC, POLICY1), Paths.get(POLICY1));
Files.copy(Paths.get(TESTSRC, POLICY2), Paths.get(POLICY2));
Files.copy(Paths.get(TESTSRC, PWDFILE), Paths.get(PWDFILE));
//create Jar file
ProcessTools.executeCommand(JAR, "-cvf", "test.jar", "PrivilegeTest.class");
//Creating first key , keystore both.jks
ProcessTools.executeCommand(KEYTOOL,
"-genkey",
"-alias", "first",
"-keystore", KEYSTORE1,
"-keypass", PASSWORD,
"-dname", "cn=First",
"-storepass", PASSWORD
).shouldHaveExitValue(0);
//Creating Second key, keystore both.jks
ProcessTools.executeCommand(KEYTOOL,
"-genkey",
// "-storetype","JKS",
"-alias", "second",
"-keystore", KEYSTORE1,
"-keypass", PASSWORD,
"-dname", "cn=Second",
"-storepass", PASSWORD
).shouldHaveExitValue(0);
//copy both.jks to first.jks, remove second Keypair from first.jks
Files.copy(Paths.get(KEYSTORE1), Paths.get(KEYSTORE2));
ProcessTools.executeCommand(KEYTOOL,
"-delete",
"-keystore", KEYSTORE2,
"-alias", "second",
"-storepass", PASSWORD
).shouldHaveExitValue(0);
//sign jar with first key, first.jar is only signed by first signer
ProcessTools.executeCommand(JARSIGNER,
"-keystore", KEYSTORE1,
"-storepass", PASSWORD,
"-keypass", PASSWORD,
"-signedjar", "first.jar", "test.jar",
"first").shouldHaveExitValue(0);
//sign jar with second key, both.jar is signed by first and second signer
ProcessTools.executeCommand(JARSIGNER,
"-keystore", KEYSTORE1,
"-storepass", PASSWORD,
"-keypass", PASSWORD,
"-signedjar", "both.jar", "first.jar",
"second").shouldHaveExitValue(0);
//test case 1
//setIO permission granted to code that was signed by first signer
//setFactory permission granted to code that was signed by second signer
//Keystore that contains both first and second keypairs
//code was singed by first signer
//Expect AccessControlException for setFactory permission
System.out.println("Test Case 1");
//copy policy file into current directory
String[] cmd = constructCMD("first.jar", POLICY1, "false", "true");
ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
//test case 2, test with both.jar
//setIO permission granted to code that was signed by first signer
//setFactory permission granted to code that was signed by second signer
//Keystore that contains both first and second keypairs
//code was singed by first signer and second signer
//Expect no AccessControlException
System.out.println("Test Case 2");
cmd = constructCMD("both.jar", POLICY1, "false", "false");
ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
//test case 3
//setIO permission granted to code that was signed by first signer
//setFactory permission granted to code that was signed by second signer
//Keystore that contains only first keypairs
//code was singed by first signer and second signer
//Expect AccessControlException for setFactory permission
System.out.println("Test Case 3");
cmd = constructCMD("both.jar", POLICY2, "false", "true");
ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
}
private static String[] constructCMD(String classpath, String policy, String arg1, String arg2) {
String[] cmd = {
"-classpath", classpath,
"-Djava.security.manager",
"-Djava.security.policy=" + policy,
"PrivilegeTest",
arg1, arg2};
return cmd;
}
}
class PrivilegeTest {
private static final Permission PERM1 = new RuntimePermission("setIO");
private static final Permission PERM2 = new RuntimePermission("setFactory");
public static void main(String args[]) {
boolean expectException1 = Boolean.parseBoolean(args[0]);
boolean expectException2 = Boolean.parseBoolean(args[1]);
test(PERM1, expectException1);
test(PERM2, expectException2);
}
public static void test(Permission perm, boolean expectException) {
boolean getException = (Boolean) AccessController.doPrivileged((PrivilegedAction) () -> {
try {
AccessController.checkPermission(perm);
return (Boolean) false;
} catch (AccessControlException ex) {
return (Boolean) true;
}
});
if (expectException ^ getException) {
String message = "Check Permission :" + perm + "\n ExpectException = "
+ expectException + "\n getException = " + getException;
throw new RuntimeException(message);
}
}
}
keystore "file:both.jks";
keystorePasswordURL "file:keypass";
grant signedBy "first" {
permission java.lang.RuntimePermission "setIO";
};
grant signedBy "second" {
permission java.lang.RuntimePermission "setFactory";
};
keystore "file:first.jks";
keystorePasswordURL "file:keypass";
grant signedBy "first" {
permission java.lang.RuntimePermission "setIO";
};
grant signedBy "second" {
permission java.lang.RuntimePermission "setFactory";
};
...@@ -34,6 +34,7 @@ import static java.lang.System.out; ...@@ -34,6 +34,7 @@ import static java.lang.System.out;
* @test * @test
* @bug 8048607 * @bug 8048607
* @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java * @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java
* @run main TestKGParity
* @summary Test key generation of DES and DESEDE * @summary Test key generation of DES and DESEDE
*/ */
public class TestKGParity { public class TestKGParity {
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NullCipher;
import javax.crypto.SealedObject;
/*
* @test
* @bug 8048624
* @summary This test instantiate a NullCipher, seal and unseal a String
* object using the SealedObject with the initialized NullCipher,
* and then compare the String content.
*/
public class TestSealedObjectNull {
private static final String SEAL_STR = "Any String!@#$%^";
public static void main(String[] args) throws IOException,
IllegalBlockSizeException, ClassNotFoundException,
BadPaddingException {
Cipher nullCipher = new NullCipher();
// Seal
SealedObject so = new SealedObject(SEAL_STR, nullCipher);
// Unseal and compare
if (!(SEAL_STR.equals(so.getObject(nullCipher)))) {
throw new RuntimeException("Unseal and compare failed.");
}
System.out.println("Test passed.");
}
}
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.PBEKeySpec;
import javax.security.auth.DestroyFailedException;
import static java.lang.System.out;
/*
* @test
* @bug 8048820
* @summary The test verifies if the SecretKeyFactory.translateKey() method
* works as expected for the PBKDF2 algorithms.
*/
public class PBKDF2TranslateTest {
private static final String PASS_PHRASE = "some hidden string";
private static final int ITERATION_COUNT = 1000;
private static final int KEY_SIZE = 128;
private static final String[] TEST_ALGOS = { "PBKDF2WithHmacSHA1",
"PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256",
"PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512" };
private final String algoForTest;
public static void main(String[] args) throws Exception {
for (String algo : TEST_ALGOS) {
PBKDF2TranslateTest theTest = new PBKDF2TranslateTest(algo);
byte[] salt = new byte[8];
new Random().nextBytes(salt);
theTest.testMyOwnSecretKey(salt);
theTest.generateAndTranslateKey(salt);
theTest.translateSpoiledKey(salt);
}
}
public PBKDF2TranslateTest(String algo) {
algoForTest = algo;
}
/**
* The test case scenario implemented in the method: - derive PBKDF2 key
* using the given algorithm; - translate the key - check if the translated
* and original keys have the same key value.
*
*/
public void generateAndTranslateKey(byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeyException {
// derive PBKDF2 key
SecretKey key1 = getSecretKeyForPBKDF2(algoForTest, salt);
// translate key
SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest);
SecretKey key2 = skf.translateKey(key1);
// Check if it still the same after translation
if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
System.out.println("Key1=" + new String(key1.getEncoded())
+ " key2=" + new String(key2.getEncoded()) + " salt="
+ new String(salt));
throw new RuntimeException(
"generateAndTranslateKey test case failed: the key1 and"
+ " key2 values in its primary encoding format are"
+ " not the same for " + algoForTest
+ " algorithm.");
}
}
/**
* The test case scenario implemented in the method: - derive Key1 for the
* given PBKDF2 algorithm - create my own secret Key2 as an instance of a
* class implements PBEKey - translate Key2 - check if the key value of the
* translated key and Key1 are the same.
*/
private void testMyOwnSecretKey(byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeyException {
SecretKey key1 = getSecretKeyForPBKDF2(algoForTest, salt);
SecretKey key2 = getMyOwnSecretKey(salt);
// Is it actually the same?
if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
throw new RuntimeException(
"We shouldn't be here. The key1 and key2 values in its"
+ " primary encoding format have to be the same!");
}
// translate key
SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest);
SecretKey key3 = skf.translateKey(key2);
// Check if it still the same after translation
if (!Arrays.equals(key1.getEncoded(), key3.getEncoded())) {
System.out.println("Key1=" + new String(key1.getEncoded())
+ " key3=" + new String(key3.getEncoded()) + " salt="
+ new String(salt));
throw new RuntimeException(
"testMyOwnSecretKey test case failed: the key1 and key3"
+ " values in its primary encoding format are not"
+ " the same for " + algoForTest + " algorithm.");
}
}
/**
* The test case scenario implemented in the method: - create my own secret
* Key2 as an instance of a class implements PBEKey - spoil the key (set
* iteration count to 0, for example) - try to translate key -
* InvalidKeyException is expected.
*/
public void translateSpoiledKey(byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException {
// derive the key
SecretKey key1 = getMyOwnSecretKey(salt);
// spoil the key
((MyPBKDF2SecretKey) key1).spoil();
// translate key
SecretKeyFactory skf = SecretKeyFactory.getInstance(algoForTest);
try {
skf.translateKey(key1);
throw new RuntimeException(
"translateSpoiledKey test case failed, should throw"
+ " InvalidKeyException when spoil the key");
} catch (InvalidKeyException ike) {
out.println("Expected exception when spoil the key");
}
}
/**
* Generate a PBKDF2 secret key using given algorithm.
*/
private SecretKey getSecretKeyForPBKDF2(String algoDeriveKey, byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory skf = SecretKeyFactory.getInstance(algoDeriveKey);
PBEKeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(), salt,
ITERATION_COUNT, KEY_SIZE);
return skf.generateSecret(spec);
}
/**
* Generate a secrete key as an instance of a class implements PBEKey.
*/
private SecretKey getMyOwnSecretKey(byte[] salt)
throws InvalidKeySpecException, NoSuchAlgorithmException {
return new MyPBKDF2SecretKey(PASS_PHRASE, algoForTest, salt,
ITERATION_COUNT, KEY_SIZE);
}
/**
* An utility class to check the SecretKeyFactory.translateKey() method.
*/
class MyPBKDF2SecretKey implements PBEKey {
private final byte[] key;
private final byte[] salt;
private final String algorithm;
private final int keyLength;
private final String pass;
private int itereationCount;
/**
* The key is generating by SecretKeyFactory and its value just copying
* in the key field of MySecretKey class. So, this is real key derived
* using the given algo.
*/
public MyPBKDF2SecretKey(String passPhrase, String algo, byte[] salt1,
int iterationCount, int keySize)
throws InvalidKeySpecException, NoSuchAlgorithmException {
algorithm = algo;
salt = salt1;
itereationCount = iterationCount;
pass = passPhrase;
PBEKeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), salt,
iterationCount, keySize);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo);
SecretKey realKey = keyFactory.generateSecret(spec);
keyLength = realKey.getEncoded().length;
key = new byte[keyLength];
System.arraycopy(realKey.getEncoded(), 0, key, 0, keyLength);
}
@Override
public String getAlgorithm() {
return algorithm;
}
@Override
public String getFormat() {
return "RAW";
}
@Override
public byte[] getEncoded() {
byte[] copy = new byte[keyLength];
System.arraycopy(key, 0, copy, 0, keyLength);
return copy;
}
@Override
public int getIterationCount() {
return itereationCount;
}
@Override
public byte[] getSalt() {
return salt;
}
@Override
public char[] getPassword() {
return pass.toCharArray();
}
/**
* Spoil the generated key (before translation) to cause an
* InvalidKeyException
*/
public void spoil() {
itereationCount = -1;
}
@Override
public void destroy() throws DestroyFailedException {
}
@Override
public boolean isDestroyed() {
return false;
}
}
}
\ No newline at end of file
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.security.auth.DestroyFailedException;
/*
* @test
* @bug 8048820
* @summary The test verifies SecretKey values should remain the same after
* translation with SecretKeyFactory.translateKey().
*/
public class SecKFTranslateTest {
private static final String SUN_JCE = "SunJCE";
public static void main(String[] args) throws Exception {
SecKFTranslateTest test = new SecKFTranslateTest();
test.run();
}
private void run() throws Exception {
for (Algorithm algorithm : Algorithm.values()) {
runTest(algorithm);
}
}
private void runTest(Algorithm algo) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException,
InvalidKeySpecException, NoSuchPaddingException,
InvalidAlgorithmParameterException, ShortBufferException,
IllegalBlockSizeException, BadPaddingException {
AlgorithmParameterSpec[] aps = new AlgorithmParameterSpec[1];
byte[] plainText = new byte[800];
SecretKey key1 = algo.intSecurityKey(aps);
Random random = new Random();
// Initialization
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.toString(),
SUN_JCE);
random.nextBytes(plainText);
Cipher ci = Cipher.getInstance(algo.toString(), SUN_JCE);
// Encryption
ci.init(Cipher.ENCRYPT_MODE, key1, aps[0]);
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
int offset = ci.update(plainText, 0, plainText.length, cipherText, 0);
ci.doFinal(cipherText, offset);
// translate key
SecretKey key2 = skf.translateKey(key1);
// Decryption
ci.init(Cipher.DECRYPT_MODE, key2, aps[0]);
byte[] recoveredText = new byte[ci.getOutputSize(plainText.length)];
ci.doFinal(cipherText, 0, cipherText.length, recoveredText);
// Comparison
if (!Arrays.equals(plainText, recoveredText)) {
System.out.println("Key1:" + new String(key1.getEncoded())
+ " Key2:" + new String(key2.getEncoded()));
throw new RuntimeException("Testing translate key failed with "
+ algo);
}
}
}
class MyOwnSecKey implements SecretKey {
private static final String DEFAULT_ALGO = "PBEWithMD5AndDES";
private final byte[] key;
private final String algorithm;
private final int keySize;
public MyOwnSecKey(byte[] key1, int offset, String algo)
throws InvalidKeyException {
algorithm = algo;
if (algo.equalsIgnoreCase("DES")) {
keySize = 8;
} else if (algo.equalsIgnoreCase("DESede")) {
keySize = 24;
} else {
throw new InvalidKeyException(
"Inappropriate key format and algorithm");
}
if (key1 == null || key1.length - offset < keySize) {
throw new InvalidKeyException("Wrong key size");
}
key = new byte[keySize];
System.arraycopy(key, offset, key, 0, keySize);
}
public MyOwnSecKey(PBEKeySpec ks) throws InvalidKeySpecException {
algorithm = DEFAULT_ALGO;
key = new String(ks.getPassword()).getBytes();
keySize = key.length;
}
@Override
public String getAlgorithm() {
return algorithm;
}
@Override
public String getFormat() {
return "RAW";
}
@Override
public byte[] getEncoded() {
byte[] copy = new byte[keySize];
System.arraycopy(key, 0, copy, 0, keySize);
return copy;
}
@Override
public void destroy() throws DestroyFailedException {
}
@Override
public boolean isDestroyed() {
return false;
}
}
enum Algorithm {
DES {
@Override
SecretKey intSecurityKey(AlgorithmParameterSpec[] spec)
throws InvalidKeyException {
int keyLength = 8;
byte[] keyVal = new byte[keyLength];
new SecureRandom().nextBytes(keyVal);
SecretKey key1 = new MyOwnSecKey(keyVal, 0, this.toString());
return key1;
}
},
DESEDE {
@Override
SecretKey intSecurityKey(AlgorithmParameterSpec[] spec)
throws InvalidKeyException {
int keyLength = 24;
byte[] keyVal = new byte[keyLength];
new SecureRandom().nextBytes(keyVal);
SecretKey key1 = new MyOwnSecKey(keyVal, 0, this.toString());
return key1;
}
},
PBEWithMD5ANDdes {
@Override
SecretKey intSecurityKey(AlgorithmParameterSpec[] spec)
throws InvalidKeySpecException {
byte[] salt = new byte[8];
int iterCnt = 6;
new Random().nextBytes(salt);
spec[0] = new PBEParameterSpec(salt, iterCnt);
PBEKeySpec pbeKS = new PBEKeySpec(
new String("So far so good").toCharArray());
SecretKey key1 = new MyOwnSecKey(pbeKS);
return key1;
}
};
abstract SecretKey intSecurityKey(AlgorithmParameterSpec[] spec)
throws InvalidKeyException, InvalidKeySpecException;
}
/**
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 only, as published by
* the Free Software Foundation.
*
* This code 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 General Public License version 2 for more
* details (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License version 2
* along with this work; if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or
* visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.security.auth.login.LoginContext;
/**
* @test
* @bug 8050461
* @summary Test should throw Configuration error if configuration file contains
* syntax error
* @build SampleLoginModule JAASConfigSyntaxTest
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutApplication.config JAASConfigSyntaxTest
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutBraces.config JAASConfigSyntaxTest
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutFlag.config JAASConfigSyntaxTest
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutLoginModule.config JAASConfigSyntaxTest
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutSemiColen.config JAASConfigSyntaxTest
*/
public class JAASConfigSyntaxTest {
private static final String TEST_NAME = "JAASConfigSyntaxTest";
public static void main(String[] args) throws Exception {
try {
LoginContext lc = new LoginContext(TEST_NAME);
lc.login();
throw new RuntimeException("Test Case Failed, did not get "
+ "expected exception");
} catch (Exception ex) {
if (ex.getMessage().contains("java.io.IOException: "
+ "Configuration Error:")) {
System.out.println("Test case passed");
} else {
throw new RuntimeException(ex);
}
}
}
}
{
SampleLoginModule Required;
SampleLoginModule Required;
SampleLoginModule Required;
};
\ No newline at end of file
JAASConfigSyntaxTest
SampleLoginModule Required;
SampleLoginModule Required;
SampleLoginModule Required;
;
\ No newline at end of file
JAASConfigSyntaxTest{
SampleLoginModule ;
SampleLoginModule ;
SampleLoginModule ;
};
\ No newline at end of file
JAASConfigSyntaxTest{
SampleLoginModule Required;
SampleLoginModule Required
SampleLoginModule Required;
};
\ No newline at end of file
/**
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 only, as published by
* the Free Software Foundation.
*
* This code 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 General Public License version 2 for more
* details (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License version 2
* along with this work; if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or
* visit www.oracle.com if you need additional information or have any
* questions.
*/
import static java.lang.System.out;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
/**
* Login module which passes all the time
*/
public class SampleLoginModule implements LoginModule {
private final String name;
public SampleLoginModule() {
name = this.getClass().getName();
}
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
}
@Override
public boolean login() throws LoginException {
out.println(name + " Login method of AbstractLoginModule is called ");
out.println(name + ":login:PASS");
return true;
}
@Override
public boolean commit() throws LoginException {
out.println("Commit of AbstractLoginModule is called");
out.println(name + ":commit:PASS");
return true;
}
@Override
public boolean abort() throws LoginException {
out.println("Abourt is called in AbstractLoginModule");
out.println(name + ":abort:PASS");
return true;
}
@Override
public boolean logout() throws LoginException {
out.println("logout is called in AbstractLoginModule");
out.println(name + ":logout:PASS");
return true;
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.security.Principal;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.ChoiceCallback;
import javax.security.auth.callback.ConfirmationCallback;
import javax.security.auth.callback.LanguageCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
public class CustomLoginModule implements LoginModule {
static final String HELLO = "Hello";
private Subject subject;
private CallbackHandler callbackHandler;
private boolean loginSucceeded = false;
private String username;
private char[] password;
/*
* Initialize this LoginModule.
*/
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
// check if custom parameter is passed from comfiguration
if (options == null) {
throw new RuntimeException("options is null");
}
// read username/password from configuration
Object o = options.get("username");
if (o == null) {
throw new RuntimeException("Custom parameter not passed");
}
if (!(o instanceof String)) {
throw new RuntimeException("Password is not a string");
}
username = (String) o;
o = options.get("password");
if (o == null) {
throw new RuntimeException("Custom parameter not passed");
}
if (!(o instanceof String)) {
throw new RuntimeException("Password is not a string");
}
password = ((String) o).toCharArray();
}
/*
* Authenticate the user.
*/
@Override
public boolean login() throws LoginException {
// prompt for a user name and password
if (callbackHandler == null) {
throw new LoginException("No CallbackHandler available");
}
// standard callbacks
NameCallback name = new NameCallback("username: ", "default");
PasswordCallback passwd = new PasswordCallback("password: ", false);
LanguageCallback language = new LanguageCallback();
TextOutputCallback error = new TextOutputCallback(
TextOutputCallback.ERROR, "This is an error");
TextOutputCallback warning = new TextOutputCallback(
TextOutputCallback.WARNING, "This is a warning");
TextOutputCallback info = new TextOutputCallback(
TextOutputCallback.INFORMATION, "This is a FYI");
TextInputCallback text = new TextInputCallback("Please type " + HELLO,
"Bye");
ChoiceCallback choice = new ChoiceCallback("Choice: ",
new String[] { "pass", "fail" }, 1, true);
ConfirmationCallback confirmation = new ConfirmationCallback(
"confirmation: ", ConfirmationCallback.INFORMATION,
ConfirmationCallback.YES_NO_OPTION, ConfirmationCallback.NO);
CustomCallback custom = new CustomCallback();
Callback[] callbacks = new Callback[] {
choice, info, warning, error, name, passwd, text, language,
confirmation, custom
};
boolean uce = false;
try {
callbackHandler.handle(callbacks);
} catch (UnsupportedCallbackException e) {
Callback callback = e.getCallback();
if (custom.equals(callback)) {
uce = true;
System.out.println("CustomLoginModule: "
+ "custom callback not supported as expected");
} else {
throw new LoginException("Unsupported callback: " + callback);
}
} catch (IOException ioe) {
throw new LoginException(ioe.toString());
}
if (!uce) {
throw new RuntimeException("UnsupportedCallbackException "
+ "not thrown");
}
if (!HELLO.equals(text.getText())) {
System.out.println("Text: " + text.getText());
throw new FailedLoginException("No hello");
}
if (!Locale.GERMANY.equals(language.getLocale())) {
System.out.println("Selected locale: " + language.getLocale());
throw new FailedLoginException("Achtung bitte");
}
String readUsername = name.getName();
char[] readPassword = passwd.getPassword();
if (readPassword == null) {
// treat a NULL password as an empty password
readPassword = new char[0];
}
passwd.clearPassword();
// verify the username/password
if (!username.equals(readUsername)
|| !Arrays.equals(password, readPassword)) {
loginSucceeded = false;
throw new FailedLoginException("Username/password is not correct");
}
// check chosen option
int[] selected = choice.getSelectedIndexes();
if (selected == null || selected.length == 0) {
throw new FailedLoginException("Nothing selected");
}
if (selected[0] != 0) {
throw new FailedLoginException("Wrong choice: " + selected[0]);
}
// check confirmation
if (confirmation.getSelectedIndex() != ConfirmationCallback.YES) {
throw new FailedLoginException("Not confirmed: "
+ confirmation.getSelectedIndex());
}
loginSucceeded = true;
System.out.println("CustomLoginModule: authentication succeeded");
return true;
}
/*
* This method is called if the LoginContext's overall authentication
* succeeded.
*/
@Override
public boolean commit() throws LoginException {
if (loginSucceeded) {
// add a Principal to the Subject
Principal principal = new TestPrincipal(username);
if (!subject.getPrincipals().contains(principal)) {
subject.getPrincipals().add(principal);
}
return true;
}
return false;
}
/*
* This method is called if the LoginContext's overall authentication
* failed.
*/
@Override
public boolean abort() throws LoginException {
loginSucceeded = false;
return true;
}
/*
* Logout the user.
*/
@Override
public boolean logout() throws LoginException {
loginSucceeded = false;
boolean removed = subject.getPrincipals().remove(
new TestPrincipal(username));
if (!removed) {
throw new LoginException("Coundn't remove a principal: "
+ username);
}
return true;
}
static class TestPrincipal implements Principal {
private final String name;
public TestPrincipal(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return("TestPrincipal [name =" + name + "]");
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof TestPrincipal)) {
return false;
}
TestPrincipal other = (TestPrincipal) o;
return name != null ? name.equals(other.name) : other.name == null;
}
}
static class CustomCallback implements Callback {}
}
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.security.auth.login.LoginException;
/**
* Login module which passes all the time
*/
public class DummyLoginModule extends SmartLoginModule {
private final String header;
public DummyLoginModule() {
header = "DummyLoginModule: ";
}
@Override
public boolean login() throws LoginException {
System.out.println("\t\t" + header + " login method is called ");
System.out.println("\t\t" + header + " login:PASS");
return true;
}
@Override
public boolean commit() throws LoginException {
System.out.println("\t\t" + header + " commit method is called");
System.out.println("\t\t" + header + " commit:PASS");
return true;
}
@Override
public boolean abort() throws LoginException {
System.out.println("\t\t" + header + " abort method is called ");
System.out.println("\t\t" + header + " abort:PASS");
return true;
}
@Override
public boolean logout() throws LoginException {
System.out.println("\t\t" + header + " logout method is called");
System.out.println("\t\t" + header + " logout:PASS");
return true;
}
}
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
/**
* @test
* @bug 8050427 4703361
* @summary Test case for RFE: 4703361. Tests the Dynamic Configuration of
* Authentication Modules with different methods
* @compile SmartLoginModule.java DummyLoginModule.java MyConfiguration.java
* @run main/othervm DynamicConfigurationTest
*/
public class DynamicConfigurationTest {
public static void main(String... args) {
String rightConfigName = "PT";
String wrongConfigName = "NT";
char[] rightPwd = new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's',
'w', 'o', 'r', 'd', '1'};
char[] wrongPwd = new char[]{'w', 'r', 'o', 'n', 'g', 'P', 'a', 's',
's','w', 'o', 'r', 'd'};
// Test with wrong configuration name
// Expect LoginException when initiate a new LoginContext object
testConfigName(wrongConfigName, true);
System.out.println("Wrong Config Name Test passed ");
// Spedify two loginModules: SmartLoginModule and DummyLoginModule
// Flags: required-required
// Test with right password for SmartLoginModule
// No exception is expected
Configuration cf = new MyConfiguration();
testLogin(rightConfigName, rightPwd, cf, false);
System.out.println("Positive test passed");
// Spedify two loginModules: SmartLoginModule and DummyLoginModule
// Flags: required-required
// Test with wrong password for SmartLoginModule
// Expect LoginException by calling LoginContext.login() method
testLogin(rightConfigName, wrongPwd, cf, true);
System.out.println("Should fail test passed");
// Spedify two loginModules: SmartLoginModule and DummyLoginModule
// Change the flags from required-required to optional-sufficient
// Test with wrong password for SmartLoginModule, while DummyLoginModule
// always passes
// No Exception is expected
cf = new MyConfiguration(true);
testLogin(rightConfigName, wrongPwd, cf, false);
System.out.println("One module fails where are other module succeeeds "
+ "Test passed with optional-sufficient flags");
}
public static void testConfigName(String confName,
boolean expectException) {
String expectedMsg = "No LoginModules configured for " + confName;
try {
LoginContext lc = new LoginContext(confName, new Subject(),
new MyCallbackHandler(), new MyConfiguration());
if (expectException) {
throw new RuntimeException("Wrong Config Name Test failed: "
+ "expected LoginException not thrown.");
}
} catch (LoginException le) {
if (!expectException || !le.getMessage().equals(expectedMsg)) {
System.out.println("Wrong Config Name Test failed: "
+ "received Unexpected exception.");
throw new RuntimeException(le);
}
}
}
public static void testLogin(String confName, char[] passwd,
Configuration cf, boolean expectException) {
try {
CallbackHandler ch = new MyCallbackHandler("testUser", passwd);
LoginContext lc = new LoginContext(confName, new Subject(),
ch, cf);
lc.login();
if (expectException) {
throw new RuntimeException("Login Test failed: "
+ "expected LoginException not thrown");
}
} catch (LoginException le) {
if (!expectException) {
System.out.println("Login Test failed: "
+ "received Unexpected exception.");
throw new RuntimeException(le);
}
}
}
}
/**
* The application simulates the CallbackHandler. It simulates! which means all
* process to get username and password is ignored. We have to take this
* approach for automation purpose. So, this is not a real world example at all.
*/
class MyCallbackHandler implements CallbackHandler {
String userName;
char[] password;
/**
* This is simply a workaround approach for IO approach to get username and
* password. For automation purpose only.
*/
public MyCallbackHandler() {
super();
}
public MyCallbackHandler(String username, char[] password) {
super();
userName = username;
this.password = password;
}
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback nc = (NameCallback) callback;
nc.setName(userName);
} else if (callback instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callback;
pc.setPassword(password);
} else {
throw new UnsupportedCallbackException(callback,
"Unrecognized Callback");
}
}
}
}
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.HashMap;
import javax.security.auth.login.AppConfigurationEntry;
import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
import javax.security.auth.login.Configuration;
/**
* This class is used to test LoginContext constructor API. It simply contains
* one configuration entry: PT.
*/
public class MyConfiguration extends Configuration {
private static final AppConfigurationEntry[] ptAE
= new AppConfigurationEntry[2];
private static final HashMap<String, String> map = new HashMap<>();
private boolean optionOrder = false;
public MyConfiguration() {
setupConfiguration();
}
public MyConfiguration(boolean optionOrder) {
this.optionOrder = optionOrder;
setupConfiguration();
}
private void setupConfiguration() {
ptAE[0] = new AppConfigurationEntry("SmartLoginModule",
optionOrder ? OPTIONAL : REQUIRED,
map);
ptAE[1] = new AppConfigurationEntry("DummyLoginModule",
optionOrder ? SUFFICIENT : REQUIRED,
map);
}
@Override
public AppConfigurationEntry[]
getAppConfigurationEntry(String applicationName) {
if (applicationName.equals("PT")) {
return ptAE;
} else {
return null;
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
/**
* @test
* @bug 8048138
* @summary Check if shared state is passed to login module
* @run main/othervm SharedState
*/
public class SharedState {
static final String NAME = "name";
static final String VALUE = "shared";
public static void main(String[] args) throws LoginException {
System.setProperty("java.security.auth.login.config",
System.getProperty("test.src")
+ System.getProperty("file.separator")
+ "shared.config");
new LoginContext("SharedState").login();
}
public static abstract class Module implements LoginModule {
@Override
public boolean login() throws LoginException {
return true;
}
@Override
public boolean commit() throws LoginException {
return true;
}
@Override
public boolean abort() throws LoginException {
return true;
}
@Override
public boolean logout() throws LoginException {
return true;
}
}
public static class FirstModule extends Module {
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String,?> sharedState, Map<String,?> options) {
((Map)sharedState).put(NAME, VALUE);
}
}
public static class SecondModule extends Module {
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String,?> sharedState, Map<String,?> options) {
// check shared object
Object shared = sharedState.get(NAME);
if (!VALUE.equals(shared)) {
throw new RuntimeException("Unexpected shared object: "
+ shared);
}
}
}
}
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.Principal;
import java.util.Arrays;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
/**
* This code was based on JAAS demo code, small modification is made for testing
* purpose.
*/
public class SmartLoginModule implements LoginModule {
// initial state
private Subject subject;
private CallbackHandler callbackHandler;
// the authentication status
private boolean succeeded = false;
private boolean commitSucceeded = false;
// username and password
private String username;
private char[] password;
// Default values for this login module. In real world,
// don't do it in this way!
private String myUsername;
private char[] myPassword;
private String header;
// testUser's SamplePrincipal
private SamplePrincipal userPrincipal;
public SmartLoginModule() {
this("testUser",
new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's',
'w', 'o', 'r', 'd', '1'},
"SmartLoginModule1: ");
}
public SmartLoginModule(String userName, char[] password, String header) {
myUsername = userName;
myPassword = password;
this.header = header;
}
@Override
public boolean abort() throws LoginException {
if (!succeeded) {
return false;
} else if (succeeded && !commitSucceeded) {
// login succeeded but overall authentication failed
succeeded = false;
username = null;
password = null;
userPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
}
@Override
public boolean commit() throws LoginException {
if (!succeeded) {
return false;
} else {
// add a Principal (authenticated identity) to the Subject
// assume the user we authenticated is the SamplePrincipal
userPrincipal = new SamplePrincipal(username);
if (!subject.getPrincipals().contains(userPrincipal)) {
subject.getPrincipals().add(userPrincipal);
}
// in any case, clean out state
username = null;
password = null;
commitSucceeded = true;
return true;
}
}
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
}
@Override
public boolean login() throws LoginException {
if (callbackHandler == null) {
throw new LoginException("Error: no CallbackHandler available to "
+ "garner authentication information from the user");
}
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback(header + "user name: ");
callbacks[1] = new PasswordCallback(header + "password: ", false);
try {
callbackHandler.handle(callbacks);
username = ((NameCallback) callbacks[0]).getName();
char[] tmpPassword
= ((PasswordCallback) callbacks[1]).getPassword();
if (tmpPassword == null) {
tmpPassword = new char[0];
}
password = new char[tmpPassword.length];
System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
((PasswordCallback) callbacks[1]).clearPassword();
} catch (java.io.IOException ioe) {
throw (LoginException) new LoginException().initCause(ioe);
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + header
+ uce.getCallback().toString()
+ " not available to garner authentication information "
+ "from the user");
}
// verify the username/password
if (username.equals(myUsername)
&& Arrays.equals(password, myPassword)) {
System.out.println("\t\t" + header + " authentication succeeded");
succeeded = true;
return true;
} else {
// authentication failed -- clean out state
System.out.println("\t\t" + header + " authentication failed");
printDebugInfo();
succeeded = false;
username = null;
password = null;
throw new FailedLoginException("User Name or Password Incorrect");
}
}
@Override
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
username = null;
password = null;
userPrincipal = null;
return true;
}
// print debugging information
private void printDebugInfo() {
System.out.println("\t\t" + header + " correct user name: "
+ myUsername);
System.out.println("\t\t" + header + " user entered user name: "
+ username);
System.out.print("\t\t" + header + " correct password: ");
for (char c : myPassword) {
System.out.print(c);
}
System.out.println();
System.out.print("\t\t" + header + " user entered password: ");
for (char c : password) {
System.out.print(c);
}
System.out.println();
}
}
class SamplePrincipal implements Principal, java.io.Serializable {
/**
* @serial
*/
private String name;
/**
* Create a SamplePrincipal with a Sample username.
*
* @param name the Sample username for this user.
* @exception NullPointerException if the <code>name</code> is
* <code>null</code>.
*/
public SamplePrincipal(String name) {
if (name == null) {
throw new NullPointerException("illegal null input");
}
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return "SamplePrincipal: " + name;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (this == o) {
return true;
}
if (!(o instanceof SamplePrincipal)) {
return false;
}
SamplePrincipal that = (SamplePrincipal) o;
return this.getName().equals(that.getName());
}
@Override
public int hashCode() {
return name.hashCode();
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.Principal;
import java.util.Arrays;
import java.util.Locale;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.ChoiceCallback;
import javax.security.auth.callback.ConfirmationCallback;
import javax.security.auth.callback.LanguageCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
/*
* @test
* @bug 8048138
* @summary Checks if JAAS login works fine with standard callbacks
* @compile DefaultHandlerModule.java
* @run main/othervm StandardCallbacks
*/
public class StandardCallbacks {
private static final String USERNAME = "username";
private static final char[] PASSWORD = "password".toCharArray();
public static void main(String[] args) throws LoginException {
System.setProperty("java.security.auth.login.config",
System.getProperty("test.src")
+ System.getProperty("file.separator")
+ "custom.config");
CustomCallbackHandler handler = new CustomCallbackHandler(USERNAME);
LoginContext context = new LoginContext("StandardCallbacks", handler);
handler.setPassword(PASSWORD);
System.out.println("Try to login with correct password, "
+ "successful authentication is expected");
context.login();
System.out.println("Authentication succeeded!");
Subject subject = context.getSubject();
System.out.println("Authenticated user has the following principals ["
+ subject.getPrincipals().size() + " ]:");
boolean found = true;
for (Principal principal : subject.getPrincipals()) {
System.out.println("principal: " + principal);
if (principal instanceof CustomLoginModule.TestPrincipal) {
CustomLoginModule.TestPrincipal testPrincipal =
(CustomLoginModule.TestPrincipal) principal;
if (USERNAME.equals(testPrincipal.getName())) {
System.out.println("Found test principal: "
+ testPrincipal);
found = true;
break;
}
}
}
if (!found) {
throw new RuntimeException("TestPrincipal not found");
}
// check if all expected text output callbacks have been called
if (!handler.info) {
throw new RuntimeException("TextOutputCallback.INFO not called");
}
if (!handler.warning) {
throw new RuntimeException("TextOutputCallback.WARNING not called");
}
if (!handler.error) {
throw new RuntimeException("TextOutputCallback.ERROR not called");
}
System.out.println("Authenticated user has the following public "
+ "credentials [" + subject.getPublicCredentials().size()
+ "]:");
subject.getPublicCredentials().stream().
forEach((o) -> {
System.out.println("public credential: " + o);
});
context.logout();
System.out.println("Test passed");
}
private static class CustomCallbackHandler implements CallbackHandler {
private final String username;
private char[] password;
private boolean info = false;
private boolean warning = false;
private boolean error = false;
CustomCallbackHandler(String username) {
this.username = username;
}
void setPassword(char[] password) {
this.password = password;
}
@Override
public void handle(Callback[] callbacks)
throws UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof TextOutputCallback) {
TextOutputCallback toc = (TextOutputCallback) callback;
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println("INFO: " + toc.getMessage());
info = true;
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
error = true;
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
warning = true;
break;
default:
throw new UnsupportedCallbackException(toc,
"Unsupported message type: "
+ toc.getMessageType());
}
} else if (callback instanceof TextInputCallback) {
TextInputCallback tic = (TextInputCallback) callback;
System.out.println(tic.getPrompt());
tic.setText(CustomLoginModule.HELLO);
} else if (callback instanceof LanguageCallback) {
LanguageCallback lc = (LanguageCallback) callback;
lc.setLocale(Locale.GERMANY);
} else if (callback instanceof ConfirmationCallback) {
ConfirmationCallback cc = (ConfirmationCallback) callback;
System.out.println(cc.getPrompt());
cc.setSelectedIndex(ConfirmationCallback.YES);
} else if (callback instanceof ChoiceCallback) {
ChoiceCallback cc = (ChoiceCallback) callback;
System.out.println(cc.getPrompt()
+ Arrays.toString(cc.getChoices()));
cc.setSelectedIndex(0);
} else if (callback instanceof NameCallback) {
NameCallback nc = (NameCallback) callback;
System.out.println(nc.getPrompt());
nc.setName(username);
} else if (callback instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callback;
System.out.println(pc.getPrompt());
pc.setPassword(password);
} else {
throw new UnsupportedCallbackException(callback,
"Unknown callback");
}
}
}
}
}
StandardCallbacks {
DefaultHandlerModule required;
CustomLoginModule required username="username" password="password";
};
SharedState {
SharedState$FirstModule required;
SharedState$SecondModule required;
};
\ No newline at end of file
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.RealmCallback;
import javax.security.sasl.RealmChoiceCallback;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
/*
* @test
* @bug 8049814
* @summary JAVA SASL server and client tests with CRAM-MD5 and
* DIGEST-MD5 mechanisms. The tests try different QOP values on
* client and server side.
* @modules java.security.sasl/javax.security.sasl
*/
public class ClientServerTest {
private static final int DELAY = 100;
private static final String LOCALHOST = "localhost";
private static final String DIGEST_MD5 = "DIGEST-MD5";
private static final String CRAM_MD5 = "CRAM-MD5";
private static final String PROTOCOL = "saslservice";
private static final String USER_ID = "sasltester";
private static final String PASSWD = "password";
private static final String QOP_AUTH = "auth";
private static final String QOP_AUTH_CONF = "auth-conf";
private static final String QOP_AUTH_INT = "auth-int";
private static final String AUTHID_SASL_TESTER = "sasl_tester";
private static final ArrayList<String> SUPPORT_MECHS = new ArrayList<>();
static {
SUPPORT_MECHS.add(DIGEST_MD5);
SUPPORT_MECHS.add(CRAM_MD5);
}
public static void main(String[] args) throws Exception {
String[] allQops = { QOP_AUTH_CONF, QOP_AUTH_INT, QOP_AUTH };
String[] twoQops = { QOP_AUTH_INT, QOP_AUTH };
String[] authQop = { QOP_AUTH };
String[] authIntQop = { QOP_AUTH_INT };
String[] authConfQop = { QOP_AUTH_CONF };
String[] emptyQop = {};
boolean success = true;
success &= runTest("", CRAM_MD5, new String[] { QOP_AUTH },
new String[] { QOP_AUTH }, false);
success &= runTest("", DIGEST_MD5, new String[] { QOP_AUTH },
new String[] { QOP_AUTH }, false);
success &= runTest(AUTHID_SASL_TESTER, DIGEST_MD5,
new String[] { QOP_AUTH }, new String[] { QOP_AUTH }, false);
success &= runTest("", DIGEST_MD5, allQops, authQop, false);
success &= runTest("", DIGEST_MD5, allQops, authIntQop, false);
success &= runTest("", DIGEST_MD5, allQops, authConfQop, false);
success &= runTest("", DIGEST_MD5, twoQops, authQop, false);
success &= runTest("", DIGEST_MD5, twoQops, authIntQop, false);
success &= runTest("", DIGEST_MD5, twoQops, authConfQop, true);
success &= runTest("", DIGEST_MD5, authIntQop, authQop, true);
success &= runTest("", DIGEST_MD5, authConfQop, authQop, true);
success &= runTest("", DIGEST_MD5, authConfQop, emptyQop, true);
success &= runTest("", DIGEST_MD5, authIntQop, emptyQop, true);
success &= runTest("", DIGEST_MD5, authQop, emptyQop, true);
if (!success) {
throw new RuntimeException("At least one test case failed");
}
System.out.println("Test passed");
}
private static boolean runTest(String authId, String mech,
String[] clientQops, String[] serverQops, boolean expectException)
throws Exception {
System.out.println("AuthId:" + authId
+ " mechanism:" + mech
+ " clientQops: " + Arrays.toString(clientQops)
+ " serverQops: " + Arrays.toString(serverQops)
+ " expect exception:" + expectException);
try (Server server = Server.start(LOCALHOST, authId, serverQops)) {
new Client(LOCALHOST, server.getPort(), mech, authId, clientQops)
.run();
if (expectException) {
System.out.println("Expected exception not thrown");
return false;
}
} catch (SaslException e) {
if (!expectException) {
System.out.println("Unexpected exception: " + e);
return false;
}
System.out.println("Expected exception: " + e);
}
return true;
}
static enum SaslStatus {
SUCCESS, FAILURE, CONTINUE
}
static class Message implements Serializable {
private final SaslStatus status;
private final byte[] data;
public Message(SaslStatus status, byte[] data) {
this.status = status;
this.data = data;
}
public SaslStatus getStatus() {
return status;
}
public byte[] getData() {
return data;
}
}
static class SaslPeer {
final String host;
final String mechanism;
final String qop;
final CallbackHandler callback;
SaslPeer(String host, String authId, String... qops) {
this(host, null, authId, qops);
}
SaslPeer(String host, String mechanism, String authId, String... qops) {
this.host = host;
this.mechanism = mechanism;
StringJoiner sj = new StringJoiner(",");
for (String q : qops) {
sj.add(q);
}
qop = sj.toString();
callback = new TestCallbackHandler(USER_ID, PASSWD, host, authId);
}
Message getMessage(Object ob) {
if (!(ob instanceof Message)) {
throw new RuntimeException("Expected an instance of Message");
}
return (Message) ob;
}
}
static class Server extends SaslPeer implements Runnable, Closeable {
private volatile boolean ready = false;
private volatile ServerSocket ssocket;
static Server start(String host, String authId, String[] serverQops)
throws UnknownHostException {
Server server = new Server(host, authId, serverQops);
Thread thread = new Thread(server);
thread.setDaemon(true);
thread.start();
while (!server.ready) {
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return server;
}
Server(String host, String authId, String... qops) {
super(host, authId, qops);
}
int getPort() {
return ssocket.getLocalPort();
}
private void processConnection(SaslEndpoint endpoint)
throws SaslException, IOException, ClassNotFoundException {
System.out.println("process connection");
endpoint.send(SUPPORT_MECHS);
Object o = endpoint.receive();
if (!(o instanceof String)) {
throw new RuntimeException("Received unexpected object: " + o);
}
String mech = (String) o;
SaslServer saslServer = createSaslServer(mech);
Message msg = getMessage(endpoint.receive());
while (!saslServer.isComplete()) {
byte[] data = processData(msg.getData(), endpoint,
saslServer);
if (saslServer.isComplete()) {
System.out.println("server is complete");
endpoint.send(new Message(SaslStatus.SUCCESS, data));
} else {
System.out.println("server continues");
endpoint.send(new Message(SaslStatus.CONTINUE, data));
msg = getMessage(endpoint.receive());
}
}
}
private byte[] processData(byte[] data, SaslEndpoint endpoint,
SaslServer server) throws SaslException, IOException {
try {
return server.evaluateResponse(data);
} catch (SaslException e) {
endpoint.send(new Message(SaslStatus.FAILURE, null));
System.out.println("Error while processing data");
throw e;
}
}
private SaslServer createSaslServer(String mechanism)
throws SaslException {
Map<String, String> props = new HashMap<>();
props.put(Sasl.QOP, qop);
return Sasl.createSaslServer(mechanism, PROTOCOL, host, props,
callback);
}
@Override
public void run() {
try (ServerSocket ss = new ServerSocket(0)) {
ssocket = ss;
System.out.println("server started on port " + getPort());
ready = true;
Socket socket = ss.accept();
try (SaslEndpoint endpoint = new SaslEndpoint(socket)) {
System.out.println("server accepted connection");
processConnection(endpoint);
}
} catch (Exception e) {
// ignore it for now, client will throw an exception
}
}
@Override
public void close() throws IOException {
if (!ssocket.isClosed()) {
ssocket.close();
}
}
}
static class Client extends SaslPeer {
private final int port;
Client(String host, int port, String mech, String authId,
String... qops) {
super(host, mech, authId, qops);
this.port = port;
}
public void run() throws Exception {
System.out.println("Host:" + host + " port: "
+ port);
try (SaslEndpoint endpoint = SaslEndpoint.create(host, port)) {
negotiateMechanism(endpoint);
SaslClient client = createSaslClient();
byte[] data = new byte[0];
if (client.hasInitialResponse()) {
data = client.evaluateChallenge(data);
}
endpoint.send(new Message(SaslStatus.CONTINUE, data));
Message msg = getMessage(endpoint.receive());
while (!client.isComplete()
&& msg.getStatus() != SaslStatus.FAILURE) {
switch (msg.getStatus()) {
case CONTINUE:
System.out.println("client continues");
data = client.evaluateChallenge(msg.getData());
endpoint.send(new Message(SaslStatus.CONTINUE,
data));
msg = getMessage(endpoint.receive());
break;
case SUCCESS:
System.out.println("client succeeded");
data = client.evaluateChallenge(msg.getData());
if (data != null) {
throw new SaslException("data should be null");
}
break;
default:
throw new RuntimeException("Wrong status:"
+ msg.getStatus());
}
}
if (msg.getStatus() == SaslStatus.FAILURE) {
throw new RuntimeException("Status is FAILURE");
}
}
System.out.println("Done");
}
private SaslClient createSaslClient() throws SaslException {
Map<String, String> props = new HashMap<>();
props.put(Sasl.QOP, qop);
return Sasl.createSaslClient(new String[] {mechanism}, USER_ID,
PROTOCOL, host, props, callback);
}
private void negotiateMechanism(SaslEndpoint endpoint)
throws ClassNotFoundException, IOException {
Object o = endpoint.receive();
if (o instanceof ArrayList) {
ArrayList list = (ArrayList) o;
if (!list.contains(mechanism)) {
throw new RuntimeException(
"Server does not support specified mechanism:"
+ mechanism);
}
} else {
throw new RuntimeException(
"Expected an instance of ArrayList, but received " + o);
}
endpoint.send(mechanism);
}
}
static class SaslEndpoint implements AutoCloseable {
private final Socket socket;
private ObjectInputStream input;
private ObjectOutputStream output;
static SaslEndpoint create(String host, int port) throws IOException {
return new SaslEndpoint(new Socket(host, port));
}
SaslEndpoint(Socket socket) throws IOException {
this.socket = socket;
}
private ObjectInputStream getInput() throws IOException {
if (input == null && socket != null) {
input = new ObjectInputStream(socket.getInputStream());
}
return input;
}
private ObjectOutputStream getOutput() throws IOException {
if (output == null && socket != null) {
output = new ObjectOutputStream(socket.getOutputStream());
}
return output;
}
public Object receive() throws IOException, ClassNotFoundException {
return getInput().readObject();
}
public void send(Object obj) throws IOException {
getOutput().writeObject(obj);
getOutput().flush();
}
@Override
public void close() throws IOException {
if (socket != null && !socket.isClosed()) {
socket.close();
}
}
}
static class TestCallbackHandler implements CallbackHandler {
private final String userId;
private final char[] passwd;
private final String realm;
private String authId;
TestCallbackHandler(String userId, String passwd, String realm,
String authId) {
this.userId = userId;
this.passwd = passwd.toCharArray();
this.realm = realm;
this.authId = authId;
}
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
System.out.println("NameCallback");
((NameCallback) callback).setName(userId);
} else if (callback instanceof PasswordCallback) {
System.out.println("PasswordCallback");
((PasswordCallback) callback).setPassword(passwd);
} else if (callback instanceof RealmCallback) {
System.out.println("RealmCallback");
((RealmCallback) callback).setText(realm);
} else if (callback instanceof RealmChoiceCallback) {
System.out.println("RealmChoiceCallback");
RealmChoiceCallback choice = (RealmChoiceCallback) callback;
if (realm == null) {
choice.setSelectedIndex(choice.getDefaultChoice());
} else {
String[] choices = choice.getChoices();
for (int j = 0; j < choices.length; j++) {
if (realm.equals(choices[j])) {
choice.setSelectedIndex(j);
break;
}
}
}
} else if (callback instanceof AuthorizeCallback) {
System.out.println("AuthorizeCallback");
((AuthorizeCallback) callback).setAuthorized(true);
if (authId == null || authId.trim().length() == 0) {
authId = userId;
}
((AuthorizeCallback) callback).setAuthorizedID(authId);
} else {
throw new UnsupportedCallbackException(callback);
}
}
}
}
}
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"fooObject"})
@XmlRootElement(name = "Foo")
public class Foo {
protected List<Foo> fooObject;
public List<Foo> getFooObject() {
if (fooObject == null) {
fooObject = new ArrayList<Foo>();
}
return this.fooObject;
}
}
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8073872
* @summary test that stackoverflow is not observable when element
* references containing class
* @compile Foo.java
* @run testng/othervm SchemagenStackOverflow
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import org.testng.Assert;
import org.testng.annotations.Test;
public class SchemagenStackOverflow {
@Test
public void schemagenStackOverflowTest() throws Exception {
// Create new instance of JAXB context
JAXBContext context = JAXBContext.newInstance(Foo.class);
context.generateSchema(new TestOutputResolver());
// Read schema content from file
String content = Files.lines(resultSchemaFile).collect(Collectors.joining(""));
System.out.println("Generated schema content:" + content);
// Check if schema was generated: check class and list object names
Assert.assertTrue(content.contains("name=\"Foo\""));
Assert.assertTrue(content.contains("name=\"fooObject\""));
}
// Schemagen output resolver
class TestOutputResolver extends SchemaOutputResolver {
@Override
public Result createOutput(String namespaceUri, String fileName)
throws IOException {
return new StreamResult(resultSchemaFile.toFile());
}
}
// Schemagen output file name and path
static final String SCHEMA_FILENAME = "generatedSchema.xsd";
Path resultSchemaFile = Paths.get(System.getProperty("user.dir", "."))
.resolve(SCHEMA_FILENAME);
}
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8145039
* @summary Check that marshalling of xjc generated class doesn't throw
* ClassCast exception.
* @library /lib/testlibrary
* @run testng/othervm JaxbMarshallTest
*/
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import jdk.testlibrary.JDKToolLauncher;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class JaxbMarshallTest {
@BeforeTest
public void setUp() throws IOException {
// Create test directory inside scratch
testWorkDir = Paths.get(System.getProperty("user.dir", "."));
// Save its URL
testWorkDirUrl = testWorkDir.toUri().toURL();
// Get test source directory path
testSrcDir = Paths.get(System.getProperty("test.src", "."));
// Get path of xjc result folder
xjcResultDir = testWorkDir.resolve(TEST_PACKAGE);
// Copy schema document file to scratch directory
Files.copy(testSrcDir.resolve(XSD_FILENAME), testWorkDir.resolve(XSD_FILENAME), REPLACE_EXISTING);
}
/*
* Test does the following steps to reproduce problem reported by 8145039:
* 1. Copy test schema to JTREG scratch folder
* 2. Run xjc on test schema file
* 3. Compile generated java files with test javac
* 4. Marshall the new list instance to ensure that
* ClassCastException is not thrown
*/
@Test
public void marshallClassCastExceptionTest() throws Exception {
JAXBContext jaxbContext;
Marshaller marshaller;
URLClassLoader jaxbContextClassLoader;
// Generate java classes by xjc
runXjc(XSD_FILENAME);
// Compile xjc generated java files
compileXjcGeneratedClasses();
// Create JAXB context based on xjc generated package.
// Need to create URL class loader ot make compiled classes discoverable
// by JAXB context
jaxbContextClassLoader = URLClassLoader.newInstance(new URL[] {testWorkDirUrl});
jaxbContext = JAXBContext.newInstance( TEST_PACKAGE, jaxbContextClassLoader);
// Create instance of Xjc generated data type.
// Java classes were compiled during the test execution hence reflection
// is needed here
Class classLongListClass = jaxbContextClassLoader.loadClass(TEST_CLASS);
Object objectLongListClass = classLongListClass.newInstance();
// Get 'getIn' method object
Method getInMethod = classLongListClass.getMethod( GET_LIST_METHOD, (Class [])null );
// Invoke 'getIn' method
List<Long> inList = (List<Long>)getInMethod.invoke(objectLongListClass);
// Add values into the jaxb object list
inList.add(Long.valueOf(0));
inList.add(Long.valueOf(43));
inList.add(Long.valueOf(1000000123));
// Marshall constructed complex type variable to standard output.
// In case of failure the ClassCastException will be thrown
marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(objectLongListClass, System.out);
}
// Compile schema file into java classes definitions
void runXjc(String xsdFileName) throws Exception {
// Prepare process builder to run schemagen tool and save its output
JDKToolLauncher xjcLauncher = JDKToolLauncher.createUsingTestJDK("xjc");
xjcLauncher.addToolArg(xsdFileName);
System.out.println("Executing xjc command: " + Arrays.asList(xjcLauncher.getCommand()));
ProcessBuilder pb = new ProcessBuilder(xjcLauncher.getCommand());
// Set xjc work directory with the input java file
pb.directory(testWorkDir.toFile());
pb.inheritIO();
Process p = pb.start();
p.waitFor();
p.destroy();
}
// Compile java classes with javac tool
void compileXjcGeneratedClasses() throws Exception {
JDKToolLauncher javacLauncher = JDKToolLauncher.createUsingTestJDK("javac");
javacLauncher.addToolArg(xjcResultDir.resolve("ObjectFactory.java").toString());
javacLauncher.addToolArg(xjcResultDir.resolve("TypesLongList.java").toString());
javacLauncher.addToolArg(xjcResultDir.resolve("package-info.java").toString());
System.out.println("Compiling xjc generated classes: " + Arrays.asList(javacLauncher.getCommand()));
ProcessBuilder pb = new ProcessBuilder(javacLauncher.getCommand());
pb.inheritIO();
pb.directory(testWorkDir.toFile());
Process p = pb.start();
p.waitFor();
p.destroy();
}
// Test schema filename
static final String XSD_FILENAME = "testSchema.xsd";
// Package of java classes generated by xjc
static final String TEST_PACKAGE = "testns_package";
// Name of generated java class
static final String TEST_CLASS = TEST_PACKAGE+".TypesLongList";
// Method to get the list from xjc generated class
static final String GET_LIST_METHOD = "getIn";
// Test working directory
Path testWorkDir;
// Test working directory URL
URL testWorkDirUrl;
// Directory with test src
Path testSrcDir;
// Directory with java files generated by xjc
Path xjcResultDir;
}
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://testns_package"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
targetNamespace="http://testns_package">
<!-- Simple type list -->
<xsd:simpleType name="LongList">
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:unsignedInt"/>
</xsd:simpleType>
</xsd:list>
</xsd:simpleType>
<!--- Complex test type -->
<xsd:element name="typesLongList">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="in" type="tns:LongList"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
<?xml version="1.0" encoding="UTF-8"?>
<element>
<text>.</text>
</element>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:call-template name="recurse1">
<xsl:with-param name="num">
<xsl:value-of select="0"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>&#xa;</xsl:text>
</xsl:template>
<xsl:template name="recurse1">
<xsl:param name="num"/>
<xsl:call-template name="recurse2">
<xsl:with-param name="num" select="0"/>
</xsl:call-template>
<xsl:if test="not($num = 19)">
<xsl:variable name="tmpnumber"><xsl:value-of select="$num + 1"/></xsl:variable>
<xsl:call-template name="recurse1">
<xsl:with-param name="num">
<xsl:value-of select="$tmpnumber"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="recurse2">
<xsl:param name="num"/>
<xsl:call-template name="recursefinal">
<xsl:with-param name="num" select="0"/>
</xsl:call-template>
<xsl:if test="not($num = 19)">
<xsl:variable name="tmpnumber"><xsl:value-of select="$num + 1"/></xsl:variable>
<xsl:call-template name="recurse2">
<xsl:with-param name="num" select="$tmpnumber"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="recursefinal">
<xsl:param name="num"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:call-template name="dodot"/>
<xsl:if test="not($num = 10)">
<xsl:variable name="tmpnumber"><xsl:value-of select="$num + 1"/></xsl:variable>
<xsl:call-template name="recursefinal">
<xsl:with-param name="num" select="$tmpnumber"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="dodot">
<xsl:variable name="ElementTexts">
<xsl:for-each select="element">
<xsl:value-of select="text"/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$ElementTexts"/>
</xsl:template>
</xsl:stylesheet>
0fto-erech 200amos-batch 00000000X/
1FB01 20150709 EWF 2016021207USD 0000,9302122026623 ////////91284422 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000007366,71//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////D8OOoOOooooOoooooO////15/07 P0480715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40090597 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150630 EWF 2016021206USD 0000,9302122026624 ////////1500006837 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000003844,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////b3oooooooooooooooo////15/07 R1683315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40127254 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150709 EWF 2016021207CHF 0001,0000022026625 ////////94043801 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000438,50//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0CooOooooooooooOOo////15/07 P0472115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30092874 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150702 EWF 2016021207EUR 0001,0468822026626 ////////TL152062 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000661,30//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3coooooooooooooooo////15/07 P0431815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40099751 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150617 EWF 2016021206EUR 0001,0468822026627 ////////TKL100216 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000699,92//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////55oooooOoOooooOoOo////15/07 L0032815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////2014686 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150702 EWF 2016021207EUR 0001,0468822026628 ////////TL152063 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000001983,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9boooooooooooooooo////15/07 P0431815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40099751 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150713 EWF 2016021207EUR 0001,0468822026629 ////////000359084 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000002230,76//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////51oOoOoOoOoooooOOO////15/07 R1735915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40128088 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150708 EWF 2016021207CHF 0001,0000022026630 ////////90864081 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000001893,20//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////acoooooooooooooooo////15/07 P0470615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090668 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150708 EWF 2016021207USD 0000,9302122026631 ////////123939 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000007896,34//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////09oooooooooooooooo////15/07 P0400015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40128846 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150707 EWF 2016021207USD 0000,9302122026633 ////////000358117 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000006810,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////f5oooooooooooooooo////15/07 P0462815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40128088 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150713 EWF 2016021207CHF 0001,0000022026635 ////////M90257500 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000016300,50//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////C3oOOOooOoOooOOOoo////15/07 R1488615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150713 EWF 2016021207USD 0000,9302122026637 ////////M90257457 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000831,90//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////60ooooOooOOOoOoOoo////15/07 P0463815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 40///////////////0000000000055,22//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0463815 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400158 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150713 EWF 2016021207USD 0000,9302122026638 ////////M90257509 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000002218,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////60OoooooOOooooOooo////15/07 P0491115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 40///////////////0000000000055,22//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0491115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400158 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150713 EWF 2016021207CHF 0001,0000022026639 ////////M90257515 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000005833,20//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////A6OOooOoOoOooOoooo////15/07 R1575215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150701 EWF 2016021207USD 0000,9302122026642 ////////C/5 335835 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////16OooooOooOOoOoooo////15/07 R1612715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150701 EWF 2016021207USD 0000,9302122026643 ////////C/5 335833 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000835,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////58OOoOOooooOooOOoo////15/07 R1441715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150706 EWF 2016021207USD 0000,9302122026644 ////////C/5 336036 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6BooooOOoooOooOooo////15/07 R1659015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150701 EWF 2016021207USD 0000,9302122026645 ////////C/5 335836 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6DoOoooOooOOoOooOo////15/07 R1613415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150708 EWF 2016021207USD 0000,9302122026646 ////////C/5 336201 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////74ooOoOooooooooOoO////15/07 R1728915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150706 EWF 2016021207USD 0000,9302122026647 ////////C/5 336035 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000515,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////86OoooOOoooOoooOOo////15/07 R1612615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150706 EWF 2016021207USD 0000,9302122026648 ////////C/5 336034 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000835,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99OOooooooOooOoooo////15/07 R1445115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150701 EWF 2016021207USD 0000,9302122026649 ////////C/5 335834 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000835,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////D8OOoooOOOooooOOoo////15/07 R1445315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126141 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150706 EWF 2016021207CHF 0001,0000022026650 ////////351732 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000192,80//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////4BooOooooOOOoOOOOo////15/07 P0448015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090682 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150706 EWF 2016021207CHF 0001,0000022026651 ////////351730 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000057,25//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////69ooOoOooooooooooO////15/07 P0451715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090682 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 40///////////////0000000000007,02//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0451715 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400122 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150706 EWF 2016021207CHF 0001,0000022026652 ////////351731 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000100,05//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////A9oooooooOoOooOOOo////15/07 P0448015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30090682 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150707 EWF 2016021207EUR 0001,0468822026653 ////////05/91014407 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000225,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////22oooOooooOooOooOO////15/07 R1727915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150707 EWF 2016021207EUR 0001,0468822026654 ////////05/91015508 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000225,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////24OooooOOoOooOoOoO////15/07 R1728015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150701 EWF 2016021207EUR 0001,0468822026655 ////////05/91015531 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000768,45//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////76oOOOOooOoOooooOO////15/07 W0054415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150708 EWF 2016021207USD 0000,9302122026656 ////////SI156008034 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000261,79//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////96OooooOoOoooOOOoo////15/07 P0479215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40126601 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150709 EWF 2016021207EUR 0001,0468822026657 ////////05/91015509 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000705,35//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////99ooOoOOoooooOoooo////15/07 R1625015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40096899 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150713 EWF 2016021207EUR 0001,0468822026662 ////////55941607 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000725,60//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////4BOoooOOOoOoooooOo////15/07 P0486115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40091085 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150708 EWF 2016021207CHF 0001,0000022026663 ////////100-120606 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000004229,50//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0boooooooooooooooo////15/07 P0474115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30094003 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 40///////////////0000000000430,56//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0474115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400158 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 40///////////////0000000000054,38//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0474115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400122 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150707 EWF 2016021207CHF 0001,0000022026664 ////////13143106 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000318,65//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6eoooooooooooooooo////15/07 P0468115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30092269 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 40///////////////0000000000014,04//////////////////////////////////////////////// /////////////////////////////////////7000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////P0468115 ////15/07 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////400122 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150709 EWF 2016021207EUR 0001,0468822026665 ////////TL152315 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000001983,90//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////74oooooooooooooooo////15/07 P0431815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40099751 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150710 EWF 2016021207EUR 0001,0468822026667 ////////11321 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000000840,00//////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////caoooooooooooooooo////15/07 P0471915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////950//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////40129316 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20150401 EWF 2016021204EUR 0001,0553176278995 ////////76278995 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000007833,33//////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////15/04 S0026415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////566//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VERB05001 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20110209 EWF 2016021202CHF 0001,0000090149059 ////////M90149059 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000001077,30//////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////11/03 S0080410 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////566//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1FB01 20110209 EWF 2016021202USD 0000,9570290149062 ////////90149062 ///////////////////////////////////////////////////////////X///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2BBSEG 31///////////////0000000002185,78//////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////11/03 S0125011 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////566//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////30124374 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="UTF-8"?>
<transferInvoice version="0.32">
<invoice>
<invoiceNumber>22026623</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0409</vendor>
<vendorCAGECode>CAGE1</vendorCAGECode>
<vendorAccountNumber>40090597</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>91284422</creditorInvoiceNumber>
<invoiceDate>2015-07-09</invoiceDate>
<closingDate/>
<bookingDate>2015-07-15</bookingDate>
<createdDate>2015-07-15</createdDate>
<invoiceText>D8OOoOOooooOoooooOOOOooOoooOoOoo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">7366.71</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0480715</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-08</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026624</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0307</vendor>
<vendorCAGECode>CAGE2</vendorCAGECode>
<vendorAccountNumber>40127254</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>1500006837</creditorInvoiceNumber>
<invoiceDate>2015-06-30</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>b3oooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">3844.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1683315</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-30</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026625</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0568</vendor>
<vendorAccountNumber>30092874</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>94043801</creditorInvoiceNumber>
<invoiceDate>2015-07-09</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>0CooOooooooooooOOoooOooOoOOoooOo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">438.5</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">190.008</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>4V</taxCode>
<taxAmount internationalCurrencyCode="CHF">32.48</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0472115</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-08</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026626</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0316</vendor>
<vendorCAGECode>CAGE3</vendorCAGECode>
<vendorAccountNumber>40099751</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>TL152062</creditorInvoiceNumber>
<invoiceDate>2015-07-02</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>3coooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">661.3</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0431815</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-01</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026627</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0440</vendor>
<vendorAccountNumber>2014686</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>TKL100216</creditorInvoiceNumber>
<invoiceDate>2015-06-17</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>55oooooOoOooooOoOoOOOoOOOoooOOoo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">699.92</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>L</orderType>
<orderNumber>L0032815</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-17</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026628</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0316</vendor>
<vendorCAGECode>CAGE4</vendorCAGECode>
<vendorAccountNumber>40099751</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>TL152063</creditorInvoiceNumber>
<invoiceDate>2015-07-02</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>9boooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">1983.0</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0431815</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-01</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026629</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0506</vendor>
<vendorAccountNumber>40128088</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>000359084</creditorInvoiceNumber>
<invoiceDate>2015-07-13</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>51oOoOoOoOoooooOOOoOooooOOoooOoO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">2230.76</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1735915</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-12</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026630</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0497</vendor>
<vendorAccountNumber>30090668</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>90864081</creditorInvoiceNumber>
<invoiceDate>2015-07-08</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>acoooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">1893.2</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>4V</taxCode>
<taxAmount internationalCurrencyCode="CHF">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0470615</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-07</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026631</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0512</vendor>
<vendorAccountNumber>40128846</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>123939</creditorInvoiceNumber>
<invoiceDate>2015-07-08</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>09oooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">7896.34</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>TAX</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0400015</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-07</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026633</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0202</vendor>
<vendorAccountNumber>40128088</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>000358117</creditorInvoiceNumber>
<invoiceDate>2015-07-07</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>f5oooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">6810.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">3187.08</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0462815</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-06</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026635</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0011</vendor>
<vendorAccountNumber>30124373</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>M90257500</creditorInvoiceNumber>
<invoiceDate>2015-07-13</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>C3oOOOooOoOooOOOoooOOOoOOoooOoOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">16300.5</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="CHF">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1488615</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-12</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026637</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0139</vendor>
<vendorAccountNumber>30124373</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>M90257457</creditorInvoiceNumber>
<invoiceDate>2015-07-13</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>60ooooOooOOOoOoOoooooooOOOOoooOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">831.9</totalAmount>
<nettoAmount internationalCurrencyCode="USD">334.1052</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">118.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0463815</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-12</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
<invoiceCharges>
<chargeType>
<chargeCode>H</chargeCode>
<description>HANDLING CHARGE</description>
<isTax>N</isTax>
<affectsAveragePrice>N</affectsAveragePrice>
</chargeType>
<accountNumber>400158</accountNumber>
<costType/>
<costcenter>7000</costcenter>
<financialCostcenter>7000</financialCostcenter>
<costcenter2/>
<chargeAmount>
<totalAmount internationalCurrencyCode="USD">55.224</totalAmount>
<nettoAmount internationalCurrencyCode="USD">55.224</nettoAmount>
<taxation>
<taxCode>V0</taxCode>
<financialTaxCode>V0</financialTaxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</chargeAmount>
<bookingType>D</bookingType>
</invoiceCharges>
</invoice>
<invoice>
<invoiceNumber>22026638</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0139</vendor>
<vendorAccountNumber>30124373</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>M90257509</creditorInvoiceNumber>
<invoiceDate>2015-07-13</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>60OoooooOOooooOoooooooooOOooOOOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">2218.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">982.8</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">118.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0491115</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-12</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
<invoiceCharges>
<chargeType>
<chargeCode>H</chargeCode>
<description>HANDLING CHARGE</description>
<isTax>N</isTax>
<affectsAveragePrice>N</affectsAveragePrice>
</chargeType>
<accountNumber>400158</accountNumber>
<costType/>
<costcenter>7000</costcenter>
<financialCostcenter>7000</financialCostcenter>
<costcenter2/>
<chargeAmount>
<totalAmount internationalCurrencyCode="USD">55.224</totalAmount>
<nettoAmount internationalCurrencyCode="USD">55.224</nettoAmount>
<taxation>
<taxCode>V0</taxCode>
<financialTaxCode>V0</financialTaxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</chargeAmount>
<bookingType>D</bookingType>
</invoiceCharges>
</invoice>
<invoice>
<invoiceNumber>22026639</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0162</vendor>
<vendorAccountNumber>30124373</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>M90257515</creditorInvoiceNumber>
<invoiceDate>2015-07-13</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>A6OOooOoOoOooOoooooooooOooooOOoo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">5833.2</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="CHF">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1575215</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-12</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026642</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGE5</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 335835</creditorInvoiceNumber>
<invoiceDate>2015-07-01</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>16OooooOooOOoOooooOoooooooooooOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">515.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1612715</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-31</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026643</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGE6</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 335833</creditorInvoiceNumber>
<invoiceDate>2015-07-01</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>58OOoOOooooOooOOooOoooOooooOOoOo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">835.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1441715</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-31</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026644</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGE7</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 336036</creditorInvoiceNumber>
<invoiceDate>2015-07-06</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>6BooooOOoooOooOooooOooooOoOOoooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">515.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1659015</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-05</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026645</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGE8</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 335836</creditorInvoiceNumber>
<invoiceDate>2015-07-01</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>6DoOoooOooOOoOooOoOoOoOOOoOoOooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">515.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1613415</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-31</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026646</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGE9</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 336201</creditorInvoiceNumber>
<invoiceDate>2015-07-08</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>74ooOoOooooooooOoOOOoOoOooOoooOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">515.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1728915</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-07</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026647</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGEA</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 336035</creditorInvoiceNumber>
<invoiceDate>2015-07-06</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>86OoooOOoooOoooOOoOooOoooOOoOoOo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">515.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1612615</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-05</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026648</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGEB</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 336034</creditorInvoiceNumber>
<invoiceDate>2015-07-06</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>99OOooooooOooOooooOooOooOoOOoOoo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">835.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1445115</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-05</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026649</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0400</vendor>
<vendorCAGECode>CAGEC</vendorCAGECode>
<vendorAccountNumber>40126141</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>C/5 335834</creditorInvoiceNumber>
<invoiceDate>2015-07-01</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>D8OOoooOOOooooOOoooOOoOoooOoOOOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">835.0</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1445315</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-31</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026650</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0429</vendor>
<vendorAccountNumber>30090682</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>351732</creditorInvoiceNumber>
<invoiceDate>2015-07-06</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>4BooOooooOOOoOOOOooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">192.8</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>4V</taxCode>
<taxAmount internationalCurrencyCode="CHF">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0448015</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-05</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026651</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0429</vendor>
<vendorAccountNumber>30090682</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>351730</creditorInvoiceNumber>
<invoiceDate>2015-07-06</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>69ooOoOooooooooooOoOooOOOOoooOoO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">57.25</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">17.784</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">15.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>4V</taxCode>
<taxAmount internationalCurrencyCode="CHF">4.24</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0451715</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-05</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
<invoiceCharges>
<chargeType>
<chargeCode>F</chargeCode>
<description>FREIGHT</description>
<isTax>N</isTax>
<affectsAveragePrice>N</affectsAveragePrice>
</chargeType>
<accountNumber>400122</accountNumber>
<costType/>
<costcenter>7000</costcenter>
<financialCostcenter>7000</financialCostcenter>
<costcenter2/>
<chargeAmount>
<totalAmount internationalCurrencyCode="CHF">7.02</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">7.02</nettoAmount>
<taxation>
<taxCode>4V</taxCode>
<financialTaxCode>4V</financialTaxCode>
<taxAmount internationalCurrencyCode="CHF">0.5616</taxAmount>
</taxation>
</chargeAmount>
<bookingType>D</bookingType>
</invoiceCharges>
</invoice>
<invoice>
<invoiceNumber>22026652</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0429</vendor>
<vendorAccountNumber>30090682</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>351731</creditorInvoiceNumber>
<invoiceDate>2015-07-06</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>A9oooooooOoOooOOOoOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">100.05</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>4V</taxCode>
<taxAmount internationalCurrencyCode="CHF">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0448015</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-05</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026653</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0028</vendor>
<vendorCAGECode>CAGED</vendorCAGECode>
<vendorAccountNumber>40096899</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>05/91014407</creditorInvoiceNumber>
<invoiceDate>2015-07-07</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>22oooOooooOooOooOOoOooOoooooOooO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">225.0</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1727915</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-06</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026654</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0028</vendor>
<vendorCAGECode>CAGEE</vendorCAGECode>
<vendorAccountNumber>40096899</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>05/91015508</creditorInvoiceNumber>
<invoiceDate>2015-07-07</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>24OooooOOoOooOoOoOoOoooOOoOOooOo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">225.0</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1728015</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-06</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026655</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0028</vendor>
<vendorCAGECode>CAGEF</vendorCAGECode>
<vendorAccountNumber>40096899</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>05/91015531</creditorInvoiceNumber>
<invoiceDate>2015-07-01</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>76oOOOOooOoOooooOOoOoOOooOooOoOO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">768.45</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">359.6346</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>W</orderType>
<orderNumber>W0054415</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-07-31</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026656</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0651</vendor>
<vendorAccountNumber>40126601</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>SI156008034</creditorInvoiceNumber>
<invoiceDate>2015-07-08</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>96OooooOoOoooOOOoooOOoooOoOOOOoO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">261.79</totalAmount>
<nettoAmount internationalCurrencyCode="USD">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0479215</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-07</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.93021</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026657</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0028</vendor>
<vendorCAGECode>CAGEG</vendorCAGECode>
<vendorAccountNumber>40096899</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>05/91015509</creditorInvoiceNumber>
<invoiceDate>2015-07-09</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>99ooOoOOoooooOooooOOOOoooOOoOOoO</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">705.35</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">330.1038</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>R</orderType>
<orderNumber>R1625015</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-08</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026662</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0495</vendor>
<vendorCAGECode>CAGEH</vendorCAGECode>
<vendorAccountNumber>40091085</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>55941607</creditorInvoiceNumber>
<invoiceDate>2015-07-13</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>4BOoooOOOoOoooooOoOOooOooooOoOoo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">725.6</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0486115</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-12</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026663</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0604</vendor>
<vendorAccountNumber>30094003</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>100-120606</creditorInvoiceNumber>
<invoiceDate>2015-07-08</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>0boooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">4229.5</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">1347.84</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">1036.2</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>TAX</taxCode>
<taxAmount internationalCurrencyCode="CHF">313.3</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0474115</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-07</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
<invoiceCharges>
<chargeType>
<chargeCode>H</chargeCode>
<description>HANDLING CHARGE</description>
<isTax>N</isTax>
<affectsAveragePrice>N</affectsAveragePrice>
</chargeType>
<accountNumber>400158</accountNumber>
<costType/>
<costcenter>7000</costcenter>
<financialCostcenter>7000</financialCostcenter>
<costcenter2/>
<chargeAmount>
<totalAmount internationalCurrencyCode="CHF">430.56</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">430.56</nettoAmount>
<taxation>
<taxCode>4V</taxCode>
<financialTaxCode>4V</financialTaxCode>
<taxAmount internationalCurrencyCode="CHF">34.4448</taxAmount>
</taxation>
</chargeAmount>
<bookingType>D</bookingType>
</invoiceCharges>
<invoiceCharges>
<chargeType>
<chargeCode>F</chargeCode>
<description>FREIGHT</description>
<isTax>N</isTax>
<affectsAveragePrice>N</affectsAveragePrice>
</chargeType>
<accountNumber>400122</accountNumber>
<costType/>
<costcenter>7000</costcenter>
<financialCostcenter>7000</financialCostcenter>
<costcenter2/>
<chargeAmount>
<totalAmount internationalCurrencyCode="CHF">54.3816</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">54.3816</nettoAmount>
<taxation>
<taxCode>4V</taxCode>
<financialTaxCode>4V</financialTaxCode>
<taxAmount internationalCurrencyCode="CHF">4.3524</taxAmount>
</taxation>
</chargeAmount>
<bookingType>D</bookingType>
</invoiceCharges>
</invoice>
<invoice>
<invoiceNumber>22026664</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0634</vendor>
<vendorAccountNumber>30092269</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>13143106</creditorInvoiceNumber>
<invoiceDate>2015-07-07</invoiceDate>
<closingDate>2015-07-16</closingDate>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>6eoooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">318.65</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">124.0434</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">30.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>4V</taxCode>
<taxAmount internationalCurrencyCode="CHF">23.599999999999998</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0468115</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-06</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
<invoiceCharges>
<chargeType>
<chargeCode>F</chargeCode>
<description>FREIGHT</description>
<isTax>N</isTax>
<affectsAveragePrice>N</affectsAveragePrice>
</chargeType>
<accountNumber>400122</accountNumber>
<costType/>
<costcenter>7000</costcenter>
<financialCostcenter>7000</financialCostcenter>
<costcenter2/>
<chargeAmount>
<totalAmount internationalCurrencyCode="CHF">14.04</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">14.04</nettoAmount>
<taxation>
<taxCode>4V</taxCode>
<financialTaxCode>4V</financialTaxCode>
<taxAmount internationalCurrencyCode="CHF">1.1232</taxAmount>
</taxation>
</chargeAmount>
<bookingType>D</bookingType>
</invoiceCharges>
</invoice>
<invoice>
<invoiceNumber>22026665</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0316</vendor>
<vendorCAGECode>CAGEI</vendorCAGECode>
<vendorAccountNumber>40099751</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>TL152315</creditorInvoiceNumber>
<invoiceDate>2015-07-09</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>74oooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">1983.9</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0431815</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-08</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>22026667</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>OPEN</invoiceState>
<type>I</type>
<vendor>V0642</vendor>
<vendorAccountNumber>40129316</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>11321</creditorInvoiceNumber>
<invoiceDate>2015-07-10</invoiceDate>
<closingDate/>
<bookingDate>2015-07-16</bookingDate>
<createdDate>2015-07-16</createdDate>
<invoiceText>caoooooooooooooooooooooooooooooo</invoiceText>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">840.0</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">0.0</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>P</orderType>
<orderNumber>P0471915</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>30D</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-08-09</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>07</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.04688</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>76278995</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0166</vendor>
<vendorCAGECode>CAGEJ</vendorCAGECode>
<vendorAccountNumber>VERB05001</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>76278995</creditorInvoiceNumber>
<invoiceDate>2015-04-01</invoiceDate>
<closingDate>2015-04-17</closingDate>
<bookingDate>2015-04-17</bookingDate>
<createdDate>2015-04-17</createdDate>
<invoiceAmount>
<totalAmount internationalCurrencyCode="EUR">7833.33</totalAmount>
<nettoAmount internationalCurrencyCode="EUR">3394.4414</nettoAmount>
<handlingAmount internationalCurrencyCode="EUR">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>V0</taxCode>
<taxAmount internationalCurrencyCode="EUR">580.25</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>S</orderType>
<orderNumber>S0026415</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>Y</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code/>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2015-04-01</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>Y</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>04</financialPeriodMonth>
<financialPeriodYear>2015</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>EUR</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.05531</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>90149059</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0016</vendor>
<vendorAccountNumber>30124373</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>M90149059</creditorInvoiceNumber>
<invoiceDate>2011-02-09</invoiceDate>
<closingDate>2011-02-18</closingDate>
<bookingDate>2011-02-18</bookingDate>
<createdDate>2011-02-18</createdDate>
<invoiceAmount>
<totalAmount internationalCurrencyCode="CHF">1077.3</totalAmount>
<nettoAmount internationalCurrencyCode="CHF">504.1764</nettoAmount>
<handlingAmount internationalCurrencyCode="CHF">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>TAX</taxCode>
<taxAmount internationalCurrencyCode="CHF">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>S</orderType>
<orderNumber>S0080410</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>N</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>5</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2011-02-09</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>N</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>03</financialPeriodMonth>
<financialPeriodYear>2011</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>CHF</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>1.0</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
<invoice>
<invoiceNumber>90149062</invoiceNumber>
<invoiceHeader>
<entityInformation>
<entityCode>CRX</entityCode>
<currency>CHF</currency>
</entityInformation>
<invoiceState>CLOSED</invoiceState>
<type>I</type>
<vendor>V0016</vendor>
<vendorAccountNumber>30124374</vendorAccountNumber>
<mandator/>
<creditorInvoiceNumber>90149062</creditorInvoiceNumber>
<invoiceDate>2011-02-09</invoiceDate>
<closingDate>2011-02-21</closingDate>
<bookingDate>2011-02-21</bookingDate>
<createdDate>2011-02-21</createdDate>
<invoiceAmount>
<totalAmount internationalCurrencyCode="USD">2185.78</totalAmount>
<nettoAmount internationalCurrencyCode="USD">1022.945</nettoAmount>
<handlingAmount internationalCurrencyCode="USD">0.0</handlingAmount>
<discount>0.0</discount>
<taxation>
<taxCode>TAX</taxCode>
<taxAmount internationalCurrencyCode="USD">0.0</taxAmount>
</taxation>
</invoiceAmount>
<orderInformation>
<orderType>S</orderType>
<orderNumber>S0125011</orderNumber>
</orderInformation>
<invoiceTransferInformation>
<transferDate>2016-02-12</transferDate>
<preTransferDate/>
<transferRelease>N</transferRelease>
</invoiceTransferInformation>
<paymentInformation>
<paymentCondition>
<code>6</code>
</paymentCondition>
<paymentMode>
<code/>
</paymentMode>
<paymentDate/>
<paymentDueDate>2011-02-09</paymentDueDate>
<paymentReminderCount>0</paymentReminderCount>
<paymentRelease>N</paymentRelease>
</paymentInformation>
<financialPeriodInformation>
<financialPeriodMonth>03</financialPeriodMonth>
<financialPeriodYear>2011</financialPeriodYear>
</financialPeriodInformation>
<currencyConversionInformation>
<targetCurrency>USD</targetCurrency>
<sourceCurrency>CHF</sourceCurrency>
<conversionRate>0.95702</conversionRate>
</currencyConversionInformation>
</invoiceHeader>
</invoice>
</transferInvoice>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Invoice Transfer XSLT
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt" version="1.0">
<!--<xsl:output method="xml" indent="yes"/>-->
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:decimal-format name="european" decimal-separator="," grouping-separator="'"/>
<!-- Definition of global constants -->
<xsl:variable name="batchSTYPE">0</xsl:variable>
<xsl:variable name="batchGROUP">fto-erech</xsl:variable>
<xsl:variable name="batchMANDT">200</xsl:variable>
<xsl:variable name="batchUSNAM">amos-batch</xsl:variable>
<xsl:variable name="batchSTART">00000000</xsl:variable>
<xsl:variable name="batchXKEEP">X</xsl:variable>
<!-- KREDI constants -->
<xsl:variable name="constTCODE">FB01</xsl:variable>
<xsl:variable name="constBLART">TP</xsl:variable>
<xsl:variable name="constBUKRS">EWF</xsl:variable>
<!-- LZBKZ constants
"566" for S-Orders and "950" for all the rest -->
<xsl:variable name="constLZBZK_S_ORDER">566</xsl:variable>
<xsl:variable name="constLZBZK_OTHER">950</xsl:variable>
<!-- Tax code uised for charges flagged as "TAX" -->
<xsl:variable name="taxCodeConst">2w</xsl:variable>
<!-- Tax code used for all other occurences in file -->
<xsl:variable name="taxCodeDefaultConst">V0</xsl:variable>
<!-- entry point -->
<xsl:template match="/">
<xsl:variable name="transformation_1">
<xsl:call-template name="transformation_1_elements"/>
</xsl:variable>
<xsl:variable name="transformation_2">
<transformation_2_elements>
<batchInformation>
<xsl:call-template name="batchInformation"/>
</batchInformation>
<xsl:for-each select="exslt:node-set($transformation_1)">
<xsl:apply-templates select="transformation_1_elements"/>
</xsl:for-each>
</transformation_2_elements>
</xsl:variable>
<xsl:variable name="transformation_3">
<transformation_3_elements>
<xsl:for-each select="exslt:node-set($transformation_2)">
<xsl:apply-templates select="transformation_2_elements"/>
</xsl:for-each>
</transformation_3_elements>
</xsl:variable>
<!-- text output -->
<xsl:for-each select="exslt:node-set($transformation_3)">
<xsl:apply-templates select="transformation_3_elements" />
</xsl:for-each>
<!-- xml output
<xsl:for-each select="exslt:node-set($transformation_3)">
<xsl:copy-of select="."/>
</xsl:for-each>-->
</xsl:template>
<xsl:template match="transformation_3_elements">
<xsl:for-each select="*">
<xsl:call-template name="Fill_Up" />
</xsl:for-each>
</xsl:template>
<xsl:template name="Fill_Up">
<xsl:for-each select="*">
<xsl:variable name="align">
<xsl:value-of select="@Alignment" />
</xsl:variable>
<xsl:variable name="filler">
<xsl:value-of select="@Filler" />
</xsl:variable>
<xsl:variable name="length">
<xsl:value-of select="@Length" />
</xsl:variable>
<xsl:variable name="tagValue">
<xsl:value-of select="." />
</xsl:variable>
<xsl:variable name="defaultFiller">
<xsl:choose>
<xsl:when test="$filler = 'blank'">
<!-- make empty fields to be filled with '/' -->
<xsl:choose>
<xsl:when test="$tagValue = '/'">
<xsl:value-of select="'/'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' '" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$filler" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="justify">
<xsl:with-param name="align" select="$align" />
<xsl:with-param name="filler" select="$defaultFiller" />
<xsl:with-param name="value" select="$tagValue" />
<xsl:with-param name="width" select="$length" />
</xsl:call-template>
</xsl:for-each>
<xsl:text>&#xa;</xsl:text>
</xsl:template>
<!-- start transformation_3 -->
<xsl:template match="transformation_2_elements">
<xsl:apply-templates select="batchInformation" />
<xsl:apply-templates select="invoice_elements" mode="transformation_3" />
</xsl:template>
<xsl:template match="invoice_elements" mode="transformation_3">
<xsl:for-each select="*">
<xsl:if test="contains(name(),'header_elements')">
<xsl:call-template name="header_elements_copy" />
</xsl:if>
<xsl:if test="contains(name(),'header_1_elements')">
<xsl:call-template name="header_1_elements_copy" />
</xsl:if>
<xsl:if test="contains(name(),'invoiceCharges_1_elements')">
<xsl:call-template name="invoiceCharges_1_elements_copy" />
</xsl:if>
<xsl:if test="contains(name(),'invoiceDetails_1_elements')">
<xsl:call-template name="invoiceDetails_1_elements_copy" />
</xsl:if>
<xsl:if test="contains(name(),'invoiceDetails_DetailCharges_1_elements')">
<xsl:call-template name="invoiceDetails_DetailCharges_1_elements_copy" />
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="batchInformation">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template name="header_elements_copy">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template name="header_1_elements_copy">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template name="invoiceCharges_1_elements_copy">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template name="invoiceDetails_1_elements_copy">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template name="invoiceDetails_DetailCharges_1_elements_copy">
<xsl:copy-of select="." />
</xsl:template>
<!-- end transformation_3 -->
<!-- start transformation_2 -->
<xsl:template name="batchInformation">
<STYPE ID="1" Length="1" Alignment="left" Filler="blank">
<xsl:value-of select="$batchSTYPE" />
</STYPE>
<GROUP ID="2" Length="12" Alignment="left" Filler="blank">
<xsl:value-of select="$batchGROUP" />
</GROUP>
<MANDT ID="3" Length="3" Alignment="left" Filler="blank">
<xsl:value-of select="$batchMANDT" />
</MANDT>
<USNAM ID="4" Length="12" Alignment="left" Filler="blank">
<xsl:value-of select="$batchUSNAM" />
</USNAM>
<START ID="5" Length="8" Alignment="left" Filler="blank">
<xsl:value-of select="$batchSTART" />
</START>
<XKEEP ID="6" Length="1" Alignment="left" Filler="blank">
<xsl:value-of select="$batchXKEEP" />
</XKEEP>
<NODATA ID="7" Length="1" Alignment="left" Filler="blank">/</NODATA>
</xsl:template>
<xsl:template match="transformation_1_elements">
<xsl:apply-templates select="invoice_elements" mode="transformation_2"/>
</xsl:template>
<xsl:template match="invoice_elements" mode="transformation_2">
<invoice_elements>
<xsl:for-each select="@*">
<xsl:attribute name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:call-template name="header_elements"/>
<xsl:call-template name="header_1_elements"/>
<xsl:for-each select="*[count(./*) &gt; 0]">
<xsl:if test="contains(name(),'invoiceCharges_elements')">
<xsl:call-template name="invoiceCharges_1_elements"/>
</xsl:if>
<xsl:if test="contains(name(),'invoiceDetails_elements')">
<xsl:call-template name="invoiceDetails_1_elements"/>
</xsl:if>
<xsl:if test="contains(name(),'invoiceDetails_DetailCharges_elements')">
<xsl:call-template name="invoiceDetails_DetailCharges_1_elements"/>
</xsl:if>
</xsl:for-each>
</invoice_elements>
</xsl:template>
<xsl:template name="header_elements">
<header_elements>
<STYPE ID="1" Length="1" Alignment="left" Filler="blank">1</STYPE>
<TCODE ID="2" Length="20" Alignment="left" Filler="blank">
<xsl:value-of select="$constTCODE" />
</TCODE>
<!-- create invoice date -->
<xsl:variable name="invoiceDate">
<xsl:call-template name="getFormatedDate">
<xsl:with-param name="date2format" select="invoiceDate"/>
</xsl:call-template>
</xsl:variable>
<!-- create invoice date month -->
<xsl:variable name="invoiceMonth">
<xsl:call-template name="getMonthOfDate">
<xsl:with-param name="date2format" select="invoiceDate"/>
</xsl:call-template>
</xsl:variable>
<BLDAT ID="3" Length="8" Alignment="left" Filler="blank">
<xsl:value-of select="$invoiceDate" />
</BLDAT>
<BLART ID="4" Length="2" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="(invoiceNumber &gt; 0051053500) and (invoiceNumber &lt; 0051999999)">KA</xsl:when>
<xsl:when test="(invoiceNumber &gt; 0054012000) and (invoiceNumber &lt; 0054999999)">EA</xsl:when>
<xsl:otherwise> </xsl:otherwise>
</xsl:choose>
</BLART>
<BUKRS ID="5" Length="4" Alignment="left" Filler="blank">
<xsl:value-of select="$constBUKRS" />
</BUKRS>
<!-- create transfer date -->
<xsl:variable name="transferDate">
<xsl:call-template name="getFormatedDate">
<xsl:with-param name="date2format" select="transferDate"/>
</xsl:call-template>
</xsl:variable>
<BUDAT ID="6" Length="8" Alignment="left" Filler="blank">
<xsl:value-of select="$transferDate" />
</BUDAT>
<MONAT ID="7" Length="2" Alignment="left" Filler="blank">
<xsl:value-of select="$invoiceMonth" />
</MONAT>
<WAERS ID="8" Length="5" Alignment="left" Filler="blank">
<xsl:value-of select="targetCurrency" />
</WAERS>
<KURSF ID="9" Length="10" Alignment="left" Filler="blank">
<xsl:value-of select="format-number(conversionRate, '0000,00000', 'european')"/>
</KURSF>
<!--<BELNR ID="10" Length="10" Alignment="left" Filler="blank">/</BELNR>-->
<BELNR ID="10" Length="10" Alignment="left" Filler="blank">
<xsl:value-of select="invoiceNumber" />
</BELNR>
<WWERT ID="11" Length="8" Alignment="left" Filler="blank">/</WWERT>
<XBLNR ID="12" Length="16" Alignment="left" Filler="blank">
<xsl:value-of select="creditorInvoiceNumber" />
</XBLNR>
<BVORG ID="13" Length="16" Alignment="left" Filler="blank">/</BVORG>
<BKTXT ID="14" Length="25" Alignment="left" Filler="blank">/</BKTXT>
<PARGB ID="15" Length="4" Alignment="left" Filler="blank">/</PARGB>
<AUGLV ID="16" Length="8" Alignment="left" Filler="blank">/</AUGLV>
<VBUND ID="17" Length="6" Alignment="left" Filler="blank">/</VBUND>
<XMWST ID="18" Length="1" Alignment="left" Filler="blank">X</XMWST>
<DOCID ID="19" Length="10" Alignment="left" Filler="blank">/</DOCID>
<BARCD ID="20" Length="40" Alignment="left" Filler="blank">/</BARCD>
<STODT ID="21" Length="8" Alignment="left" Filler="blank">/</STODT>
<BRNCH ID="22" Length="4" Alignment="left" Filler="blank">/</BRNCH>
<NUMPG ID="23" Length="3" Alignment="left" Filler="blank">/</NUMPG>
<STGRD ID="24" Length="2" Alignment="left" Filler="blank">/</STGRD>
<KURSF_M ID="25" Length="10" Alignment="left" Filler="blank">/</KURSF_M>
<AUGTX ID="26" Length="50" Alignment="left" Filler="blank">/</AUGTX>
<XPRFG ID="27" Length="1" Alignment="left" Filler="blank">/</XPRFG>
<XBWAE ID="28" Length="1" Alignment="left" Filler="blank">/</XBWAE>
<LDGRP ID="29" Length="4" Alignment="left" Filler="blank">/</LDGRP>
<PROPMANO ID="30" Length="13" Alignment="left" Filler="blank">/</PROPMANO>
<VATDATE ID="31" Length="8" Alignment="left" Filler="blank">/</VATDATE>
<SENDE ID="32" Length="1" Alignment="left" Filler="blank">/</SENDE>
</header_elements>
</xsl:template>
<xsl:template name="header_1_elements">
<!-- KREDITOR SECTION -->
<header_1_elements>
<STYPE ID="1" Length="1" Alignment="left" Filler="blank">2</STYPE>
<TBNAM ID="2" Length="30" Alignment="left" Filler="blank">BBSEG</TBNAM>
<NEWBS ID="3" Length="2" Alignment="left" Filler="blank">
<xsl:if test="type='I'">31</xsl:if>
<xsl:if test="type='C'">21</xsl:if>
</NEWBS>
<DUMMYX ID="4" Length="10" Alignment="left" Filler="blank">/</DUMMYX>
<NEWUM ID="5" Length="1" Alignment="left" Filler="blank">/</NEWUM>
<NEWBK ID="6" Length="4" Alignment="left" Filler="blank">/</NEWBK>
<WRBTR ID="7" Length="16" Alignment="left" Filler="blank">
<!-- <xsl:value-of select="format-number(totalAmount, '#0.00', 'european')"/> -->
<xsl:value-of select="format-number(totalAmount, '0000000000000,00', 'european')"/>
</WRBTR>
<DMBTR ID="8" Length="16" Alignment="left" Filler="blank">/</DMBTR>
<WMWST ID="9" Length="16" Alignment="left" Filler="blank">/</WMWST>
<MWSTS ID="10" Length="16" Alignment="left" Filler="blank">/</MWSTS>
<MWSKZ ID="11" Length="2" Alignment="left" Filler="blank">
<xsl:value-of select="financialTaxCode" />
</MWSKZ>
<XSKRL ID="12" Length="1" Alignment="left" Filler="blank">/</XSKRL>
<FWZUZ ID="13" Length="16" Alignment="left" Filler="blank">/</FWZUZ>
<HWZUZ ID="14" Length="16" Alignment="left" Filler="blank">/</HWZUZ>
<GSBER ID="15" Length="4" Alignment="left" Filler="blank">/</GSBER>
<KOSTL ID="16" Length="10" Alignment="left" Filler="blank">/</KOSTL>
<DUMMY4 ID="17" Length="4" Alignment="left" Filler="blank">/</DUMMY4>
<AUFNR ID="18" Length="12" Alignment="left" Filler="blank">/</AUFNR>
<EBELN ID="19" Length="10" Alignment="left" Filler="blank">/</EBELN>
<EBELP ID="20" Length="5" Alignment="left" Filler="blank">/</EBELP>
<PROJN ID="21" Length="16" Alignment="left" Filler="blank">/</PROJN>
<MATNR ID="22" Length="18" Alignment="left" Filler="blank">/</MATNR>
<WERKS ID="23" Length="4" Alignment="left" Filler="blank">/</WERKS>
<MENGE ID="24" Length="17" Alignment="left" Filler="blank">/</MENGE>
<MEINS ID="25" Length="3" Alignment="left" Filler="blank">/</MEINS>
<VBEL2 ID="26" Length="10" Alignment="left" Filler="blank">/</VBEL2>
<POSN2 ID="27" Length="6" Alignment="left" Filler="blank">/</POSN2>
<ETEN2 ID="28" Length="4" Alignment="left" Filler="blank">/</ETEN2>
<PERNR ID="29" Length="8" Alignment="left" Filler="blank">/</PERNR>
<BEWAR ID="30" Length="3" Alignment="left" Filler="blank">/</BEWAR>
<VALUT ID="31" Length="8" Alignment="left" Filler="blank">/</VALUT>
<ZFBDT ID="32" Length="8" Alignment="left" Filler="blank">/</ZFBDT>
<ZINKZ ID="33" Length="2" Alignment="left" Filler="blank">/</ZINKZ>
<ZUONR ID="34" Length="18" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="invoiceText and string-length(invoiceText) &gt; 0">
<!-- <xsl:value-of select="invoiceText" /> -->
<xsl:value-of select="normalize-space(invoiceText)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</ZUONR>
<FKONT ID="35" Length="3" Alignment="left" Filler="blank">/</FKONT>
<XAABG ID="36" Length="1" Alignment="left" Filler="blank">/</XAABG>
<SGTXT ID="37" Length="50" Alignment="left" Filler="blank">
<!-- fa_period Month/fa_period Year Orderno projectno cost_type -->
<xsl:variable name="twoDigitYear">
<xsl:value-of select="substring(financialPeriodYear, 3, 4)"/>
</xsl:variable>
<xsl:value-of select="$twoDigitYear" />
<xsl:value-of select="'/'" />
<xsl:value-of select="financialPeriodMonth" />
<xsl:value-of select="' '" />
<xsl:value-of select="orderNumber" />
</SGTXT>
<BLNKZ ID="38" Length="2" Alignment="left" Filler="blank">/</BLNKZ>
<BLNBT ID="39" Alignment="left" Filler="blank" Length="16">/</BLNBT>
<BLNPZ ID="40" Alignment="left" Filler="blank" Length="8">/</BLNPZ>
<MABER ID="41" Alignment="left" Filler="blank" Length="2">/</MABER>
<SKFBT ID="42" Alignment="left" Filler="blank" Length="16">/</SKFBT>
<WSKTO ID="43" Alignment="left" Filler="blank" Length="16">/</WSKTO>
<ZTERM ID="44" Alignment="left" Filler="blank" Length="4">/</ZTERM>
<ZBD1T ID="45" Alignment="left" Filler="blank" Length="3">/</ZBD1T>
<ZBD1P ID="46" Alignment="left" Filler="blank" Length="6">/</ZBD1P>
<ZBD2T ID="47" Alignment="left" Filler="blank" Length="3">/</ZBD2T>
<ZBD2P ID="48" Alignment="left" Filler="blank" Length="6">/</ZBD2P>
<ZBD3T ID="49" Alignment="left" Filler="blank" Length="3">/</ZBD3T>
<ZLSPR ID="50" Alignment="left" Filler="blank" Length="1">/</ZLSPR>
<REBZG ID="51" Alignment="left" Filler="blank" Length="10">/</REBZG>
<REBZJ ID="52" Alignment="left" Filler="blank" Length="4">/</REBZJ>
<REBZZ ID="53" Alignment="left" Filler="blank" Length="3">/</REBZZ>
<ZLSCH ID="54" Alignment="left" Filler="blank" Length="1">/</ZLSCH>
<SAMNR ID="55" Alignment="left" Filler="blank" Length="8">/</SAMNR>
<ZBFIX ID="56" Alignment="left" Filler="blank" Length="1">/</ZBFIX>
<QSSKZ ID="57" Alignment="left" Filler="blank" Length="2">/</QSSKZ>
<QSSHB ID="58" Alignment="left" Filler="blank" Length="16">/</QSSHB>
<QSFBT ID="59" Alignment="left" Filler="blank" Length="16">/</QSFBT>
<ESRNR ID="60" Alignment="left" Filler="blank" Length="11">/</ESRNR>
<ESRPZ ID="61" Alignment="left" Filler="blank" Length="2">/</ESRPZ>
<ESRRE ID="62" Alignment="left" Filler="blank" Length="27">/</ESRRE>
<FDTAG ID="63" Alignment="left" Filler="blank" Length="8">/</FDTAG>
<FDLEV ID="64" Alignment="left" Filler="blank" Length="2">/</FDLEV>
<ANLN1 ID="65" Alignment="left" Filler="blank" Length="12">/</ANLN1>
<ANLN2 ID="66" Alignment="left" Filler="blank" Length="4">/</ANLN2>
<BZDAT ID="67" Alignment="left" Filler="blank" Length="8">/</BZDAT>
<ANBWA ID="68" Alignment="left" Filler="blank" Length="3">/</ANBWA>
<ABPER ID="69" Alignment="left" Filler="blank" Length="7">/</ABPER>
<GBETR ID="70" Alignment="left" Filler="blank" Length="16">/</GBETR>
<KURSR ID="71" Alignment="left" Filler="blank" Length="10">/</KURSR>
<MANSP ID="72" Alignment="left" Filler="blank" Length="1">/</MANSP>
<MSCHL ID="73" Alignment="left" Filler="blank" Length="1">/</MSCHL>
<HBKID ID="74" Alignment="left" Filler="blank" Length="5">/</HBKID>
<BVTYP ID="75" Alignment="left" Filler="blank" Length="4">/</BVTYP>
<ANFBN ID="76" Alignment="left" Filler="blank" Length="10">/</ANFBN>
<ANFBU ID="77" Alignment="left" Filler="blank" Length="4">/</ANFBU>
<ANFBJ ID="78" Alignment="left" Filler="blank" Length="4">/</ANFBJ>
<LZBKZ ID="79" Alignment="left" Filler="blank" Length="3">
<xsl:choose>
<xsl:when test="orderType='S'">
<xsl:value-of select="$constLZBZK_S_ORDER" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$constLZBZK_OTHER" />
</xsl:otherwise>
</xsl:choose>
</LZBKZ>
<LANDL ID="80" Alignment="left" Filler="blank" Length="3">/</LANDL>
<DIEKZ ID="81" Alignment="left" Filler="blank" Length="1">/</DIEKZ>
<ZOLLD ID="82" Alignment="left" Filler="blank" Length="8">/</ZOLLD>
<ZOLLT ID="83" Alignment="left" Filler="blank" Length="8">/</ZOLLT>
<VRSDT ID="84" Alignment="left" Filler="blank" Length="8">/</VRSDT>
<VRSKZ ID="85" Alignment="left" Filler="blank" Length="1">/</VRSKZ>
<HZUON ID="86" Alignment="left" Filler="blank" Length="18">/</HZUON>
<REGUL ID="87" Alignment="left" Filler="blank" Length="1">/</REGUL>
<NAME1 ID="88" Alignment="left" Filler="blank" Length="35">/</NAME1>
<NAME2 ID="89" Alignment="left" Filler="blank" Length="35">/</NAME2>
<NAME3 ID="90" Alignment="left" Filler="blank" Length="35">/</NAME3>
<NAME4 ID="91" Alignment="left" Filler="blank" Length="35">/</NAME4>
<STRAS ID="92" Alignment="left" Filler="blank" Length="35">/</STRAS>
<ORT01 ID="93" Alignment="left" Filler="blank" Length="35">/</ORT01>
<PSTLZ ID="94" Alignment="left" Filler="blank" Length="10">/</PSTLZ>
<LAND1 ID="95" Alignment="left" Filler="blank" Length="3">/</LAND1>
<REGIO ID="96" Alignment="left" Filler="blank" Length="3">/</REGIO>
<BANKL ID="97" Alignment="left" Filler="blank" Length="15">/</BANKL>
<BANKS ID="98" Alignment="left" Filler="blank" Length="3">/</BANKS>
<BANKN ID="99" Alignment="left" Filler="blank" Length="18">/</BANKN>
<BKONT ID="100" Alignment="left" Filler="blank" Length="2">/</BKONT>
<STCD1 ID="101" Alignment="left" Filler="blank" Length="16">/</STCD1>
<STCD2 ID="102" Alignment="left" Filler="blank" Length="11">/</STCD2>
<MADAT ID="103" Alignment="left" Filler="blank" Length="8">/</MADAT>
<MANST ID="104" Alignment="left" Filler="blank" Length="1">/</MANST>
<EGMLD ID="105" Alignment="left" Filler="blank" Length="3">/</EGMLD>
<DUMMY2 ID="106" Alignment="left" Filler="blank" Length="3">/</DUMMY2>
<STCEG ID="107" Alignment="left" Filler="blank" Length="20">/</STCEG>
<STKZA ID="108" Alignment="left" Filler="blank" Length="1">/</STKZA>
<STKZU ID="109" Alignment="left" Filler="blank" Length="1">/</STKZU>
<PFACH ID="110" Alignment="left" Filler="blank" Length="10">/</PFACH>
<PSTL2 ID="111" Alignment="left" Filler="blank" Length="10">/</PSTL2>
<SPRAS ID="112" Alignment="left" Filler="blank" Length="1">/</SPRAS>
<XINVE ID="113" Alignment="left" Filler="blank" Length="1">/</XINVE>
<NEWKO ID="114" Alignment="left" Filler="blank" Length="17">
<xsl:value-of select="vendorAccountNumber" />
</NEWKO>
<NEWBW Length="3" Alignment="left" Filler="blank" ID="115">/</NEWBW>
<KNRZE Length="17" Alignment="left" Filler="blank" ID="116">/</KNRZE>
<HKONT Length="10" Alignment="left" Filler="blank" ID="117">/</HKONT>
<PRCTR Length="10" Alignment="left" Filler="blank" ID="118">/</PRCTR>
<VERTN Length="13" Alignment="left" Filler="blank" ID="119">/</VERTN>
<VERTT Length="1" Alignment="left" Filler="blank" ID="120">/</VERTT>
<VBEWA Length="4" Alignment="left" Filler="blank" ID="121">/</VBEWA>
<HWBAS Length="16" Alignment="left" Filler="blank" ID="122">/</HWBAS>
<FWBAS Length="16" Alignment="left" Filler="blank" ID="123">/</FWBAS>
<FIPOS Length="14" Alignment="left" Filler="blank" ID="124">/</FIPOS>
<VNAME Length="6" Alignment="left" Filler="blank" ID="125">/</VNAME>
<EGRUP Length="3" Alignment="left" Filler="blank" ID="126">/</EGRUP>
<BTYPE Length="2" Alignment="left" Filler="blank" ID="127">/</BTYPE>
<PAOBJNR Length="10" Alignment="left" Filler="blank" ID="128">/</PAOBJNR>
<KSTRG Length="12" Alignment="left" Filler="blank" ID="129">/</KSTRG>
<IMKEY Length="8" Alignment="left" Filler="blank" ID="130">/</IMKEY>
<DUMMY3 Length="8" Alignment="left" Filler="blank" ID="131">/</DUMMY3>
<VPTNR Length="10" Alignment="left" Filler="blank" ID="132">/</VPTNR>
<NPLNR Length="12" Alignment="left" Filler="blank" ID="133">/</NPLNR>
<VORNR Length="4" Alignment="left" Filler="blank" ID="134">/</VORNR>
<XEGDR Length="1" Alignment="left" Filler="blank" ID="135">/</XEGDR>
<RECID Length="2" Alignment="left" Filler="blank" ID="136">/</RECID>
<PPRCT Length="10" Alignment="left" Filler="blank" ID="137">/</PPRCT>
<PROJK Length="24" Alignment="left" Filler="blank" ID="138">/</PROJK>
<UZAWE Length="2" Alignment="left" Filler="blank" ID="139">/</UZAWE>
<TXJCD Length="15" Alignment="left" Filler="blank" ID="140">/</TXJCD>
<FISTL Length="16" Alignment="left" Filler="blank" ID="141">/</FISTL>
<GEBER Length="10" Alignment="left" Filler="blank" ID="142">/</GEBER>
<DMBE2 Length="16" Alignment="left" Filler="blank" ID="143">/</DMBE2>
<DMBE3 Length="16" Alignment="left" Filler="blank" ID="144">/</DMBE3>
<PARGB Length="4" Alignment="left" Filler="blank" ID="145">/</PARGB>
<XREF1 Length="12" Alignment="left" Filler="blank" ID="146">/</XREF1>
<XREF2 Length="12" Alignment="left" Filler="blank" ID="147">/</XREF2>
<KBLNR Length="10" Alignment="left" Filler="blank" ID="149">/</KBLNR>
<KBLPOS Length="3" Alignment="left" Filler="blank" ID="150">/</KBLPOS>
<WDATE Length="8" Alignment="left" Filler="blank" ID="151">/</WDATE>
<WGBKZ Length="1" Alignment="left" Filler="blank" ID="152">/</WGBKZ>
<XAKTZ Length="1" Alignment="left" Filler="blank" ID="153">/</XAKTZ>
<WNAME Length="30" Alignment="left" Filler="blank" ID="154">/</WNAME>
<WORT1 Length="30" Alignment="left" Filler="blank" ID="155">/</WORT1>
<WBZOG Length="30" Alignment="left" Filler="blank" ID="156">/</WBZOG>
<WORT2 Length="30" Alignment="left" Filler="blank" ID="157">/</WORT2>
<WBANK Length="60" Alignment="left" Filler="blank" ID="158">/</WBANK>
<WLZBP Length="60" Alignment="left" Filler="blank" ID="159">/</WLZBP>
<DISKP Length="8" Alignment="left" Filler="blank" ID="160">/</DISKP>
<DISKT Length="3" Alignment="left" Filler="blank" ID="161">/</DISKT>
<WINFW Length="16" Alignment="left" Filler="blank" ID="162">/</WINFW>
<WINHW Length="16" Alignment="left" Filler="blank" ID="163">/</WINHW>
<WEVWV Length="1" Alignment="left" Filler="blank" ID="164">/</WEVWV>
<WSTAT Length="1" Alignment="left" Filler="blank" ID="165">/</WSTAT>
<WMWKZ Length="2" Alignment="left" Filler="blank" ID="166">/</WMWKZ>
<WSTKZ Length="1" Alignment="left" Filler="blank" ID="167">/</WSTKZ>
<RKE_ARTNR Length="18" Alignment="left" Filler="blank" ID="169">/</RKE_ARTNR>
<RKE_BONUS Length="2" Alignment="left" Filler="blank" ID="170">/</RKE_BONUS>
<RKE_BRSCH Length="4" Alignment="left" Filler="blank" ID="171">/</RKE_BRSCH>
<RKE_BUKRS Length="4" Alignment="left" Filler="blank" ID="172">/</RKE_BUKRS>
<RKE_BZIRK Length="6" Alignment="left" Filler="blank" ID="173">/</RKE_BZIRK>
<RKE_EFORM Length="5" Alignment="left" Filler="blank" ID="174">/</RKE_EFORM>
<RKE_FKART Length="4" Alignment="left" Filler="blank" ID="175">/</RKE_FKART>
<RKE_GEBIE Length="4" Alignment="left" Filler="blank" ID="176">/</RKE_GEBIE>
<RKE_GSBER Length="4" Alignment="left" Filler="blank" ID="177">/</RKE_GSBER>
<RKE_KAUFN Length="10" Alignment="left" Filler="blank" ID="178">/</RKE_KAUFN>
<RKE_KDGRP Length="2" Alignment="left" Filler="blank" ID="179">/</RKE_KDGRP>
<RKE_KDPOS Length="6" Alignment="left" Filler="blank" ID="180">/</RKE_KDPOS>
<RKE_KNDNR Length="10" Alignment="left" Filler="blank" ID="181">/</RKE_KNDNR>
<RKE_KOKRS Length="4" Alignment="left" Filler="blank" ID="182">/</RKE_KOKRS>
<RKE_KSTRG Length="12" Alignment="left" Filler="blank" ID="183">/</RKE_KSTRG>
<RKE_LAND1 Length="3" Alignment="left" Filler="blank" ID="184">/</RKE_LAND1>
<RKE_MAABC Length="1" Alignment="left" Filler="blank" ID="185">/</RKE_MAABC>
<RKE_MATKL Length="9" Alignment="left" Filler="blank" ID="186">/</RKE_MATKL>
<RKE_PRCTR Length="10" Alignment="left" Filler="blank" ID="187">/</RKE_PRCTR>
<RKE_PSPNR Length="24" Alignment="left" Filler="blank" ID="188">/</RKE_PSPNR>
<RKE_RKAUFNR Length="12" Alignment="left" Filler="blank" ID="189">/</RKE_RKAUFNR>
<RKE_SPART Length="2" Alignment="left" Filler="blank" ID="190">/</RKE_SPART>
<RKE_VKBUR Length="4" Alignment="left" Filler="blank" ID="191">/</RKE_VKBUR>
<RKE_VKGRP Length="3" Alignment="left" Filler="blank" ID="192">/</RKE_VKGRP>
<RKE_VKORG Length="4" Alignment="left" Filler="blank" ID="193">/</RKE_VKORG>
<RKE_VTWEG Length="2" Alignment="left" Filler="blank" ID="194">/</RKE_VTWEG>
<RKE_WERKS Length="4" Alignment="left" Filler="blank" ID="195">/</RKE_WERKS>
<RKE_KMBRND Length="2" Alignment="left" Filler="blank" ID="196">/</RKE_KMBRND>
<RKE_KMCATG Length="2" Alignment="left" Filler="blank" ID="197">/</RKE_KMCATG>
<RKE_KMHI01 Length="10" Alignment="left" Filler="blank" ID="198">/</RKE_KMHI01>
<RKE_KMHI02 Length="10" Alignment="left" Filler="blank" ID="199">/</RKE_KMHI02>
<RKE_KMHI03 Length="10" Alignment="left" Filler="blank" ID="200">/</RKE_KMHI03>
<RKE_KMKDGR Length="2" Alignment="left" Filler="blank" ID="201">/</RKE_KMKDGR>
<RKE_KMLAND Length="3" Alignment="left" Filler="blank" ID="202">/</RKE_KMLAND>
<RKE_KMMAKL Length="9" Alignment="left" Filler="blank" ID="203">/</RKE_KMMAKL>
<RKE_KMNIEL Length="2" Alignment="left" Filler="blank" ID="204">/</RKE_KMNIEL>
<RKE_KMSTGE Length="2" Alignment="left" Filler="blank" ID="205">/</RKE_KMSTGE>
<RKE_KMVKBU Length="4" Alignment="left" Filler="blank" ID="206">/</RKE_KMVKBU>
<RKE_KMVKGR Length="3" Alignment="left" Filler="blank" ID="207">/</RKE_KMVKGR>
<RKE_KMVTNR Length="8" Alignment="left" Filler="blank" ID="208">/</RKE_KMVTNR>
<RKE_PPRCTR Length="10" Alignment="left" Filler="blank" ID="209">/</RKE_PPRCTR>
<!-- START new RKE-elements -->
<RKE_WW005 Length="5" Alignment="left" Filler="blank" ID="276">/</RKE_WW005>
<RKE_WW006 Length="5" Alignment="left" Filler="blank" ID="277">/</RKE_WW006>
<RKE_WW007 Length="3" Alignment="left" Filler="blank" ID="278">/</RKE_WW007>
<RKE_WW008 Length="3" Alignment="left" Filler="blank" ID="279">/</RKE_WW008>
<RKE_WW009 Length="1" Alignment="left" Filler="blank" ID="280">/</RKE_WW009>
<RKE_WW010 Length="3" Alignment="left" Filler="blank" ID="281">/</RKE_WW010>
<RKE_WW011 Length="2" Alignment="left" Filler="blank" ID="282">/</RKE_WW011>
<RKE_WW012 Length="6" Alignment="left" Filler="blank" ID="283">/</RKE_WW012>
<RKE_WW013 Length="10" Alignment="left" Filler="blank" ID="284">/</RKE_WW013>
<RKE_WW015 Length="1" Alignment="left" Filler="blank" ID="285">/</RKE_WW015>
<RKE_WW016 Length="2" Alignment="left" Filler="blank" ID="286">/</RKE_WW016>
<RKE_WW017 Length="7" Alignment="left" Filler="blank" ID="287">/</RKE_WW017>
<RKE_WW019 Length="6" Alignment="left" Filler="blank" ID="289">/</RKE_WW019>
<!-- END new RKE-elements -->
<VBUND Length="6" Alignment="left" Filler="blank" ID="210">/</VBUND>
<FKBER Length="4" Alignment="left" Filler="blank" ID="211">/</FKBER>
<DABRZ Length="8" Alignment="left" Filler="blank" ID="212">/</DABRZ>
<XSTBA Length="1" Alignment="left" Filler="blank" ID="213">/</XSTBA>
<!-- START Additional (empty) tags -->
<RSTGR Length="3" Alignment="left" Filler="blank" ID="214">/</RSTGR>
<FIPEX Length="24" Alignment="left" Filler="blank" ID="215">/</FIPEX>
<XNEGP Length="1" Alignment="left" Filler="blank" ID="216">/</XNEGP>
<GRICD Length="2" Alignment="left" Filler="blank" ID="217">/</GRICD>
<GRIRG Length="3" Alignment="left" Filler="blank" ID="218">/</GRIRG>
<GITYP Length="2" Alignment="left" Filler="blank" ID="219">/</GITYP>
<FITYP Length="2" Alignment="left" Filler="blank" ID="220">/</FITYP>
<STCDT Length="2" Alignment="left" Filler="blank" ID="221">/</STCDT>
<STKZN Length="1" Alignment="left" Filler="blank" ID="222">/</STKZN>
<STCD3 Length="18" Alignment="left" Filler="blank" ID="223">/</STCD3>
<STCD4 Length="18" Alignment="left" Filler="blank" ID="224">/</STCD4>
<XREF3 Length="20" Alignment="left" Filler="blank" ID="225">/</XREF3>
<KIDNO Length="30" Alignment="left" Filler="blank" ID="226">/</KIDNO>
<DTWS1 Length="2" Alignment="left" Filler="blank" ID="227">/</DTWS1>
<DTWS2 Length="2" Alignment="left" Filler="blank" ID="228">/</DTWS2>
<DTWS3 Length="2" Alignment="left" Filler="blank" ID="229">/</DTWS3>
<DTWS4 Length="2" Alignment="left" Filler="blank" ID="230">/</DTWS4>
<DTAWS Length="2" Alignment="left" Filler="blank" ID="231">/</DTAWS>
<PYCUR Length="5" Alignment="left" Filler="blank" ID="232">/</PYCUR>
<PYAMT Length="16" Alignment="left" Filler="blank" ID="233">/</PYAMT>
<BUPLA Length="4" Alignment="left" Filler="blank" ID="234">/</BUPLA>
<SECCO Length="4" Alignment="left" Filler="blank" ID="235">/</SECCO>
<LSTAR Length="6" Alignment="left" Filler="blank" ID="236">/</LSTAR>
<EGDEB Length="10" Alignment="left" Filler="blank" ID="237">/</EGDEB>
<WENR Length="8" Alignment="left" Filler="blank" ID="238">/</WENR>
<GENR Length="8" Alignment="left" Filler="blank" ID="239">/</GENR>
<GRNR Length="8" Alignment="left" Filler="blank" ID="240">/</GRNR>
<MENR Length="8" Alignment="left" Filler="blank" ID="241">/</MENR>
<MIVE Length="13" Alignment="left" Filler="blank" ID="242">/</MIVE>
<NKSL Length="4" Alignment="left" Filler="blank" ID="243">/</NKSL>
<EMPSL Length="5" Alignment="left" Filler="blank" ID="244">/</EMPSL>
<SVWNR Length="13" Alignment="left" Filler="blank" ID="245">/</SVWNR>
<SBERI Length="10" Alignment="left" Filler="blank" ID="246">/</SBERI>
<KKBER Length="4" Alignment="left" Filler="blank" ID="247">/</KKBER>
<EMPFB Length="10" Alignment="left" Filler="blank" ID="248">/</EMPFB>
<KURSR_M Length="10" Alignment="left" Filler="blank" ID="249">/</KURSR_M>
<J_1KFREPRE Length="10" Alignment="left" Filler="blank" ID="250">/</J_1KFREPRE>
<J_1KFTBUS Length="30" Alignment="left" Filler="blank" ID="251">/</J_1KFTBUS>
<J_1KFTIND Length="30" Alignment="left" Filler="blank" ID="252">/</J_1KFTIND>
<IDXSP Length="5" Alignment="left" Filler="blank" ID="253">/</IDXSP>
<ANRED Length="15" Alignment="left" Filler="blank" ID="254">/</ANRED>
<RECNNR Length="13" Alignment="left" Filler="blank" ID="255">/</RECNNR>
<E_MIVE Length="13" Alignment="left" Filler="blank" ID="256">/</E_MIVE>
<BKREF Length="20" Alignment="left" Filler="blank" ID="257">/</BKREF>
<DTAMS Length="1" Alignment="left" Filler="blank" ID="258">/</DTAMS>
<CESSION_KZ Length="2" Alignment="left" Filler="blank" ID="259">/</CESSION_KZ>
<GRANT_NBR Length="20" Alignment="left" Filler="blank" ID="260">/</GRANT_NBR>
<FKBER_LONG Length="16" Alignment="left" Filler="blank" ID="261">/</FKBER_LONG>
<ERLKZ Length="1" Alignment="left" Filler="blank" ID="262">/</ERLKZ>
<IBAN Length="34" Alignment="left" Filler="blank" ID="263">/</IBAN>
<VALID_FROM Length="8" Alignment="left" Filler="blank" ID="264">/</VALID_FROM>
<SEGMENT Length="10" Alignment="left" Filler="blank" ID="265">/</SEGMENT>
<PSEGMENT Length="10" Alignment="left" Filler="blank" ID="266">/</PSEGMENT>
<HKTID Length="5" Alignment="left" Filler="blank" ID="267">/</HKTID>
<XSIWE Length="1" Alignment="left" Filler="blank" ID="268">/</XSIWE>
<TCNO Length="16" Alignment="left" Filler="blank" ID="269">/</TCNO>
<DATEOFSERVICE Length="8" Alignment="left" Filler="blank" ID="270">/</DATEOFSERVICE>
<NOTAXCORR Length="1" Alignment="left" Filler="blank" ID="271">/</NOTAXCORR>
<DIFFOPTRATE Length="10" Alignment="left" Filler="blank" ID="272">/</DIFFOPTRATE>
<HASDIFFOPTRATE Length="1" Alignment="left" Filler="blank" ID="273">/</HASDIFFOPTRATE>
<SENDE Length="1" Alignment="left" Filler="blank" ID="274">/</SENDE>
<PRODPER Length="8" Alignment="left" Filler="blank" ID="275">/</PRODPER>
<!-- END Additional tags -->
</header_1_elements>
</xsl:template>
<xsl:template name="invoiceCharges_1_elements">
<invoiceCharges_1_elements>
<STYPE ID="1" Length="1" Alignment="left" Filler="blank">2</STYPE>
<TBNAM ID="2" Length="30" Alignment="left" Filler="blank">BBSEG</TBNAM>
<NEWBS ID="3" Length="2" Alignment="left" Filler="blank">
<xsl:if test="parent::node()/type='I'">40</xsl:if>
<xsl:if test="parent::node()/type='C'">50</xsl:if>
</NEWBS>
<DUMMYX ID="4" Length="10" Alignment="left" Filler="blank">/</DUMMYX>
<NEWUM ID="5" Length="1" Alignment="left" Filler="blank">/</NEWUM>
<NEWBK ID="6" Length="4" Alignment="left" Filler="blank">/</NEWBK>
<WRBTR ID="7" Length="16" Alignment="left" Filler="blank">
<!-- <xsl:value-of select="format-number(totalAmount, '#0.00', 'european')"/> -->
<xsl:value-of select="format-number(totalAmount, '0000000000000,00', 'european')"/>
</WRBTR>
<DMBTR ID="8" Length="16" Alignment="left" Filler="blank">/</DMBTR>
<WMWST ID="9" Length="16" Alignment="left" Filler="blank">/</WMWST>
<MWSTS ID="10" Length="16" Alignment="left" Filler="blank">/</MWSTS>
<MWSKZ ID="11" Length="2" Alignment="left" Filler="blank">
<xsl:value-of select="parent::node()/financialTaxCode" />
</MWSKZ>
<XSKRL ID="12" Length="1" Alignment="left" Filler="blank">/</XSKRL>
<FWZUZ ID="13" Length="16" Alignment="left" Filler="blank">/</FWZUZ>
<HWZUZ ID="14" Length="16" Alignment="left" Filler="blank">/</HWZUZ>
<GSBER ID="15" Length="4" Alignment="left" Filler="blank">/</GSBER>
<KOSTL ID="16" Length="10" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="financialCostcenter and string-length(financialCostcenter) &gt; 0">
<xsl:value-of select="financialCostcenter" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</KOSTL>
<DUMMY4 ID="17" Length="4" Alignment="left" Filler="blank">/</DUMMY4>
<AUFNR ID="18" Length="12" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="costcenter2 and string-length(costcenter2) &gt; 0">
<xsl:value-of select="costcenter2" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</AUFNR>
<EBELN ID="19" Length="10" Alignment="left" Filler="blank">/</EBELN>
<EBELP ID="20" Length="5" Alignment="left" Filler="blank">/</EBELP>
<PROJN ID="21" Length="16" Alignment="left" Filler="blank">/</PROJN>
<MATNR ID="22" Length="18" Alignment="left" Filler="blank">/</MATNR>
<WERKS ID="23" Length="4" Alignment="left" Filler="blank">/</WERKS>
<MENGE ID="24" Length="17" Alignment="left" Filler="blank">/</MENGE>
<MEINS ID="25" Length="3" Alignment="left" Filler="blank">/</MEINS>
<VBEL2 ID="26" Length="10" Alignment="left" Filler="blank">/</VBEL2>
<POSN2 ID="27" Length="6" Alignment="left" Filler="blank">/</POSN2>
<ETEN2 ID="28" Length="4" Alignment="left" Filler="blank">/</ETEN2>
<PERNR ID="29" Length="8" Alignment="left" Filler="blank">/</PERNR>
<BEWAR ID="30" Length="3" Alignment="left" Filler="blank">/</BEWAR>
<VALUT ID="31" Length="8" Alignment="left" Filler="blank">/</VALUT>
<ZFBDT ID="32" Length="8" Alignment="left" Filler="blank">/</ZFBDT>
<ZINKZ ID="33" Length="2" Alignment="left" Filler="blank">/</ZINKZ>
<ZUONR ID="34" Length="18" Alignment="left" Filler="blank">
<xsl:value-of select="orderNumber" />
</ZUONR>
<FKONT ID="35" Length="3" Alignment="left" Filler="blank">/</FKONT>
<XAABG ID="36" Length="1" Alignment="left" Filler="blank">/</XAABG>
<SGTXT ID="37" Length="50" Alignment="left" Filler="blank">
<xsl:variable name="twoDigitYear">
<xsl:value-of select="substring(parent::node()/financialPeriodYear, 3, 4)"/>
</xsl:variable>
<xsl:value-of select="$twoDigitYear" />
<xsl:value-of select="'/'" />
<xsl:value-of select="parent::node()/financialPeriodMonth" />
</SGTXT>
<BLNKZ ID="38" Length="2" Alignment="left" Filler="blank">/</BLNKZ>
<BLNBT ID="39" Alignment="left" Filler="blank" Length="16">/</BLNBT>
<BLNPZ ID="40" Alignment="left" Filler="blank" Length="8">/</BLNPZ>
<MABER ID="41" Alignment="left" Filler="blank" Length="2">/</MABER>
<SKFBT ID="42" Alignment="left" Filler="blank" Length="16">/</SKFBT>
<WSKTO ID="43" Alignment="left" Filler="blank" Length="16">/</WSKTO>
<ZTERM ID="44" Alignment="left" Filler="blank" Length="4">/</ZTERM>
<ZBD1T ID="45" Alignment="left" Filler="blank" Length="3">/</ZBD1T>
<ZBD1P ID="46" Alignment="left" Filler="blank" Length="6">/</ZBD1P>
<ZBD2T ID="47" Alignment="left" Filler="blank" Length="3">/</ZBD2T>
<ZBD2P ID="48" Alignment="left" Filler="blank" Length="6">/</ZBD2P>
<ZBD3T ID="49" Alignment="left" Filler="blank" Length="3">/</ZBD3T>
<ZLSPR ID="50" Alignment="left" Filler="blank" Length="1">/</ZLSPR>
<REBZG ID="51" Alignment="left" Filler="blank" Length="10">/</REBZG>
<REBZJ ID="52" Alignment="left" Filler="blank" Length="4">/</REBZJ>
<REBZZ ID="53" Alignment="left" Filler="blank" Length="3">/</REBZZ>
<ZLSCH ID="54" Alignment="left" Filler="blank" Length="1">/</ZLSCH>
<SAMNR ID="55" Alignment="left" Filler="blank" Length="8">/</SAMNR>
<ZBFIX ID="56" Alignment="left" Filler="blank" Length="1">/</ZBFIX>
<QSSKZ ID="57" Alignment="left" Filler="blank" Length="2">/</QSSKZ>
<QSSHB ID="58" Alignment="left" Filler="blank" Length="16">/</QSSHB>
<QSFBT ID="59" Alignment="left" Filler="blank" Length="16">/</QSFBT>
<ESRNR ID="60" Alignment="left" Filler="blank" Length="11">/</ESRNR>
<ESRPZ ID="61" Alignment="left" Filler="blank" Length="2">/</ESRPZ>
<ESRRE ID="62" Alignment="left" Filler="blank" Length="27">/</ESRRE>
<FDTAG ID="63" Alignment="left" Filler="blank" Length="8">/</FDTAG>
<FDLEV ID="64" Alignment="left" Filler="blank" Length="2">/</FDLEV>
<ANLN1 ID="65" Alignment="left" Filler="blank" Length="12">/</ANLN1>
<ANLN2 ID="66" Alignment="left" Filler="blank" Length="4">/</ANLN2>
<BZDAT ID="67" Alignment="left" Filler="blank" Length="8">/</BZDAT>
<ANBWA ID="68" Alignment="left" Filler="blank" Length="3">/</ANBWA>
<ABPER ID="69" Alignment="left" Filler="blank" Length="7">/</ABPER>
<GBETR ID="70" Alignment="left" Filler="blank" Length="16">/</GBETR>
<KURSR ID="71" Alignment="left" Filler="blank" Length="10">/</KURSR>
<MANSP ID="72" Alignment="left" Filler="blank" Length="1">/</MANSP>
<MSCHL ID="73" Alignment="left" Filler="blank" Length="1">/</MSCHL>
<HBKID ID="74" Alignment="left" Filler="blank" Length="5">/</HBKID>
<BVTYP ID="75" Alignment="left" Filler="blank" Length="4">/</BVTYP>
<ANFBN ID="76" Alignment="left" Filler="blank" Length="10">/</ANFBN>
<ANFBU ID="77" Alignment="left" Filler="blank" Length="4">/</ANFBU>
<ANFBJ ID="78" Alignment="left" Filler="blank" Length="4">/</ANFBJ>
<LZBKZ ID="79" Alignment="left" Filler="blank" Length="3">
<xsl:choose>
<xsl:when test="parent::node()/orderType='S'">
<xsl:value-of select="$constLZBZK_S_ORDER" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$constLZBZK_OTHER" />
</xsl:otherwise>
</xsl:choose>
</LZBKZ>
<LANDL ID="80" Alignment="left" Filler="blank" Length="3">/</LANDL>
<DIEKZ ID="81" Alignment="left" Filler="blank" Length="1">/</DIEKZ>
<ZOLLD ID="82" Alignment="left" Filler="blank" Length="8">/</ZOLLD>
<ZOLLT ID="83" Alignment="left" Filler="blank" Length="8">/</ZOLLT>
<VRSDT ID="84" Alignment="left" Filler="blank" Length="8">/</VRSDT>
<VRSKZ ID="85" Alignment="left" Filler="blank" Length="1">/</VRSKZ>
<HZUON ID="86" Alignment="left" Filler="blank" Length="18">/</HZUON>
<REGUL ID="87" Alignment="left" Filler="blank" Length="1">/</REGUL>
<NAME1 ID="88" Alignment="left" Filler="blank" Length="35">/</NAME1>
<NAME2 ID="89" Alignment="left" Filler="blank" Length="35">/</NAME2>
<NAME3 ID="90" Alignment="left" Filler="blank" Length="35">/</NAME3>
<NAME4 ID="91" Alignment="left" Filler="blank" Length="35">/</NAME4>
<STRAS ID="92" Alignment="left" Filler="blank" Length="35">/</STRAS>
<ORT01 ID="93" Alignment="left" Filler="blank" Length="35">/</ORT01>
<PSTLZ ID="94" Alignment="left" Filler="blank" Length="10">/</PSTLZ>
<LAND1 ID="95" Alignment="left" Filler="blank" Length="3">/</LAND1>
<REGIO ID="96" Alignment="left" Filler="blank" Length="3">/</REGIO>
<BANKL ID="97" Alignment="left" Filler="blank" Length="15">/</BANKL>
<BANKS ID="98" Alignment="left" Filler="blank" Length="3">/</BANKS>
<BANKN ID="99" Alignment="left" Filler="blank" Length="18">/</BANKN>
<BKONT ID="100" Alignment="left" Filler="blank" Length="2">/</BKONT>
<STCD1 ID="101" Alignment="left" Filler="blank" Length="16">/</STCD1>
<STCD2 ID="102" Alignment="left" Filler="blank" Length="11">/</STCD2>
<MADAT ID="103" Alignment="left" Filler="blank" Length="8">/</MADAT>
<MANST ID="104" Alignment="left" Filler="blank" Length="1">/</MANST>
<EGMLD ID="105" Alignment="left" Filler="blank" Length="3">/</EGMLD>
<DUMMY2 ID="106" Alignment="left" Filler="blank" Length="3">/</DUMMY2>
<STCEG ID="107" Alignment="left" Filler="blank" Length="20">/</STCEG>
<STKZA ID="108" Alignment="left" Filler="blank" Length="1">/</STKZA>
<STKZU ID="109" Alignment="left" Filler="blank" Length="1">/</STKZU>
<PFACH ID="110" Alignment="left" Filler="blank" Length="10">/</PFACH>
<PSTL2 ID="111" Alignment="left" Filler="blank" Length="10">/</PSTL2>
<SPRAS ID="112" Alignment="left" Filler="blank" Length="1">/</SPRAS>
<XINVE ID="113" Alignment="left" Filler="blank" Length="1">/</XINVE>
<NEWKO ID="114" Length="17" Alignment="left" Filler="blank">
<xsl:value-of select="accountNumber" />
</NEWKO>
<NEWBW Length="3" Alignment="left" Filler="blank" ID="115">/</NEWBW>
<KNRZE Length="17" Alignment="left" Filler="blank" ID="116">/</KNRZE>
<HKONT Length="10" Alignment="left" Filler="blank" ID="117">/</HKONT>
<PRCTR Length="10" Alignment="left" Filler="blank" ID="118">/</PRCTR>
<VERTN Length="13" Alignment="left" Filler="blank" ID="119">/</VERTN>
<VERTT Length="1" Alignment="left" Filler="blank" ID="120">/</VERTT>
<VBEWA Length="4" Alignment="left" Filler="blank" ID="121">/</VBEWA>
<HWBAS Length="16" Alignment="left" Filler="blank" ID="122">/</HWBAS>
<FWBAS Length="16" Alignment="left" Filler="blank" ID="123">/</FWBAS>
<FIPOS Length="14" Alignment="left" Filler="blank" ID="124">/</FIPOS>
<VNAME Length="6" Alignment="left" Filler="blank" ID="125">/</VNAME>
<EGRUP Length="3" Alignment="left" Filler="blank" ID="126">/</EGRUP>
<BTYPE Length="2" Alignment="left" Filler="blank" ID="127">/</BTYPE>
<PAOBJNR Length="10" Alignment="left" Filler="blank" ID="128">/</PAOBJNR>
<KSTRG Length="12" Alignment="left" Filler="blank" ID="129">/</KSTRG>
<IMKEY Length="8" Alignment="left" Filler="blank" ID="130">/</IMKEY>
<DUMMY3 Length="8" Alignment="left" Filler="blank" ID="131">/</DUMMY3>
<VPTNR Length="10" Alignment="left" Filler="blank" ID="132">/</VPTNR>
<NPLNR Length="12" Alignment="left" Filler="blank" ID="133">/</NPLNR>
<VORNR Length="4" Alignment="left" Filler="blank" ID="134">/</VORNR>
<XEGDR Length="1" Alignment="left" Filler="blank" ID="135">/</XEGDR>
<RECID Length="2" Alignment="left" Filler="blank" ID="136">/</RECID>
<PPRCT Length="10" Alignment="left" Filler="blank" ID="137">/</PPRCT>
<PROJK Length="24" Alignment="left" Filler="blank" ID="138">/</PROJK>
<UZAWE Length="2" Alignment="left" Filler="blank" ID="139">/</UZAWE>
<TXJCD Length="15" Alignment="left" Filler="blank" ID="140">/</TXJCD>
<FISTL Length="16" Alignment="left" Filler="blank" ID="141">/</FISTL>
<GEBER Length="10" Alignment="left" Filler="blank" ID="142">/</GEBER>
<DMBE2 Length="16" Alignment="left" Filler="blank" ID="143">/</DMBE2>
<DMBE3 Length="16" Alignment="left" Filler="blank" ID="144">/</DMBE3>
<PARGB Length="4" Alignment="left" Filler="blank" ID="145">/</PARGB>
<XREF1 Length="12" Alignment="left" Filler="blank" ID="146">/</XREF1>
<XREF2 Length="12" Alignment="left" Filler="blank" ID="147">/</XREF2>
<KBLNR Length="10" Alignment="left" Filler="blank" ID="149">/</KBLNR>
<KBLPOS Length="3" Alignment="left" Filler="blank" ID="150">/</KBLPOS>
<WDATE Length="8" Alignment="left" Filler="blank" ID="151">/</WDATE>
<WGBKZ Length="1" Alignment="left" Filler="blank" ID="152">/</WGBKZ>
<XAKTZ Length="1" Alignment="left" Filler="blank" ID="153">/</XAKTZ>
<WNAME Length="30" Alignment="left" Filler="blank" ID="154">/</WNAME>
<WORT1 Length="30" Alignment="left" Filler="blank" ID="155">/</WORT1>
<WBZOG Length="30" Alignment="left" Filler="blank" ID="156">/</WBZOG>
<WORT2 Length="30" Alignment="left" Filler="blank" ID="157">/</WORT2>
<WBANK Length="60" Alignment="left" Filler="blank" ID="158">/</WBANK>
<WLZBP Length="60" Alignment="left" Filler="blank" ID="159">/</WLZBP>
<DISKP Length="8" Alignment="left" Filler="blank" ID="160">/</DISKP>
<DISKT Length="3" Alignment="left" Filler="blank" ID="161">/</DISKT>
<WINFW Length="16" Alignment="left" Filler="blank" ID="162">/</WINFW>
<WINHW Length="16" Alignment="left" Filler="blank" ID="163">/</WINHW>
<WEVWV Length="1" Alignment="left" Filler="blank" ID="164">/</WEVWV>
<WSTAT Length="1" Alignment="left" Filler="blank" ID="165">/</WSTAT>
<WMWKZ Length="2" Alignment="left" Filler="blank" ID="166">/</WMWKZ>
<WSTKZ Length="1" Alignment="left" Filler="blank" ID="167">/</WSTKZ>
<RKE_ARTNR Length="18" Alignment="left" Filler="blank" ID="169">/</RKE_ARTNR>
<RKE_BONUS Length="2" Alignment="left" Filler="blank" ID="170">/</RKE_BONUS>
<RKE_BRSCH Length="4" Alignment="left" Filler="blank" ID="171">/</RKE_BRSCH>
<RKE_BUKRS Length="4" Alignment="left" Filler="blank" ID="172">/</RKE_BUKRS>
<RKE_BZIRK Length="6" Alignment="left" Filler="blank" ID="173">/</RKE_BZIRK>
<RKE_EFORM Length="5" Alignment="left" Filler="blank" ID="174">/</RKE_EFORM>
<RKE_FKART Length="4" Alignment="left" Filler="blank" ID="175">/</RKE_FKART>
<RKE_GEBIE Length="4" Alignment="left" Filler="blank" ID="176">/</RKE_GEBIE>
<RKE_GSBER Length="4" Alignment="left" Filler="blank" ID="177">/</RKE_GSBER>
<RKE_KAUFN Length="10" Alignment="left" Filler="blank" ID="178">/</RKE_KAUFN>
<RKE_KDGRP Length="2" Alignment="left" Filler="blank" ID="179">/</RKE_KDGRP>
<RKE_KDPOS Length="6" Alignment="left" Filler="blank" ID="180">/</RKE_KDPOS>
<RKE_KNDNR Length="10" Alignment="left" Filler="blank" ID="181">/</RKE_KNDNR>
<RKE_KOKRS Length="4" Alignment="left" Filler="blank" ID="182">/</RKE_KOKRS>
<RKE_KSTRG Length="12" Alignment="left" Filler="blank" ID="183">/</RKE_KSTRG>
<RKE_LAND1 Length="3" Alignment="left" Filler="blank" ID="184">/</RKE_LAND1>
<RKE_MAABC Length="1" Alignment="left" Filler="blank" ID="185">/</RKE_MAABC>
<RKE_MATKL Length="9" Alignment="left" Filler="blank" ID="186">/</RKE_MATKL>
<RKE_PRCTR Length="10" Alignment="left" Filler="blank" ID="187">/</RKE_PRCTR>
<RKE_PSPNR Length="24" Alignment="left" Filler="blank" ID="188">/</RKE_PSPNR>
<RKE_RKAUFNR Length="12" Alignment="left" Filler="blank" ID="189">/</RKE_RKAUFNR>
<RKE_SPART Length="2" Alignment="left" Filler="blank" ID="190">/</RKE_SPART>
<RKE_VKBUR Length="4" Alignment="left" Filler="blank" ID="191">/</RKE_VKBUR>
<RKE_VKGRP Length="3" Alignment="left" Filler="blank" ID="192">/</RKE_VKGRP>
<RKE_VKORG Length="4" Alignment="left" Filler="blank" ID="193">/</RKE_VKORG>
<RKE_VTWEG Length="2" Alignment="left" Filler="blank" ID="194">/</RKE_VTWEG>
<RKE_WERKS Length="4" Alignment="left" Filler="blank" ID="195">/</RKE_WERKS>
<RKE_KMBRND Length="2" Alignment="left" Filler="blank" ID="196">/</RKE_KMBRND>
<RKE_KMCATG Length="2" Alignment="left" Filler="blank" ID="197">/</RKE_KMCATG>
<RKE_KMHI01 Length="10" Alignment="left" Filler="blank" ID="198">/</RKE_KMHI01>
<RKE_KMHI02 Length="10" Alignment="left" Filler="blank" ID="199">/</RKE_KMHI02>
<RKE_KMHI03 Length="10" Alignment="left" Filler="blank" ID="200">/</RKE_KMHI03>
<RKE_KMKDGR Length="2" Alignment="left" Filler="blank" ID="201">/</RKE_KMKDGR>
<RKE_KMLAND Length="3" Alignment="left" Filler="blank" ID="202">/</RKE_KMLAND>
<RKE_KMMAKL Length="9" Alignment="left" Filler="blank" ID="203">/</RKE_KMMAKL>
<RKE_KMNIEL Length="2" Alignment="left" Filler="blank" ID="204">/</RKE_KMNIEL>
<RKE_KMSTGE Length="2" Alignment="left" Filler="blank" ID="205">/</RKE_KMSTGE>
<RKE_KMVKBU Length="4" Alignment="left" Filler="blank" ID="206">/</RKE_KMVKBU>
<RKE_KMVKGR Length="3" Alignment="left" Filler="blank" ID="207">/</RKE_KMVKGR>
<RKE_KMVTNR Length="8" Alignment="left" Filler="blank" ID="208">/</RKE_KMVTNR>
<RKE_PPRCTR Length="10" Alignment="left" Filler="blank" ID="209">/</RKE_PPRCTR>
<!-- START new RKE-elements -->
<RKE_WW005 Length="5" Alignment="left" Filler="blank" ID="276">/</RKE_WW005>
<RKE_WW006 Length="5" Alignment="left" Filler="blank" ID="277">/</RKE_WW006>
<RKE_WW007 Length="3" Alignment="left" Filler="blank" ID="278">/</RKE_WW007>
<RKE_WW008 Length="3" Alignment="left" Filler="blank" ID="279">/</RKE_WW008>
<RKE_WW009 Length="1" Alignment="left" Filler="blank" ID="280">/</RKE_WW009>
<RKE_WW010 Length="3" Alignment="left" Filler="blank" ID="281">/</RKE_WW010>
<RKE_WW011 Length="2" Alignment="left" Filler="blank" ID="282">/</RKE_WW011>
<RKE_WW012 Length="6" Alignment="left" Filler="blank" ID="283">/</RKE_WW012>
<RKE_WW013 Length="10" Alignment="left" Filler="blank" ID="284">/</RKE_WW013>
<RKE_WW015 Length="1" Alignment="left" Filler="blank" ID="285">/</RKE_WW015>
<RKE_WW016 Length="2" Alignment="left" Filler="blank" ID="286">/</RKE_WW016>
<RKE_WW017 Length="7" Alignment="left" Filler="blank" ID="287">/</RKE_WW017>
<RKE_WW019 Length="6" Alignment="left" Filler="blank" ID="289">/</RKE_WW019>
<!-- END new RKE-elements -->
<VBUND Length="6" Alignment="left" Filler="blank" ID="210">/</VBUND>
<FKBER Length="4" Alignment="left" Filler="blank" ID="211">/</FKBER>
<DABRZ Length="8" Alignment="left" Filler="blank" ID="212">/</DABRZ>
<XSTBA Length="1" Alignment="left" Filler="blank" ID="213">/</XSTBA>
<!-- Additional (empty) tags start -->
<RSTGR Length="3" Alignment="left" Filler="blank" ID="214">/</RSTGR>
<FIPEX Length="24" Alignment="left" Filler="blank" ID="215">/</FIPEX>
<XNEGP Length="1" Alignment="left" Filler="blank" ID="216">/</XNEGP>
<GRICD Length="2" Alignment="left" Filler="blank" ID="217">/</GRICD>
<GRIRG Length="3" Alignment="left" Filler="blank" ID="218">/</GRIRG>
<GITYP Length="2" Alignment="left" Filler="blank" ID="219">/</GITYP>
<FITYP Length="2" Alignment="left" Filler="blank" ID="220">/</FITYP>
<STCDT Length="2" Alignment="left" Filler="blank" ID="221">/</STCDT>
<STKZN Length="1" Alignment="left" Filler="blank" ID="222">/</STKZN>
<STCD3 Length="18" Alignment="left" Filler="blank" ID="223">/</STCD3>
<STCD4 Length="18" Alignment="left" Filler="blank" ID="224">/</STCD4>
<XREF3 Length="20" Alignment="left" Filler="blank" ID="225">/</XREF3>
<KIDNO Length="30" Alignment="left" Filler="blank" ID="226">/</KIDNO>
<DTWS1 Length="2" Alignment="left" Filler="blank" ID="227">/</DTWS1>
<DTWS2 Length="2" Alignment="left" Filler="blank" ID="228">/</DTWS2>
<DTWS3 Length="2" Alignment="left" Filler="blank" ID="229">/</DTWS3>
<DTWS4 Length="2" Alignment="left" Filler="blank" ID="230">/</DTWS4>
<DTAWS Length="2" Alignment="left" Filler="blank" ID="231">/</DTAWS>
<PYCUR Length="5" Alignment="left" Filler="blank" ID="232">/</PYCUR>
<PYAMT Length="16" Alignment="left" Filler="blank" ID="233">/</PYAMT>
<BUPLA Length="4" Alignment="left" Filler="blank" ID="234">/</BUPLA>
<SECCO Length="4" Alignment="left" Filler="blank" ID="235">/</SECCO>
<LSTAR Length="6" Alignment="left" Filler="blank" ID="236">/</LSTAR>
<EGDEB Length="10" Alignment="left" Filler="blank" ID="237">/</EGDEB>
<WENR Length="8" Alignment="left" Filler="blank" ID="238">/</WENR>
<GENR Length="8" Alignment="left" Filler="blank" ID="239">/</GENR>
<GRNR Length="8" Alignment="left" Filler="blank" ID="240">/</GRNR>
<MENR Length="8" Alignment="left" Filler="blank" ID="241">/</MENR>
<MIVE Length="13" Alignment="left" Filler="blank" ID="242">/</MIVE>
<NKSL Length="4" Alignment="left" Filler="blank" ID="243">/</NKSL>
<EMPSL Length="5" Alignment="left" Filler="blank" ID="244">/</EMPSL>
<SVWNR Length="13" Alignment="left" Filler="blank" ID="245">/</SVWNR>
<SBERI Length="10" Alignment="left" Filler="blank" ID="246">/</SBERI>
<KKBER Length="4" Alignment="left" Filler="blank" ID="247">/</KKBER>
<EMPFB Length="10" Alignment="left" Filler="blank" ID="248">/</EMPFB>
<KURSR_M Length="10" Alignment="left" Filler="blank" ID="249">/</KURSR_M>
<J_1KFREPRE Length="10" Alignment="left" Filler="blank" ID="250">/</J_1KFREPRE>
<J_1KFTBUS Length="30" Alignment="left" Filler="blank" ID="251">/</J_1KFTBUS>
<J_1KFTIND Length="30" Alignment="left" Filler="blank" ID="252">/</J_1KFTIND>
<IDXSP Length="5" Alignment="left" Filler="blank" ID="253">/</IDXSP>
<ANRED Length="15" Alignment="left" Filler="blank" ID="254">/</ANRED>
<RECNNR Length="13" Alignment="left" Filler="blank" ID="255">/</RECNNR>
<E_MIVE Length="13" Alignment="left" Filler="blank" ID="256">/</E_MIVE>
<BKREF Length="20" Alignment="left" Filler="blank" ID="257">/</BKREF>
<DTAMS Length="1" Alignment="left" Filler="blank" ID="258">/</DTAMS>
<CESSION_KZ Length="2" Alignment="left" Filler="blank" ID="259">/</CESSION_KZ>
<GRANT_NBR Length="20" Alignment="left" Filler="blank" ID="260">/</GRANT_NBR>
<FKBER_LONG Length="16" Alignment="left" Filler="blank" ID="261">/</FKBER_LONG>
<ERLKZ Length="1" Alignment="left" Filler="blank" ID="262">/</ERLKZ>
<IBAN Length="34" Alignment="left" Filler="blank" ID="263">/</IBAN>
<VALID_FROM Length="8" Alignment="left" Filler="blank" ID="264">/</VALID_FROM>
<SEGMENT Length="10" Alignment="left" Filler="blank" ID="265">/</SEGMENT>
<PSEGMENT Length="10" Alignment="left" Filler="blank" ID="266">/</PSEGMENT>
<HKTID Length="5" Alignment="left" Filler="blank" ID="267">/</HKTID>
<XSIWE Length="1" Alignment="left" Filler="blank" ID="268">/</XSIWE>
<TCNO Length="16" Alignment="left" Filler="blank" ID="269">/</TCNO>
<DATEOFSERVICE Length="8" Alignment="left" Filler="blank" ID="270">/</DATEOFSERVICE>
<NOTAXCORR Length="1" Alignment="left" Filler="blank" ID="271">/</NOTAXCORR>
<DIFFOPTRATE Length="10" Alignment="left" Filler="blank" ID="272">/</DIFFOPTRATE>
<HASDIFFOPTRATE Length="1" Alignment="left" Filler="blank" ID="273">/</HASDIFFOPTRATE>
<SENDE Length="1" Alignment="left" Filler="blank" ID="274">/</SENDE>
<PRODPER Length="8" Alignment="left" Filler="blank" ID="275">/</PRODPER>
<!-- Additional tags end -->
</invoiceCharges_1_elements>
</xsl:template>
<xsl:template name="invoiceDetails_1_elements">
<invoiceDetails_1_elements>
<STYPE ID="1" Length="1" Alignment="left" Filler="blank">2</STYPE>
<TBNAM ID="2" Length="30" Alignment="left" Filler="blank">BBSEG</TBNAM>
<NEWBS ID="3" Length="2" Alignment="left" Filler="blank">
<xsl:if test="parent::node()/type='I'">40</xsl:if>
<xsl:if test="parent::node()/type='C'">50</xsl:if>
</NEWBS>
<DUMMYX ID="4" Length="10" Alignment="left" Filler="blank">/</DUMMYX>
<NEWUM ID="5" Length="1" Alignment="left" Filler="blank">/</NEWUM>
<NEWBK ID="6" Length="4" Alignment="left" Filler="blank">/</NEWBK>
<WRBTR ID="7" Length="16" Alignment="left" Filler="blank">
<xsl:value-of select="format-number(totalAmount, '0000000000000,00', 'european')"/>
</WRBTR>
<DMBTR ID="8" Length="16" Alignment="left" Filler="blank">/</DMBTR>
<WMWST ID="9" Length="16" Alignment="left" Filler="blank">/</WMWST>
<MWSTS ID="10" Length="16" Alignment="left" Filler="blank">/</MWSTS>
<MWSKZ ID="11" Length="2" Alignment="left" Filler="blank">
<xsl:value-of select="parent::node()/financialTaxCode" />
</MWSKZ>
<XSKRL ID="12" Length="1" Alignment="left" Filler="blank">/</XSKRL>
<FWZUZ ID="13" Length="16" Alignment="left" Filler="blank">/</FWZUZ>
<HWZUZ ID="14" Length="16" Alignment="left" Filler="blank">/</HWZUZ>
<GSBER ID="15" Length="4" Alignment="left" Filler="blank">/</GSBER>
<KOSTL ID="16" Length="10" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="financialCostcenter and string-length(financialCostcenter) &gt; 0">
<xsl:value-of select="financialCostcenter" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</KOSTL>
<DUMMY4 ID="17" Length="4" Alignment="left" Filler="blank">/</DUMMY4>
<AUFNR ID="18" Length="12" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="costcenter2 and string-length(costcenter2) &gt; 0">
<xsl:value-of select="costcenter2" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</AUFNR>
<EBELN ID="19" Length="10" Alignment="left" Filler="blank">/</EBELN>
<EBELP ID="20" Length="5" Alignment="left" Filler="blank">/</EBELP>
<PROJN ID="21" Length="16" Alignment="left" Filler="blank">/</PROJN>
<MATNR ID="22" Length="18" Alignment="left" Filler="blank">/</MATNR>
<WERKS ID="23" Length="4" Alignment="left" Filler="blank">/</WERKS>
<MENGE ID="24" Length="17" Alignment="left" Filler="blank">/</MENGE>
<MEINS ID="25" Length="3" Alignment="left" Filler="blank">/</MEINS>
<VBEL2 ID="26" Length="10" Alignment="left" Filler="blank">/</VBEL2>
<POSN2 ID="27" Length="6" Alignment="left" Filler="blank">/</POSN2>
<ETEN2 ID="28" Length="4" Alignment="left" Filler="blank">/</ETEN2>
<PERNR ID="29" Length="8" Alignment="left" Filler="blank">/</PERNR>
<BEWAR ID="30" Length="3" Alignment="left" Filler="blank">/</BEWAR>
<VALUT ID="31" Length="8" Alignment="left" Filler="blank">/</VALUT>
<ZFBDT ID="32" Length="8" Alignment="left" Filler="blank">/</ZFBDT>
<ZINKZ ID="33" Length="2" Alignment="left" Filler="blank">/</ZINKZ>
<ZUONR ID="34" Length="18" Alignment="left" Filler="blank">
<xsl:value-of select="orderNumber" />
<xsl:value-of select="'-'" />
<xsl:value-of select="itemNumber" />
</ZUONR>
<FKONT ID="35" Length="3" Alignment="left" Filler="blank">/</FKONT>
<XAABG ID="36" Length="1" Alignment="left" Filler="blank">/</XAABG>
<SGTXT ID="37" Length="50" Alignment="left" Filler="blank">
<xsl:variable name="twoDigitYear">
<xsl:value-of select="substring(parent::node()/financialPeriodYear, 3, 4)"/>
</xsl:variable>
<xsl:value-of select="$twoDigitYear" />
<xsl:value-of select="'/'" />
<xsl:value-of select="parent::node()/financialPeriodMonth" />
</SGTXT>
<BLNKZ ID="38" Length="2" Alignment="left" Filler="blank">/</BLNKZ>
<BLNBT ID="39" Alignment="left" Filler="blank" Length="16">/</BLNBT>
<BLNPZ ID="40" Alignment="left" Filler="blank" Length="8">/</BLNPZ>
<MABER ID="41" Alignment="left" Filler="blank" Length="2">/</MABER>
<SKFBT ID="42" Alignment="left" Filler="blank" Length="16">/</SKFBT>
<WSKTO ID="43" Alignment="left" Filler="blank" Length="16">/</WSKTO>
<ZTERM ID="44" Alignment="left" Filler="blank" Length="4">/</ZTERM>
<ZBD1T ID="45" Alignment="left" Filler="blank" Length="3">/</ZBD1T>
<ZBD1P ID="46" Alignment="left" Filler="blank" Length="6">/</ZBD1P>
<ZBD2T ID="47" Alignment="left" Filler="blank" Length="3">/</ZBD2T>
<ZBD2P ID="48" Alignment="left" Filler="blank" Length="6">/</ZBD2P>
<ZBD3T ID="49" Alignment="left" Filler="blank" Length="3">/</ZBD3T>
<ZLSPR ID="50" Alignment="left" Filler="blank" Length="1">/</ZLSPR>
<REBZG ID="51" Alignment="left" Filler="blank" Length="10">/</REBZG>
<REBZJ ID="52" Alignment="left" Filler="blank" Length="4">/</REBZJ>
<REBZZ ID="53" Alignment="left" Filler="blank" Length="3">/</REBZZ>
<ZLSCH ID="54" Alignment="left" Filler="blank" Length="1">/</ZLSCH>
<SAMNR ID="55" Alignment="left" Filler="blank" Length="8">/</SAMNR>
<ZBFIX ID="56" Alignment="left" Filler="blank" Length="1">/</ZBFIX>
<QSSKZ ID="57" Alignment="left" Filler="blank" Length="2">/</QSSKZ>
<QSSHB ID="58" Alignment="left" Filler="blank" Length="16">/</QSSHB>
<QSFBT ID="59" Alignment="left" Filler="blank" Length="16">/</QSFBT>
<ESRNR ID="60" Alignment="left" Filler="blank" Length="11">/</ESRNR>
<ESRPZ ID="61" Alignment="left" Filler="blank" Length="2">/</ESRPZ>
<ESRRE ID="62" Alignment="left" Filler="blank" Length="27">/</ESRRE>
<FDTAG ID="63" Alignment="left" Filler="blank" Length="8">/</FDTAG>
<FDLEV ID="64" Alignment="left" Filler="blank" Length="2">/</FDLEV>
<ANLN1 ID="65" Alignment="left" Filler="blank" Length="12">/</ANLN1>
<ANLN2 ID="66" Alignment="left" Filler="blank" Length="4">/</ANLN2>
<BZDAT ID="67" Alignment="left" Filler="blank" Length="8">/</BZDAT>
<ANBWA ID="68" Alignment="left" Filler="blank" Length="3">/</ANBWA>
<ABPER ID="69" Alignment="left" Filler="blank" Length="7">/</ABPER>
<GBETR ID="70" Alignment="left" Filler="blank" Length="16">/</GBETR>
<KURSR ID="71" Alignment="left" Filler="blank" Length="10">/</KURSR>
<MANSP ID="72" Alignment="left" Filler="blank" Length="1">/</MANSP>
<MSCHL ID="73" Alignment="left" Filler="blank" Length="1">/</MSCHL>
<HBKID ID="74" Alignment="left" Filler="blank" Length="5">/</HBKID>
<BVTYP ID="75" Alignment="left" Filler="blank" Length="4">/</BVTYP>
<ANFBN ID="76" Alignment="left" Filler="blank" Length="10">/</ANFBN>
<ANFBU ID="77" Alignment="left" Filler="blank" Length="4">/</ANFBU>
<ANFBJ ID="78" Alignment="left" Filler="blank" Length="4">/</ANFBJ>
<LZBKZ ID="79" Alignment="left" Filler="blank" Length="3">
<xsl:choose>
<xsl:when test="orderType='S'">
<xsl:value-of select="$constLZBZK_S_ORDER" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$constLZBZK_OTHER" />
</xsl:otherwise>
</xsl:choose>
</LZBKZ>
<LANDL ID="80" Alignment="left" Filler="blank" Length="3">/</LANDL>
<DIEKZ ID="81" Alignment="left" Filler="blank" Length="1">/</DIEKZ>
<ZOLLD ID="82" Alignment="left" Filler="blank" Length="8">/</ZOLLD>
<ZOLLT ID="83" Alignment="left" Filler="blank" Length="8">/</ZOLLT>
<VRSDT ID="84" Alignment="left" Filler="blank" Length="8">/</VRSDT>
<VRSKZ ID="85" Alignment="left" Filler="blank" Length="1">/</VRSKZ>
<HZUON ID="86" Alignment="left" Filler="blank" Length="18">/</HZUON>
<REGUL ID="87" Alignment="left" Filler="blank" Length="1">/</REGUL>
<NAME1 ID="88" Alignment="left" Filler="blank" Length="35">/</NAME1>
<NAME2 ID="89" Alignment="left" Filler="blank" Length="35">/</NAME2>
<NAME3 ID="90" Alignment="left" Filler="blank" Length="35">/</NAME3>
<NAME4 ID="91" Alignment="left" Filler="blank" Length="35">/</NAME4>
<STRAS ID="92" Alignment="left" Filler="blank" Length="35">/</STRAS>
<ORT01 ID="93" Alignment="left" Filler="blank" Length="35">/</ORT01>
<PSTLZ ID="94" Alignment="left" Filler="blank" Length="10">/</PSTLZ>
<LAND1 ID="95" Alignment="left" Filler="blank" Length="3">/</LAND1>
<REGIO ID="96" Alignment="left" Filler="blank" Length="3">/</REGIO>
<BANKL ID="97" Alignment="left" Filler="blank" Length="15">/</BANKL>
<BANKS ID="98" Alignment="left" Filler="blank" Length="3">/</BANKS>
<BANKN ID="99" Alignment="left" Filler="blank" Length="18">/</BANKN>
<BKONT ID="100" Alignment="left" Filler="blank" Length="2">/</BKONT>
<STCD1 ID="101" Alignment="left" Filler="blank" Length="16">/</STCD1>
<STCD2 ID="102" Alignment="left" Filler="blank" Length="11">/</STCD2>
<MADAT ID="103" Alignment="left" Filler="blank" Length="8">/</MADAT>
<MANST ID="104" Alignment="left" Filler="blank" Length="1">/</MANST>
<EGMLD ID="105" Alignment="left" Filler="blank" Length="3">/</EGMLD>
<DUMMY2 ID="106" Alignment="left" Filler="blank" Length="3">/</DUMMY2>
<STCEG ID="107" Alignment="left" Filler="blank" Length="20">/</STCEG>
<STKZA ID="108" Alignment="left" Filler="blank" Length="1">/</STKZA>
<STKZU ID="109" Alignment="left" Filler="blank" Length="1">/</STKZU>
<PFACH ID="110" Alignment="left" Filler="blank" Length="10">/</PFACH>
<PSTL2 ID="111" Alignment="left" Filler="blank" Length="10">/</PSTL2>
<SPRAS ID="112" Alignment="left" Filler="blank" Length="1">/</SPRAS>
<XINVE ID="113" Alignment="left" Filler="blank" Length="1">/</XINVE>
<NEWKO ID="114" Length="17" Alignment="left" Filler="blank">
<xsl:value-of select="accountNumber" />
</NEWKO>
<NEWBW Length="3" Alignment="left" Filler="blank" ID="115">/</NEWBW>
<KNRZE Length="17" Alignment="left" Filler="blank" ID="116">/</KNRZE>
<HKONT Length="10" Alignment="left" Filler="blank" ID="117">/</HKONT>
<PRCTR Length="10" Alignment="left" Filler="blank" ID="118">/</PRCTR>
<VERTN Length="13" Alignment="left" Filler="blank" ID="119">/</VERTN>
<VERTT Length="1" Alignment="left" Filler="blank" ID="120">/</VERTT>
<VBEWA Length="4" Alignment="left" Filler="blank" ID="121">/</VBEWA>
<HWBAS Length="16" Alignment="left" Filler="blank" ID="122">/</HWBAS>
<FWBAS Length="16" Alignment="left" Filler="blank" ID="123">/</FWBAS>
<FIPOS Length="14" Alignment="left" Filler="blank" ID="124">/</FIPOS>
<VNAME Length="6" Alignment="left" Filler="blank" ID="125">/</VNAME>
<EGRUP Length="3" Alignment="left" Filler="blank" ID="126">/</EGRUP>
<BTYPE Length="2" Alignment="left" Filler="blank" ID="127">/</BTYPE>
<PAOBJNR Length="10" Alignment="left" Filler="blank" ID="128">/</PAOBJNR>
<KSTRG Length="12" Alignment="left" Filler="blank" ID="129">/</KSTRG>
<IMKEY Length="8" Alignment="left" Filler="blank" ID="130">/</IMKEY>
<DUMMY3 Length="8" Alignment="left" Filler="blank" ID="131">/</DUMMY3>
<VPTNR Length="10" Alignment="left" Filler="blank" ID="132">/</VPTNR>
<NPLNR Length="12" Alignment="left" Filler="blank" ID="133">/</NPLNR>
<VORNR Length="4" Alignment="left" Filler="blank" ID="134">/</VORNR>
<XEGDR Length="1" Alignment="left" Filler="blank" ID="135">/</XEGDR>
<RECID Length="2" Alignment="left" Filler="blank" ID="136">/</RECID>
<PPRCT Length="10" Alignment="left" Filler="blank" ID="137">/</PPRCT>
<PROJK Length="24" Alignment="left" Filler="blank" ID="138">/</PROJK>
<UZAWE Length="2" Alignment="left" Filler="blank" ID="139">/</UZAWE>
<TXJCD Length="15" Alignment="left" Filler="blank" ID="140">/</TXJCD>
<FISTL Length="16" Alignment="left" Filler="blank" ID="141">/</FISTL>
<GEBER Length="10" Alignment="left" Filler="blank" ID="142">/</GEBER>
<DMBE2 Length="16" Alignment="left" Filler="blank" ID="143">/</DMBE2>
<DMBE3 Length="16" Alignment="left" Filler="blank" ID="144">/</DMBE3>
<PARGB Length="4" Alignment="left" Filler="blank" ID="145">/</PARGB>
<XREF1 Length="12" Alignment="left" Filler="blank" ID="146">/</XREF1>
<XREF2 Length="12" Alignment="left" Filler="blank" ID="147">/</XREF2>
<KBLNR Length="10" Alignment="left" Filler="blank" ID="149">/</KBLNR>
<KBLPOS Length="3" Alignment="left" Filler="blank" ID="150">/</KBLPOS>
<WDATE Length="8" Alignment="left" Filler="blank" ID="151">/</WDATE>
<WGBKZ Length="1" Alignment="left" Filler="blank" ID="152">/</WGBKZ>
<XAKTZ Length="1" Alignment="left" Filler="blank" ID="153">/</XAKTZ>
<WNAME Length="30" Alignment="left" Filler="blank" ID="154">/</WNAME>
<WORT1 Length="30" Alignment="left" Filler="blank" ID="155">/</WORT1>
<WBZOG Length="30" Alignment="left" Filler="blank" ID="156">/</WBZOG>
<WORT2 Length="30" Alignment="left" Filler="blank" ID="157">/</WORT2>
<WBANK Length="60" Alignment="left" Filler="blank" ID="158">/</WBANK>
<WLZBP Length="60" Alignment="left" Filler="blank" ID="159">/</WLZBP>
<DISKP Length="8" Alignment="left" Filler="blank" ID="160">/</DISKP>
<DISKT Length="3" Alignment="left" Filler="blank" ID="161">/</DISKT>
<WINFW Length="16" Alignment="left" Filler="blank" ID="162">/</WINFW>
<WINHW Length="16" Alignment="left" Filler="blank" ID="163">/</WINHW>
<WEVWV Length="1" Alignment="left" Filler="blank" ID="164">/</WEVWV>
<WSTAT Length="1" Alignment="left" Filler="blank" ID="165">/</WSTAT>
<WMWKZ Length="2" Alignment="left" Filler="blank" ID="166">/</WMWKZ>
<WSTKZ Length="1" Alignment="left" Filler="blank" ID="167">/</WSTKZ>
<RKE_ARTNR Length="18" Alignment="left" Filler="blank" ID="169">/</RKE_ARTNR>
<RKE_BONUS Length="2" Alignment="left" Filler="blank" ID="170">/</RKE_BONUS>
<RKE_BRSCH Length="4" Alignment="left" Filler="blank" ID="171">/</RKE_BRSCH>
<RKE_BUKRS Length="4" Alignment="left" Filler="blank" ID="172">/</RKE_BUKRS>
<RKE_BZIRK Length="6" Alignment="left" Filler="blank" ID="173">/</RKE_BZIRK>
<RKE_EFORM Length="5" Alignment="left" Filler="blank" ID="174">/</RKE_EFORM>
<RKE_FKART Length="4" Alignment="left" Filler="blank" ID="175">/</RKE_FKART>
<RKE_GEBIE Length="4" Alignment="left" Filler="blank" ID="176">/</RKE_GEBIE>
<RKE_GSBER Length="4" Alignment="left" Filler="blank" ID="177">/</RKE_GSBER>
<RKE_KAUFN Length="10" Alignment="left" Filler="blank" ID="178">/</RKE_KAUFN>
<RKE_KDGRP Length="2" Alignment="left" Filler="blank" ID="179">/</RKE_KDGRP>
<RKE_KDPOS Length="6" Alignment="left" Filler="blank" ID="180">/</RKE_KDPOS>
<RKE_KNDNR Length="10" Alignment="left" Filler="blank" ID="181">/</RKE_KNDNR>
<RKE_KOKRS Length="4" Alignment="left" Filler="blank" ID="182">/</RKE_KOKRS>
<RKE_KSTRG Length="12" Alignment="left" Filler="blank" ID="183">/</RKE_KSTRG>
<RKE_LAND1 Length="3" Alignment="left" Filler="blank" ID="184">/</RKE_LAND1>
<RKE_MAABC Length="1" Alignment="left" Filler="blank" ID="185">/</RKE_MAABC>
<RKE_MATKL Length="9" Alignment="left" Filler="blank" ID="186">/</RKE_MATKL>
<RKE_PRCTR Length="10" Alignment="left" Filler="blank" ID="187">/</RKE_PRCTR>
<RKE_PSPNR Length="24" Alignment="left" Filler="blank" ID="188">/</RKE_PSPNR>
<RKE_RKAUFNR Length="12" Alignment="left" Filler="blank" ID="189">/</RKE_RKAUFNR>
<RKE_SPART Length="2" Alignment="left" Filler="blank" ID="190">/</RKE_SPART>
<RKE_VKBUR Length="4" Alignment="left" Filler="blank" ID="191">/</RKE_VKBUR>
<RKE_VKGRP Length="3" Alignment="left" Filler="blank" ID="192">/</RKE_VKGRP>
<RKE_VKORG Length="4" Alignment="left" Filler="blank" ID="193">/</RKE_VKORG>
<RKE_VTWEG Length="2" Alignment="left" Filler="blank" ID="194">/</RKE_VTWEG>
<RKE_WERKS Length="4" Alignment="left" Filler="blank" ID="195">/</RKE_WERKS>
<RKE_KMBRND Length="2" Alignment="left" Filler="blank" ID="196">/</RKE_KMBRND>
<RKE_KMCATG Length="2" Alignment="left" Filler="blank" ID="197">/</RKE_KMCATG>
<RKE_KMHI01 Length="10" Alignment="left" Filler="blank" ID="198">/</RKE_KMHI01>
<RKE_KMHI02 Length="10" Alignment="left" Filler="blank" ID="199">/</RKE_KMHI02>
<RKE_KMHI03 Length="10" Alignment="left" Filler="blank" ID="200">/</RKE_KMHI03>
<RKE_KMKDGR Length="2" Alignment="left" Filler="blank" ID="201">/</RKE_KMKDGR>
<RKE_KMLAND Length="3" Alignment="left" Filler="blank" ID="202">/</RKE_KMLAND>
<RKE_KMMAKL Length="9" Alignment="left" Filler="blank" ID="203">/</RKE_KMMAKL>
<RKE_KMNIEL Length="2" Alignment="left" Filler="blank" ID="204">/</RKE_KMNIEL>
<RKE_KMSTGE Length="2" Alignment="left" Filler="blank" ID="205">/</RKE_KMSTGE>
<RKE_KMVKBU Length="4" Alignment="left" Filler="blank" ID="206">/</RKE_KMVKBU>
<RKE_KMVKGR Length="3" Alignment="left" Filler="blank" ID="207">/</RKE_KMVKGR>
<RKE_KMVTNR Length="8" Alignment="left" Filler="blank" ID="208">/</RKE_KMVTNR>
<RKE_PPRCTR Length="10" Alignment="left" Filler="blank" ID="209">/</RKE_PPRCTR>
<!-- START new RKE-elements -->
<RKE_WW005 Length="5" Alignment="left" Filler="blank" ID="276">/</RKE_WW005>
<RKE_WW006 Length="5" Alignment="left" Filler="blank" ID="277">/</RKE_WW006>
<RKE_WW007 Length="3" Alignment="left" Filler="blank" ID="278">/</RKE_WW007>
<RKE_WW008 Length="3" Alignment="left" Filler="blank" ID="279">/</RKE_WW008>
<RKE_WW009 Length="1" Alignment="left" Filler="blank" ID="280">/</RKE_WW009>
<RKE_WW010 Length="3" Alignment="left" Filler="blank" ID="281">/</RKE_WW010>
<RKE_WW011 Length="2" Alignment="left" Filler="blank" ID="282">/</RKE_WW011>
<RKE_WW012 Length="6" Alignment="left" Filler="blank" ID="283">/</RKE_WW012>
<RKE_WW013 Length="10" Alignment="left" Filler="blank" ID="284">/</RKE_WW013>
<RKE_WW015 Length="1" Alignment="left" Filler="blank" ID="285">/</RKE_WW015>
<RKE_WW016 Length="2" Alignment="left" Filler="blank" ID="286">/</RKE_WW016>
<RKE_WW017 Length="7" Alignment="left" Filler="blank" ID="287">/</RKE_WW017>
<RKE_WW019 Length="6" Alignment="left" Filler="blank" ID="289">/</RKE_WW019>
<!-- END new RKE-elements -->
<VBUND Length="6" Alignment="left" Filler="blank" ID="210">/</VBUND>
<FKBER Length="4" Alignment="left" Filler="blank" ID="211">/</FKBER>
<DABRZ Length="8" Alignment="left" Filler="blank" ID="212">/</DABRZ>
<XSTBA Length="1" Alignment="left" Filler="blank" ID="213">/</XSTBA>
<!-- START Additional (empty) tags start -->
<RSTGR Length="3" Alignment="left" Filler="blank" ID="214">/</RSTGR>
<FIPEX Length="24" Alignment="left" Filler="blank" ID="215">/</FIPEX>
<XNEGP Length="1" Alignment="left" Filler="blank" ID="216">/</XNEGP>
<GRICD Length="2" Alignment="left" Filler="blank" ID="217">/</GRICD>
<GRIRG Length="3" Alignment="left" Filler="blank" ID="218">/</GRIRG>
<GITYP Length="2" Alignment="left" Filler="blank" ID="219">/</GITYP>
<FITYP Length="2" Alignment="left" Filler="blank" ID="220">/</FITYP>
<STCDT Length="2" Alignment="left" Filler="blank" ID="221">/</STCDT>
<STKZN Length="1" Alignment="left" Filler="blank" ID="222">/</STKZN>
<STCD3 Length="18" Alignment="left" Filler="blank" ID="223">/</STCD3>
<STCD4 Length="18" Alignment="left" Filler="blank" ID="224">/</STCD4>
<XREF3 Length="20" Alignment="left" Filler="blank" ID="225">/</XREF3>
<KIDNO Length="30" Alignment="left" Filler="blank" ID="226">/</KIDNO>
<DTWS1 Length="2" Alignment="left" Filler="blank" ID="227">/</DTWS1>
<DTWS2 Length="2" Alignment="left" Filler="blank" ID="228">/</DTWS2>
<DTWS3 Length="2" Alignment="left" Filler="blank" ID="229">/</DTWS3>
<DTWS4 Length="2" Alignment="left" Filler="blank" ID="230">/</DTWS4>
<DTAWS Length="2" Alignment="left" Filler="blank" ID="231">/</DTAWS>
<PYCUR Length="5" Alignment="left" Filler="blank" ID="232">/</PYCUR>
<PYAMT Length="16" Alignment="left" Filler="blank" ID="233">/</PYAMT>
<BUPLA Length="4" Alignment="left" Filler="blank" ID="234">/</BUPLA>
<SECCO Length="4" Alignment="left" Filler="blank" ID="235">/</SECCO>
<LSTAR Length="6" Alignment="left" Filler="blank" ID="236">/</LSTAR>
<EGDEB Length="10" Alignment="left" Filler="blank" ID="237">/</EGDEB>
<WENR Length="8" Alignment="left" Filler="blank" ID="238">/</WENR>
<GENR Length="8" Alignment="left" Filler="blank" ID="239">/</GENR>
<GRNR Length="8" Alignment="left" Filler="blank" ID="240">/</GRNR>
<MENR Length="8" Alignment="left" Filler="blank" ID="241">/</MENR>
<MIVE Length="13" Alignment="left" Filler="blank" ID="242">/</MIVE>
<NKSL Length="4" Alignment="left" Filler="blank" ID="243">/</NKSL>
<EMPSL Length="5" Alignment="left" Filler="blank" ID="244">/</EMPSL>
<SVWNR Length="13" Alignment="left" Filler="blank" ID="245">/</SVWNR>
<SBERI Length="10" Alignment="left" Filler="blank" ID="246">/</SBERI>
<KKBER Length="4" Alignment="left" Filler="blank" ID="247">/</KKBER>
<EMPFB Length="10" Alignment="left" Filler="blank" ID="248">/</EMPFB>
<KURSR_M Length="10" Alignment="left" Filler="blank" ID="249">/</KURSR_M>
<J_1KFREPRE Length="10" Alignment="left" Filler="blank" ID="250">/</J_1KFREPRE>
<J_1KFTBUS Length="30" Alignment="left" Filler="blank" ID="251">/</J_1KFTBUS>
<J_1KFTIND Length="30" Alignment="left" Filler="blank" ID="252">/</J_1KFTIND>
<IDXSP Length="5" Alignment="left" Filler="blank" ID="253">/</IDXSP>
<ANRED Length="15" Alignment="left" Filler="blank" ID="254">/</ANRED>
<RECNNR Length="13" Alignment="left" Filler="blank" ID="255">/</RECNNR>
<E_MIVE Length="13" Alignment="left" Filler="blank" ID="256">/</E_MIVE>
<BKREF Length="20" Alignment="left" Filler="blank" ID="257">/</BKREF>
<DTAMS Length="1" Alignment="left" Filler="blank" ID="258">/</DTAMS>
<CESSION_KZ Length="2" Alignment="left" Filler="blank" ID="259">/</CESSION_KZ>
<GRANT_NBR Length="20" Alignment="left" Filler="blank" ID="260">/</GRANT_NBR>
<FKBER_LONG Length="16" Alignment="left" Filler="blank" ID="261">/</FKBER_LONG>
<ERLKZ Length="1" Alignment="left" Filler="blank" ID="262">/</ERLKZ>
<IBAN Length="34" Alignment="left" Filler="blank" ID="263">/</IBAN>
<VALID_FROM Length="8" Alignment="left" Filler="blank" ID="264">/</VALID_FROM>
<SEGMENT Length="10" Alignment="left" Filler="blank" ID="265">/</SEGMENT>
<PSEGMENT Length="10" Alignment="left" Filler="blank" ID="266">/</PSEGMENT>
<HKTID Length="5" Alignment="left" Filler="blank" ID="267">/</HKTID>
<XSIWE Length="1" Alignment="left" Filler="blank" ID="268">/</XSIWE>
<TCNO Length="16" Alignment="left" Filler="blank" ID="269">/</TCNO>
<DATEOFSERVICE Length="8" Alignment="left" Filler="blank" ID="270">/</DATEOFSERVICE>
<NOTAXCORR Length="1" Alignment="left" Filler="blank" ID="271">/</NOTAXCORR>
<DIFFOPTRATE Length="10" Alignment="left" Filler="blank" ID="272">/</DIFFOPTRATE>
<HASDIFFOPTRATE Length="1" Alignment="left" Filler="blank" ID="273">/</HASDIFFOPTRATE>
<SENDE Length="1" Alignment="left" Filler="blank" ID="274">/</SENDE>
<PRODPER Length="8" Alignment="left" Filler="blank" ID="275">/</PRODPER>
<!-- END Additional tags -->
</invoiceDetails_1_elements>
</xsl:template>
<xsl:template name="invoiceDetails_DetailCharges_1_elements">
<invoiceDetails_DetailCharges_1_elements>
<STYPE ID="1" Length="1" Alignment="left" Filler="blank">2</STYPE>
<TBNAM ID="2" Length="30" Alignment="left" Filler="blank">BBSEG</TBNAM>
<NEWBS ID="3" Length="2" Alignment="left" Filler="blank">
<xsl:if test="parent::node()/type='I'">40</xsl:if>
<xsl:if test="parent::node()/type='C'">50</xsl:if>
</NEWBS>
<DUMMYX ID="4" Length="10" Alignment="left" Filler="blank">/</DUMMYX>
<NEWUM ID="5" Length="1" Alignment="left" Filler="blank">/</NEWUM>
<NEWBK ID="6" Length="4" Alignment="left" Filler="blank">/</NEWBK>
<WRBTR ID="7" Length="16" Alignment="left" Filler="blank">
<!-- <xsl:value-of select="format-number(totalAmount, '#0.00', 'european')"/> -->
<xsl:value-of select="format-number(totalAmount, '0000000000000,00', 'european')"/>
</WRBTR>
<DMBTR ID="8" Length="16" Alignment="left" Filler="blank">/</DMBTR>
<WMWST ID="9" Length="16" Alignment="left" Filler="blank">/</WMWST>
<MWSTS ID="10" Length="16" Alignment="left" Filler="blank">/</MWSTS>
<MWSKZ ID="11" Length="2" Alignment="left" Filler="blank">
<xsl:value-of select="parent::node()/financialTaxCode" />
</MWSKZ>
<XSKRL ID="12" Length="1" Alignment="left" Filler="blank">/</XSKRL>
<FWZUZ ID="13" Length="16" Alignment="left" Filler="blank">/</FWZUZ>
<HWZUZ ID="14" Length="16" Alignment="left" Filler="blank">/</HWZUZ>
<GSBER ID="15" Length="4" Alignment="left" Filler="blank">/</GSBER>
<KOSTL ID="16" Length="10" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="financialCostcenter and string-length(financialCostcenter) &gt; 0">
<xsl:value-of select="financialCostcenter" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</KOSTL>
<DUMMY4 ID="17" Length="4" Alignment="left" Filler="blank">/</DUMMY4>
<AUFNR ID="18" Length="12" Alignment="left" Filler="blank">
<xsl:choose>
<xsl:when test="costcenter2 and string-length(costcenter2) &gt; 0">
<xsl:value-of select="costcenter2" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'/'" />
</xsl:otherwise>
</xsl:choose>
</AUFNR>
<EBELN ID="19" Length="10" Alignment="left" Filler="blank">/</EBELN>
<EBELP ID="20" Length="5" Alignment="left" Filler="blank">/</EBELP>
<PROJN ID="21" Length="16" Alignment="left" Filler="blank">/</PROJN>
<MATNR ID="22" Length="18" Alignment="left" Filler="blank">/</MATNR>
<WERKS ID="23" Length="4" Alignment="left" Filler="blank">/</WERKS>
<MENGE ID="24" Length="17" Alignment="left" Filler="blank">/</MENGE>
<MEINS ID="25" Length="3" Alignment="left" Filler="blank">/</MEINS>
<VBEL2 ID="26" Length="10" Alignment="left" Filler="blank">/</VBEL2>
<POSN2 ID="27" Length="6" Alignment="left" Filler="blank">/</POSN2>
<ETEN2 ID="28" Length="4" Alignment="left" Filler="blank">/</ETEN2>
<PERNR ID="29" Length="8" Alignment="left" Filler="blank">/</PERNR>
<BEWAR ID="30" Length="3" Alignment="left" Filler="blank">/</BEWAR>
<VALUT ID="31" Length="8" Alignment="left" Filler="blank">/</VALUT>
<ZFBDT ID="32" Length="8" Alignment="left" Filler="blank">/</ZFBDT>
<ZINKZ ID="33" Length="2" Alignment="left" Filler="blank">/</ZINKZ>
<ZUONR ID="34" Length="18" Alignment="left" Filler="blank">
<xsl:value-of select="orderNumber" />
<xsl:value-of select="'-'" />
<xsl:value-of select="itemNumber" />
</ZUONR>
<FKONT ID="35" Length="3" Alignment="left" Filler="blank">/</FKONT>
<XAABG ID="36" Length="1" Alignment="left" Filler="blank">/</XAABG>
<SGTXT ID="37" Length="50" Alignment="left" Filler="blank">
<xsl:variable name="twoDigitYear">
<xsl:value-of select="substring(parent::node()/financialPeriodYear, 3, 4)"/>
</xsl:variable>
<xsl:value-of select="$twoDigitYear" />
<xsl:value-of select="'/'" />
<xsl:value-of select="parent::node()/financialPeriodMonth" />
</SGTXT>
<BLNKZ ID="38" Alignment="left" Filler="blank" Length="2">/</BLNKZ>
<BLNBT ID="39" Alignment="left" Filler="blank" Length="16">/</BLNBT>
<BLNPZ ID="40" Alignment="left" Filler="blank" Length="8">/</BLNPZ>
<MABER ID="41" Alignment="left" Filler="blank" Length="2">/</MABER>
<SKFBT ID="42" Alignment="left" Filler="blank" Length="16">/</SKFBT>
<WSKTO ID="43" Alignment="left" Filler="blank" Length="16">/</WSKTO>
<ZTERM ID="44" Alignment="left" Filler="blank" Length="4">/</ZTERM>
<ZBD1T ID="45" Alignment="left" Filler="blank" Length="3">/</ZBD1T>
<ZBD1P ID="46" Alignment="left" Filler="blank" Length="6">/</ZBD1P>
<ZBD2T ID="47" Alignment="left" Filler="blank" Length="3">/</ZBD2T>
<ZBD2P ID="48" Alignment="left" Filler="blank" Length="6">/</ZBD2P>
<ZBD3T ID="49" Alignment="left" Filler="blank" Length="3">/</ZBD3T>
<ZLSPR ID="50" Alignment="left" Filler="blank" Length="1">/</ZLSPR>
<REBZG ID="51" Alignment="left" Filler="blank" Length="10">/</REBZG>
<REBZJ ID="52" Alignment="left" Filler="blank" Length="4">/</REBZJ>
<REBZZ ID="53" Alignment="left" Filler="blank" Length="3">/</REBZZ>
<ZLSCH ID="54" Alignment="left" Filler="blank" Length="1">/</ZLSCH>
<SAMNR ID="55" Alignment="left" Filler="blank" Length="8">/</SAMNR>
<ZBFIX ID="56" Alignment="left" Filler="blank" Length="1">/</ZBFIX>
<QSSKZ ID="57" Alignment="left" Filler="blank" Length="2">/</QSSKZ>
<QSSHB ID="58" Alignment="left" Filler="blank" Length="16">/</QSSHB>
<QSFBT ID="59" Alignment="left" Filler="blank" Length="16">/</QSFBT>
<ESRNR ID="60" Alignment="left" Filler="blank" Length="11">/</ESRNR>
<ESRPZ ID="61" Alignment="left" Filler="blank" Length="2">/</ESRPZ>
<ESRRE ID="62" Alignment="left" Filler="blank" Length="27">/</ESRRE>
<FDTAG ID="63" Alignment="left" Filler="blank" Length="8">/</FDTAG>
<FDLEV ID="64" Alignment="left" Filler="blank" Length="2">/</FDLEV>
<ANLN1 ID="65" Alignment="left" Filler="blank" Length="12">/</ANLN1>
<ANLN2 ID="66" Alignment="left" Filler="blank" Length="4">/</ANLN2>
<BZDAT ID="67" Alignment="left" Filler="blank" Length="8">/</BZDAT>
<ANBWA ID="68" Alignment="left" Filler="blank" Length="3">/</ANBWA>
<ABPER ID="69" Alignment="left" Filler="blank" Length="7">/</ABPER>
<GBETR ID="70" Alignment="left" Filler="blank" Length="16">/</GBETR>
<KURSR ID="71" Alignment="left" Filler="blank" Length="10">/</KURSR>
<MANSP ID="72" Alignment="left" Filler="blank" Length="1">/</MANSP>
<MSCHL ID="73" Alignment="left" Filler="blank" Length="1">/</MSCHL>
<HBKID ID="74" Alignment="left" Filler="blank" Length="5">/</HBKID>
<BVTYP ID="75" Alignment="left" Filler="blank" Length="4">/</BVTYP>
<ANFBN ID="76" Alignment="left" Filler="blank" Length="10">/</ANFBN>
<ANFBU ID="77" Alignment="left" Filler="blank" Length="4">/</ANFBU>
<ANFBJ ID="78" Alignment="left" Filler="blank" Length="4">/</ANFBJ>
<LZBKZ ID="79" Alignment="left" Filler="blank" Length="3">
<xsl:choose>
<xsl:when test="orderType='S'">
<xsl:value-of select="$constLZBZK_S_ORDER" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$constLZBZK_OTHER" />
</xsl:otherwise>
</xsl:choose>
</LZBKZ>
<LANDL ID="80" Alignment="left" Filler="blank" Length="3">/</LANDL>
<DIEKZ ID="81" Alignment="left" Filler="blank" Length="1">/</DIEKZ>
<ZOLLD ID="82" Alignment="left" Filler="blank" Length="8">/</ZOLLD>
<ZOLLT ID="83" Alignment="left" Filler="blank" Length="8">/</ZOLLT>
<VRSDT ID="84" Alignment="left" Filler="blank" Length="8">/</VRSDT>
<VRSKZ ID="85" Alignment="left" Filler="blank" Length="1">/</VRSKZ>
<HZUON ID="86" Alignment="left" Filler="blank" Length="18">/</HZUON>
<REGUL ID="87" Alignment="left" Filler="blank" Length="1">/</REGUL>
<NAME1 ID="88" Alignment="left" Filler="blank" Length="35">/</NAME1>
<NAME2 ID="89" Alignment="left" Filler="blank" Length="35">/</NAME2>
<NAME3 ID="90" Alignment="left" Filler="blank" Length="35">/</NAME3>
<NAME4 ID="91" Alignment="left" Filler="blank" Length="35">/</NAME4>
<STRAS ID="92" Alignment="left" Filler="blank" Length="35">/</STRAS>
<ORT01 ID="93" Alignment="left" Filler="blank" Length="35">/</ORT01>
<PSTLZ ID="94" Alignment="left" Filler="blank" Length="10">/</PSTLZ>
<LAND1 ID="95" Alignment="left" Filler="blank" Length="3">/</LAND1>
<REGIO ID="96" Alignment="left" Filler="blank" Length="3">/</REGIO>
<BANKL ID="97" Alignment="left" Filler="blank" Length="15">/</BANKL>
<BANKS ID="98" Alignment="left" Filler="blank" Length="3">/</BANKS>
<BANKN ID="99" Alignment="left" Filler="blank" Length="18">/</BANKN>
<BKONT ID="100" Alignment="left" Filler="blank" Length="2">/</BKONT>
<STCD1 ID="101" Alignment="left" Filler="blank" Length="16">/</STCD1>
<STCD2 ID="102" Alignment="left" Filler="blank" Length="11">/</STCD2>
<MADAT ID="103" Alignment="left" Filler="blank" Length="8">/</MADAT>
<MANST ID="104" Alignment="left" Filler="blank" Length="1">/</MANST>
<EGMLD ID="105" Alignment="left" Filler="blank" Length="3">/</EGMLD>
<DUMMY2 ID="106" Alignment="left" Filler="blank" Length="3">/</DUMMY2>
<STCEG ID="107" Alignment="left" Filler="blank" Length="20">/</STCEG>
<STKZA ID="108" Alignment="left" Filler="blank" Length="1">/</STKZA>
<STKZU ID="109" Alignment="left" Filler="blank" Length="1">/</STKZU>
<PFACH ID="110" Alignment="left" Filler="blank" Length="10">/</PFACH>
<PSTL2 ID="111" Alignment="left" Filler="blank" Length="10">/</PSTL2>
<SPRAS ID="112" Alignment="left" Filler="blank" Length="1">/</SPRAS>
<XINVE ID="113" Alignment="left" Filler="blank" Length="1">/</XINVE>
<NEWKO ID="114" Length="17" Alignment="left" Filler="blank">
<xsl:value-of select="accountNumber" />
</NEWKO>
<NEWBW Length="3" Alignment="left" Filler="blank" ID="115">/</NEWBW>
<KNRZE Length="17" Alignment="left" Filler="blank" ID="116">/</KNRZE>
<HKONT Length="10" Alignment="left" Filler="blank" ID="117">/</HKONT>
<PRCTR Length="10" Alignment="left" Filler="blank" ID="118">/</PRCTR>
<VERTN Length="13" Alignment="left" Filler="blank" ID="119">/</VERTN>
<VERTT Length="1" Alignment="left" Filler="blank" ID="120">/</VERTT>
<VBEWA Length="4" Alignment="left" Filler="blank" ID="121">/</VBEWA>
<HWBAS Length="16" Alignment="left" Filler="blank" ID="122">/</HWBAS>
<FWBAS Length="16" Alignment="left" Filler="blank" ID="123">/</FWBAS>
<FIPOS Length="14" Alignment="left" Filler="blank" ID="124">/</FIPOS>
<VNAME Length="6" Alignment="left" Filler="blank" ID="125">/</VNAME>
<EGRUP Length="3" Alignment="left" Filler="blank" ID="126">/</EGRUP>
<BTYPE Length="2" Alignment="left" Filler="blank" ID="127">/</BTYPE>
<PAOBJNR Length="10" Alignment="left" Filler="blank" ID="128">/</PAOBJNR>
<KSTRG Length="12" Alignment="left" Filler="blank" ID="129">/</KSTRG>
<IMKEY Length="8" Alignment="left" Filler="blank" ID="130">/</IMKEY>
<DUMMY3 Length="8" Alignment="left" Filler="blank" ID="131">/</DUMMY3>
<VPTNR Length="10" Alignment="left" Filler="blank" ID="132">/</VPTNR>
<NPLNR Length="12" Alignment="left" Filler="blank" ID="133">/</NPLNR>
<VORNR Length="4" Alignment="left" Filler="blank" ID="134">/</VORNR>
<XEGDR Length="1" Alignment="left" Filler="blank" ID="135">/</XEGDR>
<RECID Length="2" Alignment="left" Filler="blank" ID="136">/</RECID>
<PPRCT Length="10" Alignment="left" Filler="blank" ID="137">/</PPRCT>
<PROJK Length="24" Alignment="left" Filler="blank" ID="138">/</PROJK>
<UZAWE Length="2" Alignment="left" Filler="blank" ID="139">/</UZAWE>
<TXJCD Length="15" Alignment="left" Filler="blank" ID="140">/</TXJCD>
<FISTL Length="16" Alignment="left" Filler="blank" ID="141">/</FISTL>
<GEBER Length="10" Alignment="left" Filler="blank" ID="142">/</GEBER>
<DMBE2 Length="16" Alignment="left" Filler="blank" ID="143">/</DMBE2>
<DMBE3 Length="16" Alignment="left" Filler="blank" ID="144">/</DMBE3>
<PARGB Length="4" Alignment="left" Filler="blank" ID="145">/</PARGB>
<XREF1 Length="12" Alignment="left" Filler="blank" ID="146">/</XREF1>
<XREF2 Length="12" Alignment="left" Filler="blank" ID="147">/</XREF2>
<KBLNR Length="10" Alignment="left" Filler="blank" ID="149">/</KBLNR>
<KBLPOS Length="3" Alignment="left" Filler="blank" ID="150">/</KBLPOS>
<WDATE Length="8" Alignment="left" Filler="blank" ID="151">/</WDATE>
<WGBKZ Length="1" Alignment="left" Filler="blank" ID="152">/</WGBKZ>
<XAKTZ Length="1" Alignment="left" Filler="blank" ID="153">/</XAKTZ>
<WNAME Length="30" Alignment="left" Filler="blank" ID="154">/</WNAME>
<WORT1 Length="30" Alignment="left" Filler="blank" ID="155">/</WORT1>
<WBZOG Length="30" Alignment="left" Filler="blank" ID="156">/</WBZOG>
<WORT2 Length="30" Alignment="left" Filler="blank" ID="157">/</WORT2>
<WBANK Length="60" Alignment="left" Filler="blank" ID="158">/</WBANK>
<WLZBP Length="60" Alignment="left" Filler="blank" ID="159">/</WLZBP>
<DISKP Length="8" Alignment="left" Filler="blank" ID="160">/</DISKP>
<DISKT Length="3" Alignment="left" Filler="blank" ID="161">/</DISKT>
<WINFW Length="16" Alignment="left" Filler="blank" ID="162">/</WINFW>
<WINHW Length="16" Alignment="left" Filler="blank" ID="163">/</WINHW>
<WEVWV Length="1" Alignment="left" Filler="blank" ID="164">/</WEVWV>
<WSTAT Length="1" Alignment="left" Filler="blank" ID="165">/</WSTAT>
<WMWKZ Length="2" Alignment="left" Filler="blank" ID="166">/</WMWKZ>
<WSTKZ Length="1" Alignment="left" Filler="blank" ID="167">/</WSTKZ>
<RKE_ARTNR Length="18" Alignment="left" Filler="blank" ID="169">/</RKE_ARTNR>
<RKE_BONUS Length="2" Alignment="left" Filler="blank" ID="170">/</RKE_BONUS>
<RKE_BRSCH Length="4" Alignment="left" Filler="blank" ID="171">/</RKE_BRSCH>
<RKE_BUKRS Length="4" Alignment="left" Filler="blank" ID="172">/</RKE_BUKRS>
<RKE_BZIRK Length="6" Alignment="left" Filler="blank" ID="173">/</RKE_BZIRK>
<RKE_EFORM Length="5" Alignment="left" Filler="blank" ID="174">/</RKE_EFORM>
<RKE_FKART Length="4" Alignment="left" Filler="blank" ID="175">/</RKE_FKART>
<RKE_GEBIE Length="4" Alignment="left" Filler="blank" ID="176">/</RKE_GEBIE>
<RKE_GSBER Length="4" Alignment="left" Filler="blank" ID="177">/</RKE_GSBER>
<RKE_KAUFN Length="10" Alignment="left" Filler="blank" ID="178">/</RKE_KAUFN>
<RKE_KDGRP Length="2" Alignment="left" Filler="blank" ID="179">/</RKE_KDGRP>
<RKE_KDPOS Length="6" Alignment="left" Filler="blank" ID="180">/</RKE_KDPOS>
<RKE_KNDNR Length="10" Alignment="left" Filler="blank" ID="181">/</RKE_KNDNR>
<RKE_KOKRS Length="4" Alignment="left" Filler="blank" ID="182">/</RKE_KOKRS>
<RKE_KSTRG Length="12" Alignment="left" Filler="blank" ID="183">/</RKE_KSTRG>
<RKE_LAND1 Length="3" Alignment="left" Filler="blank" ID="184">/</RKE_LAND1>
<RKE_MAABC Length="1" Alignment="left" Filler="blank" ID="185">/</RKE_MAABC>
<RKE_MATKL Length="9" Alignment="left" Filler="blank" ID="186">/</RKE_MATKL>
<RKE_PRCTR Length="10" Alignment="left" Filler="blank" ID="187">/</RKE_PRCTR>
<RKE_PSPNR Length="24" Alignment="left" Filler="blank" ID="188">/</RKE_PSPNR>
<RKE_RKAUFNR Length="12" Alignment="left" Filler="blank" ID="189">/</RKE_RKAUFNR>
<RKE_SPART Length="2" Alignment="left" Filler="blank" ID="190">/</RKE_SPART>
<RKE_VKBUR Length="4" Alignment="left" Filler="blank" ID="191">/</RKE_VKBUR>
<RKE_VKGRP Length="3" Alignment="left" Filler="blank" ID="192">/</RKE_VKGRP>
<RKE_VKORG Length="4" Alignment="left" Filler="blank" ID="193">/</RKE_VKORG>
<RKE_VTWEG Length="2" Alignment="left" Filler="blank" ID="194">/</RKE_VTWEG>
<RKE_WERKS Length="4" Alignment="left" Filler="blank" ID="195">/</RKE_WERKS>
<RKE_KMBRND Length="2" Alignment="left" Filler="blank" ID="196">/</RKE_KMBRND>
<RKE_KMCATG Length="2" Alignment="left" Filler="blank" ID="197">/</RKE_KMCATG>
<RKE_KMHI01 Length="10" Alignment="left" Filler="blank" ID="198">/</RKE_KMHI01>
<RKE_KMHI02 Length="10" Alignment="left" Filler="blank" ID="199">/</RKE_KMHI02>
<RKE_KMHI03 Length="10" Alignment="left" Filler="blank" ID="200">/</RKE_KMHI03>
<RKE_KMKDGR Length="2" Alignment="left" Filler="blank" ID="201">/</RKE_KMKDGR>
<RKE_KMLAND Length="3" Alignment="left" Filler="blank" ID="202">/</RKE_KMLAND>
<RKE_KMMAKL Length="9" Alignment="left" Filler="blank" ID="203">/</RKE_KMMAKL>
<RKE_KMNIEL Length="2" Alignment="left" Filler="blank" ID="204">/</RKE_KMNIEL>
<RKE_KMSTGE Length="2" Alignment="left" Filler="blank" ID="205">/</RKE_KMSTGE>
<RKE_KMVKBU Length="4" Alignment="left" Filler="blank" ID="206">/</RKE_KMVKBU>
<RKE_KMVKGR Length="3" Alignment="left" Filler="blank" ID="207">/</RKE_KMVKGR>
<RKE_KMVTNR Length="8" Alignment="left" Filler="blank" ID="208">/</RKE_KMVTNR>
<RKE_PPRCTR Length="10" Alignment="left" Filler="blank" ID="209">/</RKE_PPRCTR>
<!-- START new RKE-elements -->
<RKE_WW005 Length="5" Alignment="left" Filler="blank" ID="276">/</RKE_WW005>
<RKE_WW006 Length="5" Alignment="left" Filler="blank" ID="277">/</RKE_WW006>
<RKE_WW007 Length="3" Alignment="left" Filler="blank" ID="278">/</RKE_WW007>
<RKE_WW008 Length="3" Alignment="left" Filler="blank" ID="279">/</RKE_WW008>
<RKE_WW009 Length="1" Alignment="left" Filler="blank" ID="280">/</RKE_WW009>
<RKE_WW010 Length="3" Alignment="left" Filler="blank" ID="281">/</RKE_WW010>
<RKE_WW011 Length="2" Alignment="left" Filler="blank" ID="282">/</RKE_WW011>
<RKE_WW012 Length="6" Alignment="left" Filler="blank" ID="283">/</RKE_WW012>
<RKE_WW013 Length="10" Alignment="left" Filler="blank" ID="284">/</RKE_WW013>
<RKE_WW015 Length="1" Alignment="left" Filler="blank" ID="285">/</RKE_WW015>
<RKE_WW016 Length="2" Alignment="left" Filler="blank" ID="286">/</RKE_WW016>
<RKE_WW017 Length="7" Alignment="left" Filler="blank" ID="287">/</RKE_WW017>
<RKE_WW019 Length="6" Alignment="left" Filler="blank" ID="289">/</RKE_WW019>
<!-- END new RKE-elements -->
<VBUND Length="6" Alignment="left" Filler="blank" ID="210">/</VBUND>
<FKBER Length="4" Alignment="left" Filler="blank" ID="211">/</FKBER>
<DABRZ Length="8" Alignment="left" Filler="blank" ID="212">/</DABRZ>
<XSTBA Length="1" Alignment="left" Filler="blank" ID="213">/</XSTBA>
<!-- Additional (empty) tags start -->
<RSTGR Length="3" Alignment="left" Filler="blank" ID="214">/</RSTGR>
<FIPEX Length="24" Alignment="left" Filler="blank" ID="215">/</FIPEX>
<XNEGP Length="1" Alignment="left" Filler="blank" ID="216">/</XNEGP>
<GRICD Length="2" Alignment="left" Filler="blank" ID="217">/</GRICD>
<GRIRG Length="3" Alignment="left" Filler="blank" ID="218">/</GRIRG>
<GITYP Length="2" Alignment="left" Filler="blank" ID="219">/</GITYP>
<FITYP Length="2" Alignment="left" Filler="blank" ID="220">/</FITYP>
<STCDT Length="2" Alignment="left" Filler="blank" ID="221">/</STCDT>
<STKZN Length="1" Alignment="left" Filler="blank" ID="222">/</STKZN>
<STCD3 Length="18" Alignment="left" Filler="blank" ID="223">/</STCD3>
<STCD4 Length="18" Alignment="left" Filler="blank" ID="224">/</STCD4>
<XREF3 Length="20" Alignment="left" Filler="blank" ID="225">/</XREF3>
<KIDNO Length="30" Alignment="left" Filler="blank" ID="226">/</KIDNO>
<DTWS1 Length="2" Alignment="left" Filler="blank" ID="227">/</DTWS1>
<DTWS2 Length="2" Alignment="left" Filler="blank" ID="228">/</DTWS2>
<DTWS3 Length="2" Alignment="left" Filler="blank" ID="229">/</DTWS3>
<DTWS4 Length="2" Alignment="left" Filler="blank" ID="230">/</DTWS4>
<DTAWS Length="2" Alignment="left" Filler="blank" ID="231">/</DTAWS>
<PYCUR Length="5" Alignment="left" Filler="blank" ID="232">/</PYCUR>
<PYAMT Length="16" Alignment="left" Filler="blank" ID="233">/</PYAMT>
<BUPLA Length="4" Alignment="left" Filler="blank" ID="234">/</BUPLA>
<SECCO Length="4" Alignment="left" Filler="blank" ID="235">/</SECCO>
<LSTAR Length="6" Alignment="left" Filler="blank" ID="236">/</LSTAR>
<EGDEB Length="10" Alignment="left" Filler="blank" ID="237">/</EGDEB>
<WENR Length="8" Alignment="left" Filler="blank" ID="238">/</WENR>
<GENR Length="8" Alignment="left" Filler="blank" ID="239">/</GENR>
<GRNR Length="8" Alignment="left" Filler="blank" ID="240">/</GRNR>
<MENR Length="8" Alignment="left" Filler="blank" ID="241">/</MENR>
<MIVE Length="13" Alignment="left" Filler="blank" ID="242">/</MIVE>
<NKSL Length="4" Alignment="left" Filler="blank" ID="243">/</NKSL>
<EMPSL Length="5" Alignment="left" Filler="blank" ID="244">/</EMPSL>
<SVWNR Length="13" Alignment="left" Filler="blank" ID="245">/</SVWNR>
<SBERI Length="10" Alignment="left" Filler="blank" ID="246">/</SBERI>
<KKBER Length="4" Alignment="left" Filler="blank" ID="247">/</KKBER>
<EMPFB Length="10" Alignment="left" Filler="blank" ID="248">/</EMPFB>
<KURSR_M Length="10" Alignment="left" Filler="blank" ID="249">/</KURSR_M>
<J_1KFREPRE Length="10" Alignment="left" Filler="blank" ID="250">/</J_1KFREPRE>
<J_1KFTBUS Length="30" Alignment="left" Filler="blank" ID="251">/</J_1KFTBUS>
<J_1KFTIND Length="30" Alignment="left" Filler="blank" ID="252">/</J_1KFTIND>
<IDXSP Length="5" Alignment="left" Filler="blank" ID="253">/</IDXSP>
<ANRED Length="15" Alignment="left" Filler="blank" ID="254">/</ANRED>
<RECNNR Length="13" Alignment="left" Filler="blank" ID="255">/</RECNNR>
<E_MIVE Length="13" Alignment="left" Filler="blank" ID="256">/</E_MIVE>
<BKREF Length="20" Alignment="left" Filler="blank" ID="257">/</BKREF>
<DTAMS Length="1" Alignment="left" Filler="blank" ID="258">/</DTAMS>
<CESSION_KZ Length="2" Alignment="left" Filler="blank" ID="259">/</CESSION_KZ>
<GRANT_NBR Length="20" Alignment="left" Filler="blank" ID="260">/</GRANT_NBR>
<FKBER_LONG Length="16" Alignment="left" Filler="blank" ID="261">/</FKBER_LONG>
<ERLKZ Length="1" Alignment="left" Filler="blank" ID="262">/</ERLKZ>
<IBAN Length="34" Alignment="left" Filler="blank" ID="263">/</IBAN>
<VALID_FROM Length="8" Alignment="left" Filler="blank" ID="264">/</VALID_FROM>
<SEGMENT Length="10" Alignment="left" Filler="blank" ID="265">/</SEGMENT>
<PSEGMENT Length="10" Alignment="left" Filler="blank" ID="266">/</PSEGMENT>
<HKTID Length="5" Alignment="left" Filler="blank" ID="267">/</HKTID>
<XSIWE Length="1" Alignment="left" Filler="blank" ID="268">/</XSIWE>
<TCNO Length="16" Alignment="left" Filler="blank" ID="269">/</TCNO>
<DATEOFSERVICE Length="8" Alignment="left" Filler="blank" ID="270">/</DATEOFSERVICE>
<NOTAXCORR Length="1" Alignment="left" Filler="blank" ID="271">/</NOTAXCORR>
<DIFFOPTRATE Length="10" Alignment="left" Filler="blank" ID="272">/</DIFFOPTRATE>
<HASDIFFOPTRATE Length="1" Alignment="left" Filler="blank" ID="273">/</HASDIFFOPTRATE>
<SENDE Length="1" Alignment="left" Filler="blank" ID="274">/</SENDE>
<PRODPER Length="8" Alignment="left" Filler="blank" ID="275">/</PRODPER>
<!-- Additional tags end -->
</invoiceDetails_DetailCharges_1_elements>
</xsl:template>
<!-- end transformation_2 -->
<!-- start transformation_1 -->
<xsl:template name="transformation_1_elements">
<xsl:apply-templates select="transferInvoice"/>
</xsl:template>
<xsl:template match="transferInvoice">
<transformation_1_elements>
<xsl:apply-templates select="invoice"/>
</transformation_1_elements>
</xsl:template>
<!-- end transformation_1 -->
<xsl:template match="invoice">
<invoice_elements>
<xsl:attribute name="invoiceNumber">
<xsl:value-of select="invoiceNumber"/>
</xsl:attribute>
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="invoiceHeader"/>
<xsl:apply-templates select="invoiceCharges"/>
<xsl:apply-templates select="invoiceDetails"/>
</invoice_elements>
</xsl:template>
<!-- start invoiceHeader transformation_1 -->
<xsl:template match="invoiceHeader">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="invoiceAmount"/>
<xsl:apply-templates select="orderInformation"/>
<xsl:apply-templates select="invoiceReversal"/>
<xsl:apply-templates select="invoiceTransferInformation"/>
<xsl:apply-templates select="paymentInformation"/>
<xsl:apply-templates select="financialPeriodInformation"/>
<xsl:apply-templates select="currencyConversionInformation"/>
</xsl:template>
<xsl:template match="invoiceAmount">
<internationalCurrencyCode>
<xsl:value-of select="*[position() = 1]/@internationalCurrencyCode"/>
</internationalCurrencyCode>
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="taxation"/>
</xsl:template>
<xsl:template match="taxation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="orderInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="invoiceReversal">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="invoiceTransferInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="paymentInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="financialPeriodInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="currencyConversionInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<!-- end invoiceHeader transformation_1 -->
<!-- start invoiceDetails transformation_1 -->
<xsl:template match="invoiceDetails">
<invoiceDetails_elements>
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="partInformation"/>
<xsl:apply-templates select="detailAmount"/>
<xsl:apply-templates select="orderInformation"/>
</invoiceDetails_elements>
<xsl:apply-templates select="detailCharges" mode="invoiceDetails"/>
</xsl:template>
<xsl:template match="orderInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="partInformation">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="detailAmount">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="taxation" />
</xsl:template>
<xsl:template match="chargeAmount">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="taxation" />
</xsl:template>
<xsl:template match="detailCharges" mode="invoiceDetails">
<invoiceDetails_DetailCharges_elements>
<xsl:apply-templates select="chargeType"/>
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="chargeAmount"/>
<xsl:apply-templates select="parent::node()/orderInformation"/>
</invoiceDetails_DetailCharges_elements>
</xsl:template>
<xsl:template match="chargeType">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<!-- end invoiceDetails transformation_1 -->
<!-- start invoiceCharges transformation_1 -->
<xsl:template match="invoiceCharges">
<invoiceCharges_elements>
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="chargeType" mode="invoiceCharges"/>
<xsl:apply-templates select="chargeAmount"/>
<xsl:apply-templates select="parent::node()/invoiceHeader/orderInformation"/>
</invoiceCharges_elements>
</xsl:template>
<xsl:template match="chargeType" mode="invoiceCharges">
<xsl:for-each select="*[count(./*) = 0]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<!-- end invoiceCharges transformation_1 -->
<xsl:template name="getFormatedDate">
<xsl:param name="date2format"/>
<xsl:variable name="y" select="substring($date2format, 1, 4)"/>
<xsl:variable name="m" select="substring($date2format, 6, 2)"/>
<xsl:variable name="d" select="substring($date2format, 9, 2)"/>
<xsl:value-of select="concat($y,$m,$d)"/>
</xsl:template>
<xsl:template name="getMonthOfDate">
<xsl:param name="date2format"/>
<xsl:variable name="y" select="substring($date2format, 1, 4)"/>
<xsl:variable name="m" select="substring($date2format, 6, 2)"/>
<xsl:variable name="d" select="substring($date2format, 9, 2)"/>
<xsl:value-of select="$m"/>
</xsl:template>
<xsl:template name="getYearOfDate">
<xsl:param name="date2format"/>
<xsl:variable name="y" select="substring($date2format, 1, 4)"/>
<xsl:variable name="m" select="substring($date2format, 6, 2)"/>
<xsl:variable name="d" select="substring($date2format, 9, 2)"/>
<xsl:value-of select="$y"/>
</xsl:template>
<xsl:template name="dup">
<xsl:param name="input"/>
<xsl:param name="count" select="2"/>
<xsl:choose>
<xsl:when test="not($count) or not($input)"/>
<xsl:when test="$count = 1">
<xsl:value-of select="$input"/>
</xsl:when>
<xsl:otherwise>
<!-- If $count is odd append an extra copy of input -->
<xsl:if test="$count mod 2">
<xsl:value-of select="$input"/>
</xsl:if>
<!-- Recursively apply template after doubling input and halving count -->
<xsl:call-template name="dup">
<xsl:with-param name="input" select="concat($input,$input)"/>
<xsl:with-param name="count" select="floor($count div 2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="justify">
<xsl:param name="value"/>
<xsl:param name="filler" select="' '"/>
<xsl:param name="width" select="10"/>
<xsl:param name="align" select=" 'left' "/>
<!-- Truncate if too long -->
<xsl:variable name="output" select="substring($value,1,$width)"/>
<xsl:choose>
<xsl:when test="$align = 'left' ">
<xsl:value-of select="$output"/>
<xsl:call-template name="dup">
<xsl:with-param name="input" select="$filler"/>
<xsl:with-param name="count" select="$width - string-length($output)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$align = 'right' ">
<xsl:call-template name="dup">
<xsl:with-param name="input" select="$filler"/>
<xsl:with-param name="count" select="$width - string-length($output)"/>
</xsl:call-template>
<xsl:value-of select="$output"/>
</xsl:when>
<xsl:when test="$align = 'center' ">
<xsl:call-template name="dup">
<xsl:with-param name="input" select="$filler"/>
<xsl:with-param name="count" select="floor(($width - string-length($output)) div 2)"/>
</xsl:call-template>
<xsl:value-of select="$output"/>
<xsl:call-template name="dup">
<xsl:with-param name="input" select="$filler"/>
<xsl:with-param name="count" select="ceiling(($width - string-length($output)) div 2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>INVALID ALIGN</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8150704
* @summary Test that XSL transformation with lots of temporary result trees will not run out of DTM IDs.
* @run testng/othervm TransformerTest
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TransformerTest {
@Test(dataProvider = "bug8150704")
public final void testBug8150704(String xsl, String xml, String ref) throws Exception {
System.out.println("Testing transformation of "+xml);
Transformer transformer = createTransformerFromResource(xsl);
StringWriter result = transformResourceToStringWriter(transformer, xml);
String resultstring = result.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n");
String reference = getFileContentAsString(new File(getClass().getResource(ref).getPath()));
Assert.assertEquals(resultstring, reference, "Output of transformation of "+xml+" does not match reference");
}
@DataProvider(name = "bug8150704")
private Object[][] dataBug8150704() {
return new Object[][] {
//xsl file, xml file, reference file
{"Bug8150704-1.xsl", "Bug8150704-1.xml", "Bug8150704-1.ref"},
{"Bug8150704-2.xsl", "Bug8150704-2.xml", "Bug8150704-2.ref"},
};
}
private Transformer createTransformerFromResource(String xslResource) throws TransformerException {
return TransformerFactory.newInstance().newTransformer(new StreamSource(getClass().getResource(xslResource).toString()));
}
private StringWriter transformResourceToStringWriter(Transformer transformer, String xmlResource) throws TransformerException {
StringWriter sw = new StringWriter();
transformer.transform(new StreamSource(getClass().getResource(xmlResource).toString()), new StreamResult(sw));
return sw;
}
/**
* Reads the contents of the given file into a string.
* WARNING: this method adds a final line feed even if the last line of the file doesn't contain one.
*
* @param f
* The file to read
* @return The content of the file as a string, with line terminators as \"n"
* for all platforms
* @throws IOException
* If there was an error reading
*/
private String getFileContentAsString(File f) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
String line;
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
}
}
}
external.lib.roots = ../../
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
/* @test /* @test
* @summary Test chat server chatserver test * @summary Test chat server chatserver test
* *
* @library ../../../src/share/sample/nio/chatserver * @library /src/share/sample/nio/chatserver
* @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader * @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader
* @run main ChatTest * @run testng ChatTest
*/ */
import java.io.*; import java.io.*;
...@@ -38,10 +38,13 @@ import java.util.Collections; ...@@ -38,10 +38,13 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
import org.testng.annotations.Test;
public class ChatTest { public class ChatTest {
public static int listeningPort = 0; public static int listeningPort = 0;
public static void main(String[] args) throws Throwable { @Test
public static void doTest() throws Throwable {
testStartStop(); testStartStop();
testPortOpen(); testPortOpen();
testAsksForName(); testAsksForName();
......
...@@ -25,14 +25,16 @@ ...@@ -25,14 +25,16 @@
/* @test /* @test
* @summary Test MergeSort * @summary Test MergeSort
* *
* @library ../../../src/share/sample/forkjoin/mergesort * @library /src/share/sample/forkjoin/mergesort
* @build MergeSortTest MergeDemo MergeSort * @build MergeSortTest MergeDemo MergeSort
* @run main MergeSortTest * @run testng MergeSortTest
*/ */
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; import java.util.Random;
import org.testng.annotations.Test;
public class MergeSortTest { public class MergeSortTest {
private Random random; private Random random;
private MergeSort target; private MergeSort target;
...@@ -42,7 +44,8 @@ public class MergeSortTest { ...@@ -42,7 +44,8 @@ public class MergeSortTest {
this.target = target; this.target = target;
} }
public static void main(String[] args) { @Test
public static void doTest() {
MergeSortTest test = new MergeSortTest(new Random(), new MergeSort(Runtime.getRuntime().availableProcessors() * 4)); MergeSortTest test = new MergeSortTest(new Random(), new MergeSort(Runtime.getRuntime().availableProcessors() * 4));
test.run(); test.run();
} }
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Signature;
import java.security.SignatureException;
import java.util.List;
/*
* Utilities for testing the signature algorithm OIDs.
*/
public class TestSignatureOidHelper {
private static final byte[] INPUT = "1234567890".getBytes();
private final String algorithm;
private final String provider;
private final int keySize;
private final List<OidAlgorithmPair> data;
public TestSignatureOidHelper(String algorithm, String provider,
int keySize, List<OidAlgorithmPair> data) {
this.algorithm = algorithm;
this.provider = provider;
this.keySize = keySize;
this.data = data;
}
public void execute() throws Exception {
KeyPair keyPair = createKeyPair();
for (OidAlgorithmPair oidAlgorithmPair : data) {
runTest(oidAlgorithmPair, keyPair);
System.out.println("passed");
}
System.out.println("All tests passed");
}
private KeyPair createKeyPair()
throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm,
provider);
keyGen.initialize(keySize);
return keyGen.generateKeyPair();
}
private void runTest(OidAlgorithmPair oidAlgorithmPair, KeyPair keyPair)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, SignatureException {
Signature sgAlgorithm =
Signature.getInstance(oidAlgorithmPair.algorithm, provider);
Signature sgOid = Signature.getInstance(oidAlgorithmPair.oid, provider);
if (sgAlgorithm == null) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance failed.%n",
oidAlgorithmPair.algorithm));
}
if (sgOid == null) {
throw new RuntimeException(
String.format("Test failed: OID %s getInstance failed.%n",
oidAlgorithmPair.oid));
}
if (!sgAlgorithm.getAlgorithm().equals(oidAlgorithmPair.algorithm)) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance "
+ "doesn't generate expected algorithm.%n",
oidAlgorithmPair.algorithm));
}
sgAlgorithm.initSign(keyPair.getPrivate());
sgAlgorithm.update(INPUT);
sgOid.initVerify(keyPair.getPublic());
sgOid.update(INPUT);
if (!sgOid.verify(sgAlgorithm.sign())) {
throw new RuntimeException(
"Signature verification failed unexpectedly");
}
}
}
class OidAlgorithmPair {
public final String oid;
public final String algorithm;
public OidAlgorithmPair(String oid, String algorithm) {
this.oid = oid;
this.algorithm = algorithm;
}
@Override
public String toString() {
return "[oid=" + oid + ", algorithm=" + algorithm + "]";
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Arrays;
import java.util.List;
/*
* @test
* @bug 8075286
* @summary Test the SHAwithECDSA signature algorithm OIDs in JDK.
* OID and algorithm transformation string should match.
* Both could be able to be used to generate the algorithm instance.
* @compile ../../TestSignatureOidHelper.java
* @run main TestSHAwithECDSASignatureOids
*/
public class TestSHAwithECDSASignatureOids {
private static final List<OidAlgorithmPair> DATA = Arrays.asList(
new OidAlgorithmPair("1.2.840.10045.4.1", "SHA1withECDSA"),
new OidAlgorithmPair("1.2.840.10045.4.3.1", "SHA224withECDSA"),
new OidAlgorithmPair("1.2.840.10045.4.3.2", "SHA256withECDSA"),
new OidAlgorithmPair("1.2.840.10045.4.3.3", "SHA384withECDSA"),
new OidAlgorithmPair("1.2.840.10045.4.3.4", "SHA512withECDSA"));
public static void main(String[] args) throws Exception {
TestSignatureOidHelper helper = new TestSignatureOidHelper("EC",
"SunEC", 256, DATA);
helper.execute();
}
}
/* /*
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,8 +23,9 @@ ...@@ -23,8 +23,9 @@
/* /*
* @test * @test
* @bug 8005408 8079129 * @bug 8005408 8079129 8048830
* @summary KeyStore API enhancements * @summary KeyStore API enhancements
* @run main StoreSecretKeyTest
*/ */
import java.io.*; import java.io.*;
...@@ -44,9 +45,20 @@ public class StoreSecretKeyTest { ...@@ -44,9 +45,20 @@ public class StoreSecretKeyTest {
private static final String CERT = DIR + "/trusted.pem"; private static final String CERT = DIR + "/trusted.pem";
private static final String ALIAS = "my trusted cert"; private static final String ALIAS = "my trusted cert";
private static final String ALIAS2 = "my secret key"; private static final String ALIAS2 = "my secret key";
private enum ALGORITHM {
DES(56),
DESede(168),
AES(128);
final int len;
ALGORITHM(int l) {
len = l;
}
final int getLength() {
return len;
}
}
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
boolean isSecretkeyAlgSupported = false;
// Skip test if AES is unavailable // Skip test if AES is unavailable
try { try {
SecretKeyFactory.getInstance("AES"); SecretKeyFactory.getInstance("AES");
...@@ -55,57 +67,69 @@ public class StoreSecretKeyTest { ...@@ -55,57 +67,69 @@ public class StoreSecretKeyTest {
return; return;
} }
new File(KEYSTORE).delete(); for (ALGORITHM alg : ALGORITHM.values()) {
isSecretkeyAlgSupported |= testSecretKeyAlgorithm(alg);
}
if (!isSecretkeyAlgSupported) {
throw new Exception("None of the SecretKey algorithms is "
+ "supported");
}
}
KeyStore keystore = KeyStore.getInstance("PKCS12"); private static boolean testSecretKeyAlgorithm(ALGORITHM algorithm) throws
keystore.load(null, null); Exception {
// Set trusted certificate entry System.out.println("Testing algorithm : " + algorithm.name());
Certificate cert = loadCertificate(CERT); new File(KEYSTORE).delete();
keystore.setEntry(ALIAS, try {
new KeyStore.TrustedCertificateEntry(cert), null); KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(null, null);
// Set secret key entry // Set trusted certificate entry
keystore.setEntry(ALIAS2, Certificate cert = loadCertificate(CERT);
new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)), keystore.setEntry(ALIAS,
new KeyStore.TrustedCertificateEntry(cert), null);
// Set secret key entry
SecretKey secretKey = generateSecretKey(algorithm.name(),
algorithm.len);
if(secretKey == null) {
return false;
}
keystore.setEntry(ALIAS2,
new KeyStore.SecretKeyEntry(secretKey),
new KeyStore.PasswordProtection(PASSWORD)); new KeyStore.PasswordProtection(PASSWORD));
try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) { try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
System.out.println("Storing keystore to: " + KEYSTORE); System.out.println("Storing keystore to: " + KEYSTORE);
keystore.store(outStream, PASSWORD); keystore.store(outStream, PASSWORD);
} }
try (FileInputStream inStream = new FileInputStream(KEYSTORE)) {
System.out.println("Loading keystore from: " + KEYSTORE);
keystore.load(inStream, PASSWORD);
System.out.println("Loaded keystore with " + keystore.size() +
" entries");
}
KeyStore.Entry entry = keystore.getEntry(ALIAS2, try (FileInputStream inStream = new FileInputStream(KEYSTORE)) {
new KeyStore.PasswordProtection(PASSWORD)); System.out.println("Loading keystore from: " + KEYSTORE);
System.out.println("Retrieved entry: " + entry); keystore.load(inStream, PASSWORD);
System.out.println("Loaded keystore with " + keystore.size() +
" entries");
}
if (entry instanceof KeyStore.SecretKeyEntry) { KeyStore.Entry entry = keystore.getEntry(ALIAS2,
System.out.println("Retrieved secret key entry: " + entry); new KeyStore.PasswordProtection(PASSWORD));
} else { System.out.println("Retrieved entry: " + entry);
throw new Exception("Not a secret key entry");
if (entry instanceof KeyStore.SecretKeyEntry) {
System.out.println("Retrieved secret key entry: " + entry);
} else {
throw new Exception("Not a secret key entry");
}
} catch (KeyStoreException | UnrecoverableKeyException ex) {
System.out.println("Unable to check SecretKey algorithm due to "
+ "exception: " + ex.getMessage());
return false;
} }
return true;
} }
private static SecretKey generateSecretKey(String algorithm, int size) private static SecretKey generateSecretKey(String algorithm, int size)
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
// Failover to DES if the requested secret key factory is unavailable
SecretKeyFactory keyFactory;
try {
keyFactory = SecretKeyFactory.getInstance(algorithm);
} catch (NoSuchAlgorithmException nsae) {
keyFactory = SecretKeyFactory.getInstance("DES");
algorithm = "DES";
size = 56;
}
KeyGenerator generator = KeyGenerator.getInstance(algorithm); KeyGenerator generator = KeyGenerator.getInstance(algorithm);
generator.init(size); generator.init(size);
return generator.generateKey(); return generator.generateKey();
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.DSAGenParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;
import java.util.List;
/*
* @test
* @bug 8075286
* @summary Verify that DSAGenParameterSpec can and can only be used to generate
* DSA within some certain range of key sizes as described in the class
* specification (L, N) as (1024, 160), (2048, 224), (2048, 256) and
* (3072, 256) should be OK for DSAGenParameterSpec. But the real
* implementation SUN doesn't support (3072, 256).
* @run main TestDSAGenParameterSpec
*/
public class TestDSAGenParameterSpec {
private static final String ALGORITHM_NAME = "DSA";
private static final String PROVIDER_NAME = "SUN";
private static final List<DataTuple> DATA = Arrays.asList(
new DataTuple(1024, 160, true, true),
new DataTuple(2048, 224, true, true),
new DataTuple(2048, 256, true, true),
new DataTuple(3072, 256, true, false),
new DataTuple(1024, 224),
new DataTuple(2048, 160),
new DataTuple(4096, 256),
new DataTuple(512, 160),
new DataTuple(3072, 224));
private static void testDSAGenParameterSpec(DataTuple dataTuple)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidParameterSpecException, InvalidAlgorithmParameterException {
System.out.printf("Test case: primePLen=%d, " + "subprimeQLen=%d%n",
dataTuple.primePLen, dataTuple.subprimeQLen);
AlgorithmParameterGenerator apg =
AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME,
PROVIDER_NAME);
DSAGenParameterSpec genParamSpec = createGenParameterSpec(dataTuple);
// genParamSpec will be null if IllegalAE is thrown when expected.
if (genParamSpec == null) {
return;
}
try {
apg.init(genParamSpec, null);
AlgorithmParameters param = apg.generateParameters();
checkParam(param, genParamSpec);
System.out.println("Test case passed");
} catch (InvalidParameterException ipe) {
// The DSAGenParameterSpec API support this, but the real
// implementation in SUN doesn't
if (!dataTuple.isSunProviderSupported) {
System.out.println("Test case passed: expected "
+ "InvalidParameterException is caught");
} else {
throw new RuntimeException("Test case failed.", ipe);
}
}
}
private static void checkParam(AlgorithmParameters param,
DSAGenParameterSpec genParam) throws InvalidParameterSpecException,
NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException {
String algorithm = param.getAlgorithm();
if (!algorithm.equalsIgnoreCase(ALGORITHM_NAME)) {
throw new RuntimeException(
"Unexpected type of parameters: " + algorithm);
}
DSAParameterSpec spec = param.getParameterSpec(DSAParameterSpec.class);
int valueL = spec.getP().bitLength();
int strengthP = genParam.getPrimePLength();
if (strengthP != valueL) {
System.out.printf("P: Expected %d but actual %d%n", strengthP,
valueL);
throw new RuntimeException("Wrong P strength");
}
int valueN = spec.getQ().bitLength();
int strengthQ = genParam.getSubprimeQLength();
if (strengthQ != valueN) {
System.out.printf("Q: Expected %d but actual %d%n", strengthQ,
valueN);
throw new RuntimeException("Wrong Q strength");
}
if (genParam.getSubprimeQLength() != genParam.getSeedLength()) {
System.out.println("Defaut seed length should be the same as Q.");
throw new RuntimeException("Wrong seed length");
}
// use the parameters to generate real DSA keys
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM_NAME,
PROVIDER_NAME);
keyGen.initialize(spec);
keyGen.generateKeyPair();
}
private static DSAGenParameterSpec createGenParameterSpec(
DataTuple dataTuple) {
DSAGenParameterSpec genParamSpec = null;
try {
genParamSpec = new DSAGenParameterSpec(dataTuple.primePLen,
dataTuple.subprimeQLen);
if (!dataTuple.isDSASpecSupported) {
throw new RuntimeException(
"Test case failed: the key length must not supported");
}
} catch (IllegalArgumentException e) {
if (!dataTuple.isDSASpecSupported) {
System.out.println("Test case passed: expected "
+ "IllegalArgumentException is caught");
} else {
throw new RuntimeException("Test case failed: unexpected "
+ "IllegalArgumentException is thrown", e);
}
}
return genParamSpec;
}
public static void main(String[] args) throws Exception {
for (DataTuple dataTuple : DATA) {
testDSAGenParameterSpec(dataTuple);
}
System.out.println("All tests passed");
}
private static class DataTuple {
private int primePLen;
private int subprimeQLen;
private boolean isDSASpecSupported;
private boolean isSunProviderSupported;
private DataTuple(int primePLen, int subprimeQLen,
boolean isDSASpecSupported, boolean isSunProviderSupported) {
this.primePLen = primePLen;
this.subprimeQLen = subprimeQLen;
this.isDSASpecSupported = isDSASpecSupported;
this.isSunProviderSupported = isSunProviderSupported;
}
private DataTuple(int primePLen, int subprimeQLen) {
this(primePLen, subprimeQLen, false, false);
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import java.util.List;
/*
* @test
* @bug 8075286
* @summary Test the SHA algorithm OIDs in JDK.
* OID and algorithm transformation string should match.
* Both could be able to be used to generate the algorithm instance.
* @run main TestSHAOids
*/
public class TestSHAOids {
private static final String PROVIDER_NAME = "SUN";
private static final byte[] INPUT = "1234567890".getBytes();
private static final List<DataTuple> DATA = Arrays.asList(
new DataTuple("2.16.840.1.101.3.4.2.1", "SHA-256"),
new DataTuple("2.16.840.1.101.3.4.2.2", "SHA-384"),
new DataTuple("2.16.840.1.101.3.4.2.3", "SHA-512"),
new DataTuple("2.16.840.1.101.3.4.2.4", "SHA-224"));
public static void main(String[] args) throws Exception {
for (DataTuple dataTuple : DATA) {
runTest(dataTuple);
System.out.println("passed");
}
System.out.println("All tests passed");
}
private static void runTest(DataTuple dataTuple)
throws NoSuchAlgorithmException, NoSuchProviderException {
MessageDigest mdAlgorithm = MessageDigest.getInstance(
dataTuple.algorithm, PROVIDER_NAME);
MessageDigest mdOid = MessageDigest.getInstance(dataTuple.oid,
PROVIDER_NAME);
if (mdAlgorithm == null) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance failed.%n",
dataTuple.algorithm));
}
if (mdOid == null) {
throw new RuntimeException(
String.format("Test failed: OID %s getInstance failed.%n",
dataTuple.oid));
}
if (!mdAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) {
throw new RuntimeException(String.format(
"Test failed: algorithm string %s getInstance doesn't "
+ "generate expected algorithm.%n",
dataTuple.algorithm));
}
mdAlgorithm.update(INPUT);
mdOid.update(INPUT);
// Comparison
if (!Arrays.equals(mdAlgorithm.digest(), mdOid.digest())) {
throw new RuntimeException("Digest comparison failed: "
+ "the two digests are not the same");
}
}
private static class DataTuple {
private final String oid;
private final String algorithm;
private DataTuple(String oid, String algorithm) {
this.oid = oid;
this.algorithm = algorithm;
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Arrays;
import java.util.List;
/*
* @test
* @bug 8075286
* @summary Test the SHAwithDSA signature algorithm OIDs in JDK.
* OID and algorithm transformation string should match.
* Both could be able to be used to generate the algorithm instance.
* @compile ../../TestSignatureOidHelper.java
* @run main TestSHAwithDSASignatureOids
*/
public class TestSHAwithDSASignatureOids {
private static final List<OidAlgorithmPair> DATA = Arrays.asList(
new OidAlgorithmPair("2.16.840.1.101.3.4.3.1", "SHA224withDSA"),
new OidAlgorithmPair("2.16.840.1.101.3.4.3.2", "SHA256withDSA"));
public static void main(String[] args) throws Exception {
TestSignatureOidHelper helper = new TestSignatureOidHelper("DSA",
"SUN", 1024, DATA);
helper.execute();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册