Merge
diff --git a/.hgtags b/.hgtags
index 89d6116..af1cb3c 100644
--- a/.hgtags
+++ b/.hgtags
@@ -576,3 +576,11 @@
ea965fea71f612d65013192aa637d88e05915b10 jdk8u92-b00
cc8d0d6c6f9543120836e70e0aa3fa9c9b6fe0f3 jdk8u92-b13
4f06a20cdc59ce9742e6538ff4b9040baba0778a jdk8u92-b14
+39baa472e20c13c0eb1243eb5dce589e82f78143 jdk8u76-b00
+6ea3aea950d19d803475b3f4d704a2942e71b302 jdk8u76-b01
+4de4cffb5988cd68959ce4bbd14c6d4547078c91 jdk8u76-b02
+8bef978e2374604f449b4d1d7f90cb26618540d7 jdk8u76-b03
+e057622070e5415c13b6d8511b97dce8bd2e398d jdk8u76-b04
+fa5a91b29658aa9eb7aff54ae34898c149ff7149 jdk8u102-b00
+fa5a91b29658aa9eb7aff54ae34898c149ff7149 jdk8u82-b00
+569e105bed3c517a47f0f1ebce0abcaf776a8e89 jdk8u102-b01
diff --git a/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java b/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java
index b905f75..d5eecf2 100644
--- a/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java
+++ b/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -30,11 +30,37 @@
import java.io.PrintWriter;
import java.util.Formatter;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
class ResourceBundleGenerator implements BundleGenerator {
+ // preferred timezones - keeping compatibility with JDK1.1 3 letter abbreviations
+ private static final String[] preferredTZIDs = {
+ "America/Los_Angeles",
+ "America/Denver",
+ "America/Phoenix",
+ "America/Chicago",
+ "America/New_York",
+ "America/Indianapolis",
+ "Pacific/Honolulu",
+ "America/Anchorage",
+ "America/Halifax",
+ "America/Sitka",
+ "America/St_Johns",
+ "Europe/Paris",
+ // Although CLDR does not support abbreviated zones, handle "GMT" as a
+ // special case here, as it is specified in the javadoc.
+ "GMT",
+ "Africa/Casablanca",
+ "Asia/Jerusalem",
+ "Asia/Tokyo",
+ "Europe/Bucharest",
+ "Asia/Shanghai",
+ "UTC",
+ };
+
@Override
public void generateBundle(String packageName, String baseName, String localeID, boolean useJava,
Map<String, ?> map, BundleType type) throws IOException {
@@ -89,6 +115,19 @@
for (String key : metaKeys) {
map.remove(key);
}
+
+ // Make it preferred ordered
+ LinkedHashMap<String, Object> newMap = new LinkedHashMap<>();
+ for (String preferred : preferredTZIDs) {
+ if (map.containsKey(preferred)) {
+ newMap.put(preferred, map.remove(preferred));
+ } else if (("GMT".equals(preferred) || "UTC".equals(preferred)) &&
+ metaKeys.contains(CLDRConverter.METAZONE_ID_PREFIX+preferred)) {
+ newMap.put(preferred, preferred);
+ }
+ }
+ newMap.putAll(map);
+ map = newMap;
}
try (PrintWriter out = new PrintWriter(file, encoding)) {
diff --git a/src/share/classes/com/sun/media/sound/SoftSynthesizer.java b/src/share/classes/com/sun/media/sound/SoftSynthesizer.java
index 9b1ff67..8464e5a 100644
--- a/src/share/classes/com/sun/media/sound/SoftSynthesizer.java
+++ b/src/share/classes/com/sun/media/sound/SoftSynthesizer.java
@@ -669,6 +669,40 @@
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>() {
+ public InputStream run() {
+ if (System.getProperties().getProperty("os.name")
.startsWith("Windows")) {
File gm_dls = new File(System.getenv("SystemRoot")
+ "\\system32\\drivers\\gm.dls");
diff --git a/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java b/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java
index 33cdb3a..a5b20bd 100644
--- a/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java
+++ b/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java
@@ -354,7 +354,14 @@
}
private void skipBytes(long length) throws IOException {
- in.skipBytes((int)length);
+ while (length > 0) {
+ long skipped = in.skip(length);
+ length -= skipped;
+ if (skipped == 0) {
+ // EOF or other problem, throw exception
+ throw new EOFException("Couldn't skip enough bytes");
+ }
+ }
}
private int readVersionHeader() throws IOException {
@@ -486,12 +493,12 @@
break;
}
case HPROF_GC_OBJ_ARRAY_DUMP: {
- int bytesRead = readArray(false);
+ long bytesRead = readArray(false);
bytesLeft -= bytesRead;
break;
}
case HPROF_GC_PRIM_ARRAY_DUMP: {
- int bytesRead = readArray(true);
+ long bytesRead = readArray(true);
bytesLeft -= bytesRead;
break;
}
@@ -743,12 +750,12 @@
// Handle a HPROF_GC_OBJ_ARRAY_DUMP or HPROF_GC_PRIM_ARRAY_DUMP
// Return number of bytes read
//
- private int readArray(boolean isPrimitive) throws IOException {
+ private long readArray(boolean isPrimitive) throws IOException {
long start = in.position();
long id = readID();
StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
int num = in.readInt();
- int bytesRead = identifierSize + 8;
+ long bytesRead = identifierSize + 8;
long elementClassID;
if (isPrimitive) {
elementClassID = in.readByte();
@@ -810,14 +817,14 @@
}
}
if (primitiveSignature != 0x00) {
- int size = elSize * num;
+ long size = elSize * (long)num;
bytesRead += size;
JavaValueArray va = new JavaValueArray(primitiveSignature, start);
skipBytes(size);
snapshot.addHeapObject(id, va);
snapshot.setSiteTrace(va, stackTrace);
} else {
- int sz = num * identifierSize;
+ long sz = (long)num * identifierSize;
bytesRead += sz;
JavaObjectArray arr = new JavaObjectArray(elementClassID, start);
skipBytes(sz);
diff --git a/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java b/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java
index 0c83e4d..3449a45 100644
--- a/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java
+++ b/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java
@@ -200,4 +200,9 @@
* Defined always to be true for arrays
*/
public boolean isFinal() { return true; }
+
+ /*
+ * Defined always to be false for arrays
+ */
+ public boolean isStatic() { return false; }
}
diff --git a/src/share/classes/java/lang/AbstractStringBuilder.java b/src/share/classes/java/lang/AbstractStringBuilder.java
index 3cde60d..4c31e23 100644
--- a/src/share/classes/java/lang/AbstractStringBuilder.java
+++ b/src/share/classes/java/lang/AbstractStringBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -112,29 +112,56 @@
}
/**
- * This method has the same contract as ensureCapacity, but is
- * never synchronized.
+ * For positive values of {@code minimumCapacity}, this method
+ * behaves like {@code ensureCapacity}, however it is never
+ * synchronized.
+ * If {@code minimumCapacity} is non positive due to numeric
+ * overflow, this method throws {@code OutOfMemoryError}.
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
- if (minimumCapacity - value.length > 0)
- expandCapacity(minimumCapacity);
+ if (minimumCapacity - value.length > 0) {
+ value = Arrays.copyOf(value,
+ newCapacity(minimumCapacity));
+ }
}
/**
- * This implements the expansion semantics of ensureCapacity with no
- * size check or synchronization.
+ * The maximum size of array to allocate (unless necessary).
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
*/
- void expandCapacity(int minimumCapacity) {
- int newCapacity = value.length * 2 + 2;
- if (newCapacity - minimumCapacity < 0)
- newCapacity = minimumCapacity;
- if (newCapacity < 0) {
- if (minimumCapacity < 0) // overflow
- throw new OutOfMemoryError();
- newCapacity = Integer.MAX_VALUE;
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Returns a capacity at least as large as the given minimum capacity.
+ * Returns the current capacity increased by the same amount + 2 if
+ * that suffices.
+ * Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
+ * unless the given minimum capacity is greater than that.
+ *
+ * @param minCapacity the desired minimum capacity
+ * @throws OutOfMemoryError if minCapacity is less than zero or
+ * greater than Integer.MAX_VALUE
+ */
+ private int newCapacity(int minCapacity) {
+ // overflow-conscious code
+ int newCapacity = (value.length << 1) + 2;
+ if (newCapacity - minCapacity < 0) {
+ newCapacity = minCapacity;
}
- value = Arrays.copyOf(value, newCapacity);
+ return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
+ ? hugeCapacity(minCapacity)
+ : newCapacity;
+ }
+
+ private int hugeCapacity(int minCapacity) {
+ if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
+ throw new OutOfMemoryError();
+ }
+ return (minCapacity > MAX_ARRAY_SIZE)
+ ? minCapacity : MAX_ARRAY_SIZE;
}
/**
diff --git a/src/share/classes/java/lang/StringBuffer.java b/src/share/classes/java/lang/StringBuffer.java
index 9bc8f3b..1638f30 100644
--- a/src/share/classes/java/lang/StringBuffer.java
+++ b/src/share/classes/java/lang/StringBuffer.java
@@ -171,9 +171,7 @@
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
- if (minimumCapacity > value.length) {
- expandCapacity(minimumCapacity);
- }
+ super.ensureCapacity(minimumCapacity);
}
/**
diff --git a/src/share/classes/java/lang/Thread.java b/src/share/classes/java/lang/Thread.java
index 274801c..7c8e83e 100644
--- a/src/share/classes/java/lang/Thread.java
+++ b/src/share/classes/java/lang/Thread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -145,7 +145,7 @@
registerNatives();
}
- private volatile char name[];
+ private volatile String name;
private int priority;
private Thread threadQ;
private long eetop;
@@ -366,7 +366,7 @@
throw new NullPointerException("name cannot be null");
}
- this.name = name.toCharArray();
+ this.name = name;
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
@@ -1119,7 +1119,11 @@
*/
public final synchronized void setName(String name) {
checkAccess();
- this.name = name.toCharArray();
+ if (name == null) {
+ throw new NullPointerException("name cannot be null");
+ }
+
+ this.name = name;
if (threadStatus != 0) {
setNativeName(name);
}
@@ -1132,7 +1136,7 @@
* @see #setName(String)
*/
public final String getName() {
- return new String(name, true);
+ return name;
}
/**
diff --git a/src/share/classes/java/math/BigInteger.java b/src/share/classes/java/math/BigInteger.java
index 6fa5d42..e35c723 100644
--- a/src/share/classes/java/math/BigInteger.java
+++ b/src/share/classes/java/math/BigInteger.java
@@ -276,6 +276,15 @@
*/
private static final int MULTIPLY_SQUARE_THRESHOLD = 20;
+ /**
+ * The threshold for using an intrinsic version of
+ * implMontgomeryXXX to perform Montgomery multiplication. If the
+ * number of ints in the number is more than this value we do not
+ * use the intrinsic.
+ */
+ private static final int MONTGOMERY_INTRINSIC_THRESHOLD = 512;
+
+
// Constructors
/**
@@ -1573,7 +1582,7 @@
* Multiplies int arrays x and y to the specified lengths and places
* the result into z. There will be no leading zeros in the resultant array.
*/
- private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
+ private static int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
int xstart = xlen - 1;
int ystart = ylen - 1;
@@ -1897,6 +1906,43 @@
* int array z. The contents of x are not changed.
*/
private static final int[] squareToLen(int[] x, int len, int[] z) {
+ int zlen = len << 1;
+ if (z == null || z.length < zlen)
+ z = new int[zlen];
+
+ // Execute checks before calling intrinsified method.
+ implSquareToLenChecks(x, len, z, zlen);
+ return implSquareToLen(x, len, z, zlen);
+ }
+
+ /**
+ * Parameters validation.
+ */
+ private static void implSquareToLenChecks(int[] x, int len, int[] z, int zlen) throws RuntimeException {
+ if (len < 1) {
+ throw new IllegalArgumentException("invalid input length: " + len);
+ }
+ if (len > x.length) {
+ throw new IllegalArgumentException("input length out of bound: " +
+ len + " > " + x.length);
+ }
+ if (len * 2 > z.length) {
+ throw new IllegalArgumentException("input length out of bound: " +
+ (len * 2) + " > " + z.length);
+ }
+ if (zlen < 1) {
+ throw new IllegalArgumentException("invalid input length: " + zlen);
+ }
+ if (zlen > z.length) {
+ throw new IllegalArgumentException("input length out of bound: " +
+ len + " > " + z.length);
+ }
+ }
+
+ /**
+ * Java Runtime may use intrinsic for this method.
+ */
+ private static final int[] implSquareToLen(int[] x, int len, int[] z, int zlen) {
/*
* The algorithm used here is adapted from Colin Plumb's C library.
* Technique: Consider the partial products in the multiplication
@@ -1931,9 +1977,6 @@
* again. The low bit is simply a copy of the low bit of the
* input, so it doesn't need special care.
*/
- int zlen = len << 1;
- if (z == null || z.length < zlen)
- z = new int[zlen];
// Store the squares, right shifted one bit (i.e., divided by 2)
int lastProductLowWord = 0;
@@ -2501,6 +2544,75 @@
return (invertResult ? result.modInverse(m) : result);
}
+ // Montgomery multiplication. These are wrappers for
+ // implMontgomeryXX routines which are expected to be replaced by
+ // virtual machine intrinsics. We don't use the intrinsics for
+ // very large operands: MONTGOMERY_INTRINSIC_THRESHOLD should be
+ // larger than any reasonable crypto key.
+ private static int[] montgomeryMultiply(int[] a, int[] b, int[] n, int len, long inv,
+ int[] product) {
+ implMontgomeryMultiplyChecks(a, b, n, len, product);
+ if (len > MONTGOMERY_INTRINSIC_THRESHOLD) {
+ // Very long argument: do not use an intrinsic
+ product = multiplyToLen(a, len, b, len, product);
+ return montReduce(product, n, len, (int)inv);
+ } else {
+ return implMontgomeryMultiply(a, b, n, len, inv, materialize(product, len));
+ }
+ }
+ private static int[] montgomerySquare(int[] a, int[] n, int len, long inv,
+ int[] product) {
+ implMontgomeryMultiplyChecks(a, a, n, len, product);
+ if (len > MONTGOMERY_INTRINSIC_THRESHOLD) {
+ // Very long argument: do not use an intrinsic
+ product = squareToLen(a, len, product);
+ return montReduce(product, n, len, (int)inv);
+ } else {
+ return implMontgomerySquare(a, n, len, inv, materialize(product, len));
+ }
+ }
+
+ // Range-check everything.
+ private static void implMontgomeryMultiplyChecks
+ (int[] a, int[] b, int[] n, int len, int[] product) throws RuntimeException {
+ if (len % 2 != 0) {
+ throw new IllegalArgumentException("input array length must be even: " + len);
+ }
+
+ if (len < 1) {
+ throw new IllegalArgumentException("invalid input length: " + len);
+ }
+
+ if (len > a.length ||
+ len > b.length ||
+ len > n.length ||
+ (product != null && len > product.length)) {
+ throw new IllegalArgumentException("input array length out of bound: " + len);
+ }
+ }
+
+ // Make sure that the int array z (which is expected to contain
+ // the result of a Montgomery multiplication) is present and
+ // sufficiently large.
+ private static int[] materialize(int[] z, int len) {
+ if (z == null || z.length < len)
+ z = new int[len];
+ return z;
+ }
+
+ // These methods are intended to be be replaced by virtual machine
+ // intrinsics.
+ private static int[] implMontgomeryMultiply(int[] a, int[] b, int[] n, int len,
+ long inv, int[] product) {
+ product = multiplyToLen(a, len, b, len, product);
+ return montReduce(product, n, len, (int)inv);
+ }
+ private static int[] implMontgomerySquare(int[] a, int[] n, int len,
+ long inv, int[] product) {
+ product = squareToLen(a, len, product);
+ return montReduce(product, n, len, (int)inv);
+ }
+
static int[] bnExpModThreshTable = {7, 25, 81, 241, 673, 1793,
Integer.MAX_VALUE}; // Sentinel
@@ -2579,6 +2691,17 @@
int[] mod = z.mag;
int modLen = mod.length;
+ // Make modLen even. It is conventional to use a cryptographic
+ // modulus that is 512, 768, 1024, or 2048 bits, so this code
+ // will not normally be executed. However, it is necessary for
+ // the correct functioning of the HotSpot intrinsics.
+ if ((modLen & 1) != 0) {
+ int[] x = new int[modLen + 1];
+ System.arraycopy(mod, 0, x, 1, modLen);
+ mod = x;
+ modLen++;
+ }
+
// Select an appropriate window size
int wbits = 0;
int ebits = bitLength(exp, exp.length);
@@ -2597,8 +2720,10 @@
for (int i=0; i < tblmask; i++)
table[i] = new int[modLen];
- // Compute the modular inverse
- int inv = -MutableBigInteger.inverseMod32(mod[modLen-1]);
+ // Compute the modular inverse of the least significant 64-bit
+ // digit of the modulus
+ long n0 = (mod[modLen-1] & LONG_MASK) + ((mod[modLen-2] & LONG_MASK) << 32);
+ long inv = -MutableBigInteger.inverseMod64(n0);
// Convert base to Montgomery form
int[] a = leftShift(base, base.length, modLen << 5);
@@ -2606,6 +2731,8 @@
MutableBigInteger q = new MutableBigInteger(),
a2 = new MutableBigInteger(a),
b2 = new MutableBigInteger(mod);
+ b2.normalize(); // MutableBigInteger.divide() assumes that its
+ // divisor is in normal form.
MutableBigInteger r= a2.divide(b2, q);
table[0] = r.toIntArray();
@@ -2614,22 +2741,19 @@
if (table[0].length < modLen) {
int offset = modLen - table[0].length;
int[] t2 = new int[modLen];
- for (int i=0; i < table[0].length; i++)
- t2[i+offset] = table[0][i];
+ System.arraycopy(table[0], 0, t2, offset, table[0].length);
table[0] = t2;
}
// Set b to the square of the base
- int[] b = squareToLen(table[0], modLen, null);
- b = montReduce(b, mod, modLen, inv);
+ int[] b = montgomerySquare(table[0], mod, modLen, inv, null);
// Set t to high half of b
int[] t = Arrays.copyOf(b, modLen);
// Fill in the table with odd powers of the base
for (int i=1; i < tblmask; i++) {
- int[] prod = multiplyToLen(t, modLen, table[i-1], modLen, null);
- table[i] = montReduce(prod, mod, modLen, inv);
+ table[i] = montgomeryMultiply(t, table[i-1], mod, modLen, inv, null);
}
// Pre load the window that slides over the exponent
@@ -2700,8 +2824,7 @@
isone = false;
} else {
t = b;
- a = multiplyToLen(t, modLen, mult, modLen, a);
- a = montReduce(a, mod, modLen, inv);
+ a = montgomeryMultiply(t, mult, mod, modLen, inv, a);
t = a; a = b; b = t;
}
}
@@ -2713,8 +2836,7 @@
// Square the input
if (!isone) {
t = b;
- a = squareToLen(t, modLen, a);
- a = montReduce(a, mod, modLen, inv);
+ a = montgomerySquare(t, mod, modLen, inv, a);
t = a; a = b; b = t;
}
}
@@ -2723,7 +2845,7 @@
int[] t2 = new int[2*modLen];
System.arraycopy(b, 0, t2, modLen, modLen);
- b = montReduce(t2, mod, modLen, inv);
+ b = montReduce(t2, mod, modLen, (int)inv);
t2 = Arrays.copyOf(b, modLen);
@@ -2791,6 +2913,32 @@
* Multiply an array by one word k and add to result, return the carry
*/
static int mulAdd(int[] out, int[] in, int offset, int len, int k) {
+ implMulAddCheck(out, in, offset, len, k);
+ return implMulAdd(out, in, offset, len, k);
+ }
+
+ /**
+ * Parameters validation.
+ */
+ private static void implMulAddCheck(int[] out, int[] in, int offset, int len, int k) {
+ if (len > in.length) {
+ throw new IllegalArgumentException("input length is out of bound: " + len + " > " + in.length);
+ }
+ if (offset < 0) {
+ throw new IllegalArgumentException("input offset is invalid: " + offset);
+ }
+ if (offset > (out.length - 1)) {
+ throw new IllegalArgumentException("input offset is out of bound: " + offset + " > " + (out.length - 1));
+ }
+ if (len > (out.length - offset)) {
+ throw new IllegalArgumentException("input len is out of bound: " + len + " > " + (out.length - offset));
+ }
+ }
+
+ /**
+ * Java Runtime may use intrinsic for this method.
+ */
+ private static int implMulAdd(int[] out, int[] in, int offset, int len, int k) {
long kLong = k & LONG_MASK;
long carry = 0;
diff --git a/src/share/classes/java/math/MutableBigInteger.java b/src/share/classes/java/math/MutableBigInteger.java
index 00e95aa..73a244f 100644
--- a/src/share/classes/java/math/MutableBigInteger.java
+++ b/src/share/classes/java/math/MutableBigInteger.java
@@ -2065,6 +2065,21 @@
}
/**
+ * Returns the multiplicative inverse of val mod 2^64. Assumes val is odd.
+ */
+ static long inverseMod64(long val) {
+ // Newton's iteration!
+ long t = val;
+ t *= 2 - val*t;
+ t *= 2 - val*t;
+ t *= 2 - val*t;
+ t *= 2 - val*t;
+ t *= 2 - val*t;
+ assert(t * val == 1);
+ return t;
+ }
+
+ /**
* Calculate the multiplicative inverse of 2^k mod mod, where mod is odd.
*/
static MutableBigInteger modInverseBP2(MutableBigInteger mod, int k) {
diff --git a/src/share/classes/java/net/URLConnection.java b/src/share/classes/java/net/URLConnection.java
index dd66ed2..7f7f43d 100644
--- a/src/share/classes/java/net/URLConnection.java
+++ b/src/share/classes/java/net/URLConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -1515,7 +1515,7 @@
}
if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
- if (c4 == 0xE0) {
+ if (c4 == 0xE0 || c4 == 0xEE) {
return "image/jpeg";
}
@@ -1530,10 +1530,6 @@
c11 == 0)) {
return "image/jpeg";
}
-
- if (c4 == 0xEE) {
- return "image/jpg";
- }
}
if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java
index 4629320..61bbe4e 100644
--- a/src/share/classes/java/util/logging/Logger.java
+++ b/src/share/classes/java/util/logging/Logger.java
@@ -800,6 +800,7 @@
* @param level One of the message level identifiers, e.g., SEVERE
* @param msgSupplier A function, which when called, produces the
* desired log message
+ * @since 1.8
*/
public void log(Level level, Supplier<String> msgSupplier) {
if (!isLoggable(level)) {
diff --git a/src/share/classes/javax/swing/TimerQueue.java b/src/share/classes/javax/swing/TimerQueue.java
index a6791d6..7092b45 100644
--- a/src/share/classes/javax/swing/TimerQueue.java
+++ b/src/share/classes/javax/swing/TimerQueue.java
@@ -93,6 +93,9 @@
void startIfNeeded() {
if (! running) {
runningLock.lock();
+ if (running) {
+ return;
+ }
try {
final ThreadGroup threadGroup =
AppContext.getAppContext().getThreadGroup();
@@ -168,15 +171,17 @@
try {
while (running) {
try {
- Timer timer = queue.take().getTimer();
+ DelayedTimer runningTimer = queue.take();
+ Timer timer = runningTimer.getTimer();
timer.getLock().lock();
try {
DelayedTimer delayedTimer = timer.delayedTimer;
- if (delayedTimer != null) {
+ if (delayedTimer == runningTimer) {
/*
- * Timer is not removed after we get it from
- * the queue and before the lock on the timer is
- * acquired
+ * Timer is not removed (delayedTimer != null)
+ * or not removed and added (runningTimer == delayedTimer)
+ * after we get it from the queue and before the
+ * lock on the timer is acquired
*/
timer.post(); // have timer post an event
timer.delayedTimer = null;
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java b/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java
index 190b94b..f134ad1 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -870,18 +870,13 @@
int orientation = SwingConstants.VERTICAL;
// find which scrollbar to scroll, or return if none
- if (toScroll == null || !toScroll.isVisible()) {
+ if (toScroll == null || !toScroll.isVisible()
+ || e.isShiftDown()) {
toScroll = scrollpane.getHorizontalScrollBar();
if (toScroll == null || !toScroll.isVisible()) {
return;
}
orientation = SwingConstants.HORIZONTAL;
- } else if(e.isShiftDown()){
- JScrollBar hScroll = scrollpane.getHorizontalScrollBar();
- if (hScroll != null && hScroll.isVisible()) {
- toScroll = hScroll;
- orientation = SwingConstants.HORIZONTAL;
- }
}
e.consume();
diff --git a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
index bf4e28b..209de66 100644
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $
@@ -111,7 +111,8 @@
try {
ResourceResolver apacheResolver =
ResourceResolver.getInstance(uriAttr, baseURI, secVal);
- XMLSignatureInput in = apacheResolver.resolve(uriAttr, baseURI);
+ XMLSignatureInput in = apacheResolver.resolve(uriAttr,
+ baseURI, secVal);
if (in.isOctetStream()) {
return new ApacheOctetStreamData(in);
} else {
diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java
index 79c2792..a5bd0f5 100644
--- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java
+++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java
@@ -2898,13 +2898,7 @@
return comp;
}
} else {
- // First, prefer application types.
- comp = compareIndices(primaryTypes, primaryType1, primaryType2,
- UNKNOWN_OBJECT_LOSES);
- if (comp != 0) {
- return comp;
- }
-
+ // First, prefer text types
if (flavor1.isFlavorTextType()) {
return 1;
}
@@ -2913,6 +2907,13 @@
return -1;
}
+ // Next, prefer application types.
+ comp = compareIndices(primaryTypes, primaryType1, primaryType2,
+ UNKNOWN_OBJECT_LOSES);
+ if (comp != 0) {
+ return comp;
+ }
+
// Next, look for application/x-java-* types. Prefer unknown
// MIME types because if the user provides his own data flavor,
// it will likely be the most descriptive one.
diff --git a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
index 3ff602b..56287ed 100644
--- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
+++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java
@@ -30,9 +30,12 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
@@ -40,6 +43,7 @@
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
import java.rmi.server.RemoteObject;
import java.rmi.server.UnicastRemoteObject;
import java.security.KeyStore;
@@ -59,6 +63,8 @@
import javax.management.remote.rmi.RMIConnectorServer;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
@@ -107,6 +113,8 @@
public static final String PORT =
"com.sun.management.jmxremote.port";
+ public static final String HOST =
+ "com.sun.management.jmxremote.host";
public static final String RMI_PORT =
"com.sun.management.jmxremote.rmi.port";
public static final String CONFIG_FILE_NAME =
@@ -424,10 +432,14 @@
checkAccessFile(accessFileName);
}
+ final String bindAddress =
+ props.getProperty(PropertyNames.HOST);
+
if (log.debugOn()) {
log.debug("startRemoteConnectorServer",
Agent.getText("jmxremote.ConnectorBootstrap.starting") +
"\n\t" + PropertyNames.PORT + "=" + port +
+ (bindAddress == null ? "" : "\n\t" + PropertyNames.HOST + "=" + bindAddress) +
"\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort +
"\n\t" + PropertyNames.USE_SSL + "=" + useSsl +
"\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl +
@@ -458,7 +470,7 @@
sslConfigFileName, enabledCipherSuitesList,
enabledProtocolsList, sslNeedClientAuth,
useAuthentication, loginConfigName,
- passwordFileName, accessFileName);
+ passwordFileName, accessFileName, bindAddress);
cs = data.jmxConnectorServer;
url = data.jmxRemoteURL;
log.config("startRemoteConnectorServer",
@@ -631,12 +643,13 @@
String sslConfigFileName,
String[] enabledCipherSuites,
String[] enabledProtocols,
- boolean sslNeedClientAuth) {
+ boolean sslNeedClientAuth,
+ String bindAddress) {
if (sslConfigFileName == null) {
- return new SslRMIServerSocketFactory(
+ return new HostAwareSslSocketFactory(
enabledCipherSuites,
enabledProtocols,
- sslNeedClientAuth);
+ sslNeedClientAuth, bindAddress);
} else {
checkRestrictedFile(sslConfigFileName);
try {
@@ -690,11 +703,11 @@
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
- return new SslRMIServerSocketFactory(
+ return new HostAwareSslSocketFactory(
ctx,
enabledCipherSuites,
enabledProtocols,
- sslNeedClientAuth);
+ sslNeedClientAuth, bindAddress);
} catch (Exception e) {
throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
}
@@ -714,7 +727,8 @@
boolean useAuthentication,
String loginConfigName,
String passwordFileName,
- String accessFileName)
+ String accessFileName,
+ String bindAddress)
throws IOException, MalformedURLException {
/* Make sure we use non-guessable RMI object IDs. Otherwise
@@ -722,7 +736,7 @@
* IDs. */
System.setProperty("java.rmi.server.randomIDs", "true");
- JMXServiceURL url = new JMXServiceURL("rmi", null, rmiPort);
+ JMXServiceURL url = new JMXServiceURL("rmi", bindAddress, rmiPort);
Map<String, Object> env = new HashMap<>();
@@ -733,6 +747,8 @@
String[].class.getName(), String.class.getName()
});
+ boolean useSocketFactory = bindAddress != null && !useSsl;
+
if (useAuthentication) {
if (loginConfigName != null) {
env.put("jmx.remote.x.login.config", loginConfigName);
@@ -757,7 +773,7 @@
csf = new SslRMIClientSocketFactory();
ssf = createSslRMIServerSocketFactory(
sslConfigFileName, enabledCipherSuites,
- enabledProtocols, sslNeedClientAuth);
+ enabledProtocols, sslNeedClientAuth, bindAddress);
}
if (useSsl) {
@@ -767,6 +783,12 @@
ssf);
}
+ if (useSocketFactory) {
+ ssf = new HostAwareSocketFactory(bindAddress);
+ env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
+ ssf);
+ }
+
JMXConnectorServer connServer = null;
try {
connServer =
@@ -786,6 +808,10 @@
registry =
new SingleEntryRegistry(port, csf, ssf,
"jmxrmi", exporter.firstExported);
+ } else if (useSocketFactory) {
+ registry =
+ new SingleEntryRegistry(port, csf, ssf,
+ "jmxrmi", exporter.firstExported);
} else {
registry =
new SingleEntryRegistry(port,
@@ -819,4 +845,172 @@
private static final ClassLogger log =
new ClassLogger(ConnectorBootstrap.class.getPackage().getName(),
"ConnectorBootstrap");
+
+ private static class HostAwareSocketFactory implements RMIServerSocketFactory {
+
+ private final String bindAddress;
+
+ private HostAwareSocketFactory(String bindAddress) {
+ this.bindAddress = bindAddress;
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ if (bindAddress == null) {
+ return new ServerSocket(port);
+ } else {
+ try {
+ InetAddress addr = InetAddress.getByName(bindAddress);
+ return new ServerSocket(port, 0, addr);
+ } catch (UnknownHostException e) {
+ return new ServerSocket(port);
+ }
+ }
+ }
+ }
+
+ private static class HostAwareSslSocketFactory extends SslRMIServerSocketFactory {
+
+ private final String bindAddress;
+ private final String[] enabledCipherSuites;
+ private final String[] enabledProtocols;
+ private final boolean needClientAuth;
+ private final SSLContext context;
+
+ private HostAwareSslSocketFactory(String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean sslNeedClientAuth,
+ String bindAddress) throws IllegalArgumentException {
+ this(null, enabledCipherSuites, enabledProtocols, sslNeedClientAuth, bindAddress);
+ }
+
+ private HostAwareSslSocketFactory(SSLContext ctx,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean sslNeedClientAuth,
+ String bindAddress) throws IllegalArgumentException {
+ this.context = ctx;
+ this.bindAddress = bindAddress;
+ this.enabledProtocols = enabledProtocols;
+ this.enabledCipherSuites = enabledCipherSuites;
+ this.needClientAuth = sslNeedClientAuth;
+ checkValues(ctx, enabledCipherSuites, enabledProtocols);
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ if (bindAddress != null) {
+ try {
+ InetAddress addr = InetAddress.getByName(bindAddress);
+ return new SslServerSocket(port, 0, addr, context,
+ enabledCipherSuites, enabledProtocols, needClientAuth);
+ } catch (UnknownHostException e) {
+ return new SslServerSocket(port, context,
+ enabledCipherSuites, enabledProtocols, needClientAuth);
+ }
+ } else {
+ return new SslServerSocket(port, context,
+ enabledCipherSuites, enabledProtocols, needClientAuth);
+ }
+ }
+
+ private static void checkValues(SSLContext context,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols) throws IllegalArgumentException {
+ // Force the initialization of the default at construction time,
+ // rather than delaying it to the first time createServerSocket()
+ // is called.
+ //
+ final SSLSocketFactory sslSocketFactory =
+ context == null ?
+ (SSLSocketFactory)SSLSocketFactory.getDefault() : context.getSocketFactory();
+ SSLSocket sslSocket = null;
+ if (enabledCipherSuites != null || enabledProtocols != null) {
+ try {
+ sslSocket = (SSLSocket) sslSocketFactory.createSocket();
+ } catch (Exception e) {
+ final String msg = "Unable to check if the cipher suites " +
+ "and protocols to enable are supported";
+ throw (IllegalArgumentException)
+ new IllegalArgumentException(msg).initCause(e);
+ }
+ }
+
+ // Check if all the cipher suites and protocol versions to enable
+ // are supported by the underlying SSL/TLS implementation and if
+ // true create lists from arrays.
+ //
+ if (enabledCipherSuites != null) {
+ sslSocket.setEnabledCipherSuites(enabledCipherSuites);
+ }
+ if (enabledProtocols != null) {
+ sslSocket.setEnabledProtocols(enabledProtocols);
+ }
+ }
+ }
+
+ private static class SslServerSocket extends ServerSocket {
+
+ private static SSLSocketFactory defaultSSLSocketFactory;
+ private final String[] enabledCipherSuites;
+ private final String[] enabledProtocols;
+ private final boolean needClientAuth;
+ private final SSLContext context;
+
+ private SslServerSocket(int port,
+ SSLContext ctx,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean needClientAuth) throws IOException {
+ super(port);
+ this.enabledProtocols = enabledProtocols;
+ this.enabledCipherSuites = enabledCipherSuites;
+ this.needClientAuth = needClientAuth;
+ this.context = ctx;
+ }
+
+ private SslServerSocket(int port,
+ int backlog,
+ InetAddress bindAddr,
+ SSLContext ctx,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean needClientAuth) throws IOException {
+ super(port, backlog, bindAddr);
+ this.enabledProtocols = enabledProtocols;
+ this.enabledCipherSuites = enabledCipherSuites;
+ this.needClientAuth = needClientAuth;
+ this.context = ctx;
+ }
+
+ @Override
+ public Socket accept() throws IOException {
+ final SSLSocketFactory sslSocketFactory =
+ context == null ?
+ getDefaultSSLSocketFactory() : context.getSocketFactory();
+ Socket socket = super.accept();
+ SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
+ socket, socket.getInetAddress().getHostName(),
+ socket.getPort(), true);
+ sslSocket.setUseClientMode(false);
+ if (enabledCipherSuites != null) {
+ sslSocket.setEnabledCipherSuites(enabledCipherSuites);
+ }
+ if (enabledProtocols != null) {
+ sslSocket.setEnabledProtocols(enabledProtocols);
+ }
+ sslSocket.setNeedClientAuth(needClientAuth);
+ return sslSocket;
+ }
+
+ private static synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
+ if (defaultSSLSocketFactory == null) {
+ defaultSSLSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
+ return defaultSSLSocketFactory;
+ } else {
+ return defaultSSLSocketFactory;
+ }
+ }
+
+ }
}
diff --git a/src/share/classes/sun/rmi/transport/DGCAckHandler.java b/src/share/classes/sun/rmi/transport/DGCAckHandler.java
index 7f70440..18e9ec0 100644
--- a/src/share/classes/sun/rmi/transport/DGCAckHandler.java
+++ b/src/share/classes/sun/rmi/transport/DGCAckHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -118,6 +118,9 @@
if (objList != null && task == null) {
task = scheduler.schedule(new Runnable() {
public void run() {
+ if (id != null) {
+ idTable.remove(id);
+ }
release();
}
}, dgcAckTimeout, TimeUnit.MILLISECONDS);
diff --git a/src/share/classes/sun/security/pkcs/PKCS7.java b/src/share/classes/sun/security/pkcs/PKCS7.java
index fdc295c..19211ae 100644
--- a/src/share/classes/sun/security/pkcs/PKCS7.java
+++ b/src/share/classes/sun/security/pkcs/PKCS7.java
@@ -802,7 +802,8 @@
byte[] content,
String signatureAlgorithm,
URI tsaURI,
- String tSAPolicyID)
+ String tSAPolicyID,
+ String tSADigestAlg)
throws CertificateException, IOException, NoSuchAlgorithmException
{
@@ -811,7 +812,8 @@
if (tsaURI != null) {
// Timestamp the signature
HttpTimestamper tsa = new HttpTimestamper(tsaURI);
- byte[] tsToken = generateTimestampToken(tsa, tSAPolicyID, signature);
+ byte[] tsToken = generateTimestampToken(
+ tsa, tSAPolicyID, tSADigestAlg, signature);
// Insert the timestamp token into the PKCS #7 signer info element
// (as an unsigned attribute)
@@ -869,6 +871,7 @@
*/
private static byte[] generateTimestampToken(Timestamper tsa,
String tSAPolicyID,
+ String tSADigestAlg,
byte[] toBeTimestamped)
throws IOException, CertificateException
{
@@ -876,11 +879,10 @@
MessageDigest messageDigest = null;
TSRequest tsQuery = null;
try {
- // SHA-1 is always used.
- messageDigest = MessageDigest.getInstance("SHA-1");
+ messageDigest = MessageDigest.getInstance(tSADigestAlg);
tsQuery = new TSRequest(tSAPolicyID, toBeTimestamped, messageDigest);
} catch (NoSuchAlgorithmException e) {
- // ignore
+ throw new IllegalArgumentException(e);
}
// Generate a nonce
@@ -908,9 +910,13 @@
PKCS7 tsToken = tsReply.getToken();
TimestampToken tst = tsReply.getTimestampToken();
- if (!tst.getHashAlgorithm().getName().equals("SHA-1")) {
- throw new IOException("Digest algorithm not SHA-1 in "
- + "timestamp token");
+ try {
+ if (!tst.getHashAlgorithm().equals(AlgorithmId.get(tSADigestAlg))) {
+ throw new IOException("Digest algorithm not " + tSADigestAlg + " in "
+ + "timestamp token");
+ }
+ } catch (NoSuchAlgorithmException nase) {
+ throw new IllegalArgumentException(); // should have been caught before
}
if (!MessageDigest.isEqual(tst.getHashedMessage(),
tsQuery.getHashedMessage())) {
diff --git a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
index ca4d2d3..25fc78c 100644
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -383,19 +383,19 @@
// decode secret key
} else {
- SecretKeyFactory sKeyFactory =
- SecretKeyFactory.getInstance(keyAlgo);
byte[] keyBytes = in.getOctetString();
SecretKeySpec secretKeySpec =
new SecretKeySpec(keyBytes, keyAlgo);
// Special handling required for PBE: needs a PBEKeySpec
if (keyAlgo.startsWith("PBE")) {
+ SecretKeyFactory sKeyFactory =
+ SecretKeyFactory.getInstance(keyAlgo);
KeySpec pbeKeySpec =
sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class);
key = sKeyFactory.generateSecret(pbeKeySpec);
} else {
- key = sKeyFactory.generateSecret(secretKeySpec);
+ key = secretKeySpec;
}
if (debug != null) {
diff --git a/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java b/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java
index db36c0e..0ad5387 100644
--- a/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java
+++ b/src/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java
@@ -36,9 +36,7 @@
import sun.security.util.Debug;
import sun.security.util.DerInputStream;
-import sun.security.util.DerOutputStream;
import sun.security.x509.SerialNumber;
-import sun.security.x509.KeyIdentifier;
import sun.security.x509.AuthorityKeyIdentifierExtension;
/**
@@ -131,13 +129,7 @@
serial = null;
if (ext != null) {
- KeyIdentifier akid = (KeyIdentifier)ext.get(
- AuthorityKeyIdentifierExtension.KEY_ID);
- if (akid != null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- ski = derout.toByteArray();
- }
+ ski = ext.getEncodedKeyIdentifier();
SerialNumber asn = (SerialNumber)ext.get(
AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
if (asn != null) {
diff --git a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
index 7b1076e..086e73f 100644
--- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
+++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
@@ -33,7 +33,6 @@
import java.util.*;
import sun.security.util.Debug;
-import sun.security.util.DerOutputStream;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*;
@@ -608,12 +607,9 @@
AuthorityKeyIdentifierExtension akidext =
crlImpl.getAuthKeyIdExtension();
if (akidext != null) {
- KeyIdentifier akid = (KeyIdentifier)akidext.get(
- AuthorityKeyIdentifierExtension.KEY_ID);
- if (akid != null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- certSel.setSubjectKeyIdentifier(derout.toByteArray());
+ byte[] kid = akidext.getEncodedKeyIdentifier();
+ if (kid != null) {
+ certSel.setSubjectKeyIdentifier(kid);
}
SerialNumber asn = (SerialNumber)akidext.get(
diff --git a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
index 7f30d3b..3c86d62 100644
--- a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
+++ b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
@@ -46,9 +46,10 @@
import sun.security.util.Debug;
import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension;
+import sun.security.x509.AuthorityKeyIdentifierExtension;
import static sun.security.x509.PKIXExtensions.*;
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
@@ -69,7 +70,6 @@
private AdaptableX509CertSelector caSelector;
private X509CertSelector caTargetSelector;
TrustAnchor trustAnchor;
- private Comparator<X509Certificate> comparator;
private boolean searchAllCertStores = true;
/**
@@ -93,7 +93,6 @@
trustedSubjectDNs.add(anchor.getCA());
}
}
- comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores;
}
@@ -122,6 +121,8 @@
* As each cert is added, it is sorted based on the PKIXCertComparator
* algorithm.
*/
+ Comparator<X509Certificate> comparator =
+ new PKIXCertComparator(trustedSubjectDNs, currState.cert);
Set<X509Certificate> certs = new TreeSet<>(comparator);
/*
@@ -265,14 +266,6 @@
(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
*/
caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
@@ -404,41 +397,68 @@
*
* 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
*
- * 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)
* 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]
*
- * 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)
* a) Issuer: ou=C,o=B,c=A [links=1]
* 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)
* a) Issuer: ou=G,ou=C,o=B,c=A [links=2]
* 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)
* a) Issuer: ou=K,o=J,c=A
* Subject: ou=L,ou=K,o=J,c=A
* b) Issuer: o=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> {
- final static String METHOD_NME = "PKIXCertComparator.compare()";
+ static final String METHOD_NME = "PKIXCertComparator.compare()";
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.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 @@
// if certs are the same, 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 cIssuer2 = oCert2.getIssuerX500Principal();
X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1);
diff --git a/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java b/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java
index c9b31cd..256bdf2 100644
--- a/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java
+++ b/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java
@@ -413,12 +413,16 @@
"SHA1withECDSA", --p);
if (Security.getProvider("SunMSCAPI") == null) {
+ supports(HashAlgorithm.SHA224, SignatureAlgorithm.DSA,
+ "SHA224withDSA", --p);
supports(HashAlgorithm.SHA224, SignatureAlgorithm.RSA,
"SHA224withRSA", --p);
supports(HashAlgorithm.SHA224, SignatureAlgorithm.ECDSA,
"SHA224withECDSA", --p);
}
+ supports(HashAlgorithm.SHA256, SignatureAlgorithm.DSA,
+ "SHA256withDSA", --p);
supports(HashAlgorithm.SHA256, SignatureAlgorithm.RSA,
"SHA256withRSA", --p);
supports(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA,
diff --git a/src/share/classes/sun/security/tools/jarsigner/JarSignerParameters.java b/src/share/classes/sun/security/tools/jarsigner/JarSignerParameters.java
new file mode 100644
index 0000000..fe75f9d
--- /dev/null
+++ b/src/share/classes/sun/security/tools/jarsigner/JarSignerParameters.java
@@ -0,0 +1,152 @@
+/*
+ * 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. 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.
+ */
+
+package sun.security.tools.jarsigner;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.net.URI;
+import java.util.zip.*;
+
+import com.sun.jarsigner.ContentSignerParameters;
+
+class JarSignerParameters implements ContentSignerParameters {
+
+ private String[] args;
+ private URI tsa;
+ private X509Certificate tsaCertificate;
+ private byte[] signature;
+ private String signatureAlgorithm;
+ private X509Certificate[] signerCertificateChain;
+ private byte[] content;
+ private ZipFile source;
+ private String tSAPolicyID;
+ private String tSADigestAlg;
+
+ /**
+ * Create a new object.
+ */
+ JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
+ String tSAPolicyID, String tSADigestAlg,
+ byte[] signature, String signatureAlgorithm,
+ X509Certificate[] signerCertificateChain, byte[] content,
+ ZipFile source) {
+
+ if (signature == null || signatureAlgorithm == null ||
+ signerCertificateChain == null || tSADigestAlg == null) {
+ throw new NullPointerException();
+ }
+ this.args = args;
+ this.tsa = tsa;
+ this.tsaCertificate = tsaCertificate;
+ this.tSAPolicyID = tSAPolicyID;
+ this.tSADigestAlg = tSADigestAlg;
+ this.signature = signature;
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.signerCertificateChain = signerCertificateChain;
+ this.content = content;
+ this.source = source;
+ }
+
+ /**
+ * Retrieves the command-line arguments.
+ *
+ * @return The command-line arguments. May be null.
+ */
+ public String[] getCommandLine() {
+ return args;
+ }
+
+ /**
+ * Retrieves the identifier for a Timestamping Authority (TSA).
+ *
+ * @return The TSA identifier. May be null.
+ */
+ public URI getTimestampingAuthority() {
+ return tsa;
+ }
+
+ /**
+ * Retrieves the certificate for a Timestamping Authority (TSA).
+ *
+ * @return The TSA certificate. May be null.
+ */
+ public X509Certificate getTimestampingAuthorityCertificate() {
+ return tsaCertificate;
+ }
+
+ public String getTSAPolicyID() {
+ return tSAPolicyID;
+ }
+
+ public String getTSADigestAlg() {
+ return tSADigestAlg;
+ }
+
+ /**
+ * Retrieves the signature.
+ *
+ * @return The non-null signature bytes.
+ */
+ public byte[] getSignature() {
+ return signature;
+ }
+
+ /**
+ * Retrieves the name of the signature algorithm.
+ *
+ * @return The non-null string name of the signature algorithm.
+ */
+ public String getSignatureAlgorithm() {
+ return signatureAlgorithm;
+ }
+
+ /**
+ * Retrieves the signer's X.509 certificate chain.
+ *
+ * @return The non-null array of X.509 public-key certificates.
+ */
+ public X509Certificate[] getSignerCertificateChain() {
+ return signerCertificateChain;
+ }
+
+ /**
+ * Retrieves the content that was signed.
+ *
+ * @return The content bytes. May be null.
+ */
+ public byte[] getContent() {
+ return content;
+ }
+
+ /**
+ * Retrieves the original source ZIP file before it was signed.
+ *
+ * @return The original ZIP file. May be null.
+ */
+ public ZipFile getSource() {
+ return source;
+ }
+}
diff --git a/src/share/classes/sun/security/tools/jarsigner/Main.java b/src/share/classes/sun/security/tools/jarsigner/Main.java
index 35f33c8..37b04c9 100644
--- a/src/share/classes/sun/security/tools/jarsigner/Main.java
+++ b/src/share/classes/sun/security/tools/jarsigner/Main.java
@@ -139,6 +139,7 @@
String tsaAlias; // alias for the Timestamping Authority's certificate
String altCertChain; // file to read alternative cert chain from
String tSAPolicyID;
+ String tSADigestAlg = "SHA-256";
boolean verify = false; // verify the jar
String verbose = null; // verbose output when signing/verifying
boolean showcerts = false; // show certs when verifying
@@ -342,6 +343,9 @@
} else if (collator.compare(flags, "-tsapolicyid") ==0) {
if (++n == args.length) usageNoArg();
tSAPolicyID = args[n];
+ } else if (collator.compare(flags, "-tsadigestalg") ==0) {
+ if (++n == args.length) usageNoArg();
+ tSADigestAlg = args[n];
} else if (collator.compare(flags, "-debug") ==0) {
debug = true;
} else if (collator.compare(flags, "-keypass") ==0) {
@@ -536,6 +540,9 @@
(".tsapolicyid.tsapolicyid.for.Timestamping.Authority"));
System.out.println();
System.out.println(rb.getString
+ (".tsadigestalg.algorithm.of.digest.data.in.timestamping.request"));
+ System.out.println();
+ System.out.println(rb.getString
(".altsigner.class.class.name.of.an.alternative.signing.mechanism"));
System.out.println();
System.out.println(rb.getString
@@ -1270,8 +1277,8 @@
try {
block =
sf.generateBlock(privateKey, sigalg, certChain,
- externalSF, tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args,
- zipFile);
+ externalSF, tsaUrl, tsaCert, tSAPolicyID, tSADigestAlg,
+ signingMechanism, args, zipFile);
} catch (SocketTimeoutException e) {
// Provide a helpful message when TSA is beyond a firewall
error(rb.getString("unable.to.sign.jar.") +
@@ -2268,13 +2275,14 @@
boolean externalSF, String tsaUrl,
X509Certificate tsaCert,
String tSAPolicyID,
+ String tSADigestAlg,
ContentSigner signingMechanism,
String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException
{
return new Block(this, privateKey, sigalg, certChain, externalSF,
- tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args, zipFile);
+ tsaUrl, tsaCert, tSAPolicyID, tSADigestAlg, signingMechanism, args, zipFile);
}
@@ -2288,8 +2296,8 @@
*/
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg,
X509Certificate[] certChain, boolean externalSF, String tsaUrl,
- X509Certificate tsaCert, String tSAPolicyID, ContentSigner signingMechanism,
- String[] args, ZipFile zipFile)
+ X509Certificate tsaCert, String tSAPolicyID, String tSADigestAlg,
+ ContentSigner signingMechanism, String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException {
@@ -2371,7 +2379,8 @@
// Assemble parameters for the signing mechanism
ContentSignerParameters params =
- new JarSignerParameters(args, tsaUri, tsaCert, tSAPolicyID, signature,
+ new JarSignerParameters(args, tsaUri, tsaCert, tSAPolicyID,
+ tSADigestAlg, signature,
signatureAlgorithm, certChain, content, zipFile);
// Generate the signature block
@@ -2400,120 +2409,3 @@
}
}
}
-
-
-/*
- * This object encapsulates the parameters used to perform content signing.
- */
-class JarSignerParameters implements ContentSignerParameters {
-
- private String[] args;
- private URI tsa;
- private X509Certificate tsaCertificate;
- private byte[] signature;
- private String signatureAlgorithm;
- private X509Certificate[] signerCertificateChain;
- private byte[] content;
- private ZipFile source;
- private String tSAPolicyID;
-
- /**
- * Create a new object.
- */
- JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
- String tSAPolicyID,
- byte[] signature, String signatureAlgorithm,
- X509Certificate[] signerCertificateChain, byte[] content,
- ZipFile source) {
-
- if (signature == null || signatureAlgorithm == null ||
- signerCertificateChain == null) {
- throw new NullPointerException();
- }
- this.args = args;
- this.tsa = tsa;
- this.tsaCertificate = tsaCertificate;
- this.tSAPolicyID = tSAPolicyID;
- this.signature = signature;
- this.signatureAlgorithm = signatureAlgorithm;
- this.signerCertificateChain = signerCertificateChain;
- this.content = content;
- this.source = source;
- }
-
- /**
- * Retrieves the command-line arguments.
- *
- * @return The command-line arguments. May be null.
- */
- public String[] getCommandLine() {
- return args;
- }
-
- /**
- * Retrieves the identifier for a Timestamping Authority (TSA).
- *
- * @return The TSA identifier. May be null.
- */
- public URI getTimestampingAuthority() {
- return tsa;
- }
-
- /**
- * Retrieves the certificate for a Timestamping Authority (TSA).
- *
- * @return The TSA certificate. May be null.
- */
- public X509Certificate getTimestampingAuthorityCertificate() {
- return tsaCertificate;
- }
-
- public String getTSAPolicyID() {
- return tSAPolicyID;
- }
-
- /**
- * Retrieves the signature.
- *
- * @return The non-null signature bytes.
- */
- public byte[] getSignature() {
- return signature;
- }
-
- /**
- * Retrieves the name of the signature algorithm.
- *
- * @return The non-null string name of the signature algorithm.
- */
- public String getSignatureAlgorithm() {
- return signatureAlgorithm;
- }
-
- /**
- * Retrieves the signer's X.509 certificate chain.
- *
- * @return The non-null array of X.509 public-key certificates.
- */
- public X509Certificate[] getSignerCertificateChain() {
- return signerCertificateChain;
- }
-
- /**
- * Retrieves the content that was signed.
- *
- * @return The content bytes. May be null.
- */
- public byte[] getContent() {
- return content;
- }
-
- /**
- * Retrieves the original source ZIP file before it was signed.
- *
- * @return The original ZIP file. May be null.
- */
- public ZipFile getSource() {
- return source;
- }
-}
diff --git a/src/share/classes/sun/security/tools/jarsigner/Resources.java b/src/share/classes/sun/security/tools/jarsigner/Resources.java
index 77b0628..db35b1e 100644
--- a/src/share/classes/sun/security/tools/jarsigner/Resources.java
+++ b/src/share/classes/sun/security/tools/jarsigner/Resources.java
@@ -88,6 +88,8 @@
"[-tsacert <alias>] public key certificate for Timestamping Authority"},
{".tsapolicyid.tsapolicyid.for.Timestamping.Authority",
"[-tsapolicyid <oid>] TSAPolicyID for Timestamping Authority"},
+ {".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
+ "[-tsadigestalg <algorithm>] algorithm of digest data in timestamping request"},
{".altsigner.class.class.name.of.an.alternative.signing.mechanism",
"[-altsigner <class>] class name of an alternative signing mechanism"},
{".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism",
diff --git a/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java b/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
index 3e50419..c149f8b 100644
--- a/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
+++ b/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
@@ -132,9 +132,14 @@
}
}
}
+ String tSADigestAlg = "SHA-256";
+ if (params instanceof JarSignerParameters) {
+ tSADigestAlg = ((JarSignerParameters)params).getTSADigestAlg();
+ }
return PKCS7.generateSignedData(signature, signerChain, content,
params.getSignatureAlgorithm(), tsaURI,
- params.getTSAPolicyID());
+ params.getTSAPolicyID(),
+ tSADigestAlg);
}
/**
diff --git a/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java b/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
index afd7c99..9e76a3a 100644
--- a/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
+++ b/src/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
@@ -307,4 +307,16 @@
public String getName() {
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;
+ }
}
diff --git a/src/share/classes/sun/util/resources/TimeZoneNames.java b/src/share/classes/sun/util/resources/TimeZoneNames.java
index 9befaec..5722da9 100644
--- a/src/share/classes/sun/util/resources/TimeZoneNames.java
+++ b/src/share/classes/sun/util/resources/TimeZoneNames.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -310,6 +310,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1032,7 +1033,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java b/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
index d32357c..8fa22f9 100644
--- a/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
+++ b/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java b/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
index 40ad3fa..c20c02e 100644
--- a/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
+++ b/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java b/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
index 010d56b..3d81200 100644
--- a/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
+++ b/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java b/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
index e2e2e7b..33350c4 100644
--- a/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
+++ b/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java b/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
index d7a33f2..57a3fb7 100644
--- a/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
+++ b/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java b/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
index b84d4df..d17154b 100644
--- a/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
+++ b/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java b/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
index 5601d95..32747fe 100644
--- a/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
+++ b/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java b/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
index bdae906..8705bfe 100644
--- a/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
+++ b/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
index 534261f..d5e5215 100644
--- a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
+++ b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1033,7 +1034,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
index ca5558b..4dc212b 100644
--- a/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
+++ b/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -311,6 +311,7 @@
{"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT},
{"CTT", CTT},
+ {"UTC", UTC},
/* Don't change the order of the above zones
* to keep compatibility with the previous version.
*/
@@ -1035,7 +1036,6 @@
{"US/Pacific", PST},
{"US/Pacific-New", PST},
{"US/Samoa", SAMOA},
- {"UTC", UTC},
{"VST", ICT},
{"W-SU", MSK},
{"WET", WET},
diff --git a/src/share/lib/management/management.properties b/src/share/lib/management/management.properties
index db08b78..70efa2e 100644
--- a/src/share/lib/management/management.properties
+++ b/src/share/lib/management/management.properties
@@ -316,3 +316,16 @@
# For a non-default password file location use the following line
# com.sun.management.jmxremote.access.file=filepath
+#
+
+# ################ Management agent listen interface #########################
+#
+# com.sun.management.jmxremote.host=<host-or-interface-name>
+# Specifies the local interface on which the JMX RMI agent will bind.
+# This is useful when running on machines which have several
+# interfaces defined. It makes it possible to listen to a specific
+# subnet accessible through that interface.
+#
+# The format of the value for that property is any string accepted
+# by java.net.InetAddress.getByName(String).
+#
diff --git a/src/solaris/classes/java/lang/UNIXProcess.java b/src/solaris/classes/java/lang/UNIXProcess.java
index cc3b596..1793a8f 100644
--- a/src/solaris/classes/java/lang/UNIXProcess.java
+++ b/src/solaris/classes/java/lang/UNIXProcess.java
@@ -225,9 +225,8 @@
ThreadGroup systemThreadGroup = tg;
ThreadFactory threadFactory = grimReaper -> {
- // Our thread stack requirement is quite modest.
- Thread t = new Thread(systemThreadGroup, grimReaper,
- "process reaper", 32768);
+ long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize") ? 0 : 32768;
+ Thread t = new Thread(systemThreadGroup, grimReaper,"process reaper", stackSize);
t.setDaemon(true);
// A small attempt (probably futile) to avoid priority inversion
t.setPriority(Thread.MAX_PRIORITY);
diff --git a/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/src/solaris/classes/sun/awt/X11/XBaseWindow.java
index 25e8852..297e2dd 100644
--- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java
+++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java
@@ -79,7 +79,6 @@
static enum InitialiseState {
INITIALISING,
- NOT_INITIALISED,
INITIALISED,
FAILED_INITIALISATION
};
@@ -122,7 +121,6 @@
*/
void instantPreInit(XCreateWindowParams params) {
state_lock = new StateLock();
- initialising = InitialiseState.NOT_INITIALISED;
}
/**
@@ -131,7 +129,6 @@
*/
void preInit(XCreateWindowParams params) {
state_lock = new StateLock();
- initialising = InitialiseState.NOT_INITIALISED;
embedded = Boolean.TRUE.equals(params.get(EMBEDDED));
visible = Boolean.TRUE.equals(params.get(VISIBLE));
@@ -223,7 +220,6 @@
return false;
}
return true;
- case NOT_INITIALISED:
case FAILED_INITIALISATION:
return false;
default:
@@ -673,7 +669,7 @@
XToolkit.awtLock();
try {
XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);
- xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1]);
+ xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1] + '\0');
} finally {
XToolkit.awtUnlock();
}
diff --git a/src/solaris/native/java/net/net_util_md.c b/src/solaris/native/java/net/net_util_md.c
index 693b4b0..c31d294 100644
--- a/src/solaris/native/java/net/net_util_md.c
+++ b/src/solaris/native/java/net/net_util_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -68,13 +68,6 @@
#include "java_net_SocketOptions.h"
-/* needed from libsocket on Solaris 8 */
-
-getaddrinfo_f getaddrinfo_ptr = NULL;
-freeaddrinfo_f freeaddrinfo_ptr = NULL;
-gai_strerror_f gai_strerror_ptr = NULL;
-getnameinfo_f getnameinfo_ptr = NULL;
-
/*
* EXCLBIND socket options only on Solaris
*/
@@ -434,8 +427,7 @@
int size;
char *buf;
const char *format = "%s: %s";
- const char *error_string =
- (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
+ const char *error_string = gai_strerror(gai_error);
if (error_string == NULL)
error_string = "unknown error";
diff --git a/src/solaris/native/java/net/net_util_md.h b/src/solaris/native/java/net/net_util_md.h
index 68c10d6..58be690 100644
--- a/src/solaris/native/java/net/net_util_md.h
+++ b/src/solaris/native/java/net/net_util_md.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -134,22 +134,6 @@
#endif /* SO_FLOW_SLA */
#endif /* __solaris__ */
-/* needed from libsocket on Solaris 8 */
-
-typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res);
-
-typedef void (*freeaddrinfo_f)(struct addrinfo *);
-
-typedef const char * (*gai_strerror_f)(int ecode);
-
-typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
- char *, size_t, char *, size_t, int);
-
-extern getaddrinfo_f getaddrinfo_ptr;
-extern freeaddrinfo_f freeaddrinfo_ptr;
-extern getnameinfo_f getnameinfo_ptr;
-
void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
const char* hostname,
int gai_error);
diff --git a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
index e21429e..3b176da 100644
--- a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
+++ b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1501,7 +1501,9 @@
s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) {
// Indicate whether this component manages its own
// children
- AccessibleRole role = ac.getAccessibleRole();
+ AccessibleRole role = InvocationUtils.invokeAndWait(() -> {
+ return ac.getAccessibleRole();
+ }, ac);
if (role == AccessibleRole.LIST ||
role == AccessibleRole.TABLE ||
role == AccessibleRole.TREE) {
@@ -1759,7 +1761,9 @@
*/
private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) {
if (ac != null) {
- AccessibleComponent acmp = ac.getAccessibleComponent();
+ AccessibleComponent acmp = InvocationUtils.invokeAndWait(() -> {
+ return ac.getAccessibleComponent();
+ }, ac);
if (acmp != null) {
debugString("Returning AccessibleComponent Context");
return acmp;
diff --git a/src/windows/native/java/net/NetworkInterface_winXP.c b/src/windows/native/java/net/NetworkInterface_winXP.c
index 7e3e79d..4042d16 100644
--- a/src/windows/native/java/net/NetworkInterface_winXP.c
+++ b/src/windows/native/java/net/NetworkInterface_winXP.c
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include <winsock2.h> /* needed for htonl */
#include <iprtrmib.h>
#include <assert.h>
+#include <limits.h>
#include "java_net_NetworkInterface.h"
#include "jni_util.h"
@@ -70,7 +71,7 @@
#endif
-static int bufsize = 1024;
+static int bufsize = 4096;
/*
* return an array of IP_ADAPTER_ADDRESSES containing one element
@@ -94,7 +95,12 @@
ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
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) {
free(adapterInfo);
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
@@ -103,7 +109,6 @@
adapterInfo = newAdapterInfo;
- bufsize = len;
ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
}
@@ -137,7 +142,12 @@
flags |= GAA_FLAG_INCLUDE_PREFIX;
val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
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) {
free(adapterInfo);
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
@@ -146,7 +156,6 @@
adapterInfo = newAdapterInfo;
- bufsize = len;
val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
}
diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index 25ada7c..c726b04 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -273,3 +273,13 @@
java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all
############################################################################
+
+# svc_tools
+
+# 8031482
+sun/tools/jcmd/TestJcmdSanity.java windows-all
+
+# 6456333
+sun/tools/jps/TestJpsJarRelative.java generic-all
+
+############################################################################
diff --git a/test/TEST.groups b/test/TEST.groups
index a17b16a..886566f 100644
--- a/test/TEST.groups
+++ b/test/TEST.groups
@@ -352,7 +352,8 @@
javax/xml/bind/jxc \
javax/xml/ws/8033113 \
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
#
diff --git a/test/com/sun/crypto/provider/CICO/CICOChainingTest.java b/test/com/sun/crypto/provider/CICO/CICOChainingTest.java
new file mode 100644
index 0000000..5e0d3c5
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/CICOChainingTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java b/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java
new file mode 100644
index 0000000..3164294
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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);
+ }
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/CICOSkipTest.java b/test/com/sun/crypto/provider/CICO/CICOSkipTest.java
new file mode 100644
index 0000000..0641845
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/CICOSkipTest.java
@@ -0,0 +1,270 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java
new file mode 100644
index 0000000..e6e5c2f
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/AESPBEWrapper.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java
new file mode 100644
index 0000000..d155a14
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/AbstractPBEWrapper.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java
new file mode 100644
index 0000000..0e4b376
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICOPBEFuncTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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);
+ }
+ }
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java
new file mode 100644
index 0000000..da149f0
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_RW_Test.java
@@ -0,0 +1,113 @@
+/*
+ * 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();
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java
new file mode 100644
index 0000000..62ebd83
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_SKIP_Test.java
@@ -0,0 +1,168 @@
+/*
+ * 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);
+ }
+ }
+
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java
new file mode 100644
index 0000000..9879bf4
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CICO_PBE_Test.java
@@ -0,0 +1,99 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java b/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java
new file mode 100644
index 0000000..73952eb
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/CipherNCFuncTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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");
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java
new file mode 100644
index 0000000..f68fd85
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/DefaultPBEWrapper.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java b/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java
new file mode 100644
index 0000000..98ef4f2
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/PBEAlgorithm.java
@@ -0,0 +1,86 @@
+/*
+ * 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();
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java b/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java
new file mode 100644
index 0000000..fb2d0ac
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/CICO/ReadModel.java b/test/com/sun/crypto/provider/CICO/ReadModel.java
new file mode 100644
index 0000000..d1cfb71
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/ReadModel.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+}
diff --git a/test/com/sun/crypto/provider/CICO/TestUtilities.java b/test/com/sun/crypto/provider/CICO/TestUtilities.java
new file mode 100644
index 0000000..a1160f7
--- /dev/null
+++ b/test/com/sun/crypto/provider/CICO/TestUtilities.java
@@ -0,0 +1,90 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java b/test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
new file mode 100644
index 0000000..d96cb00
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
@@ -0,0 +1,753 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java b/test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java
new file mode 100644
index 0000000..7250c4d
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/Helper.java b/test/com/sun/crypto/provider/Cipher/AEAD/Helper.java
new file mode 100644
index 0000000..dad216b
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/Helper.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java b/test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
new file mode 100644
index 0000000..21f1dee
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
@@ -0,0 +1,87 @@
+/*
+ * 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");
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java b/test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
new file mode 100644
index 0000000..f6bd380
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
@@ -0,0 +1,317 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java b/test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
new file mode 100644
index 0000000..30afb8e
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
@@ -0,0 +1,423 @@
+/*
+ * 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;
+ }
+
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java b/test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java
new file mode 100644
index 0000000..6f5e820
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java b/test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
new file mode 100644
index 0000000..157a8bb
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
@@ -0,0 +1,174 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java b/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java
index 61efd62..ffa0a5b 100644
--- a/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java
+++ b/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java
@@ -27,39 +27,52 @@
public class TestUtility {
- private static final String digits = "0123456789abcdef";
+ private static final String DIGITS = "0123456789abcdef";
- public TestUtility() {
+ private TestUtility() {
}
public static String hexDump(byte[] bytes) {
- StringBuffer buf = new StringBuffer (bytes.length * 2);
- int i;
+ StringBuilder buf = new StringBuilder(bytes.length * 2);
+ int i;
- buf.append (" "); // four spaces
+ buf.append(" "); // four spaces
for (i = 0; i < bytes.length; i++) {
- buf.append (digits.charAt ((bytes[i] >> 4) & 0x0f));
- buf.append (digits.charAt (bytes[i] & 0x0f));
- if (((i + 1) % 32) == 0) {
- if ((i + 1) != bytes.length)
- buf.append ("\n "); // line after four words
- } else if (((i + 1) % 4) == 0)
- buf.append (' '); // space between words
+ buf.append(DIGITS.charAt(bytes[i] >> 4 & 0x0f));
+ buf.append(DIGITS.charAt(bytes[i] & 0x0f));
+ if ((i + 1) % 32 == 0) {
+ if (i + 1 != bytes.length) {
+ buf.append("\n "); // line after four words
+ }
+ } else if ((i + 1) % 4 == 0) {
+ buf.append(' '); // space between words
+ }
}
- return buf.toString ();
+ return buf.toString();
}
+ public static String hexDump(byte[] bytes, int index) {
+ StringBuilder buf = new StringBuilder(bytes.length * 2);
+ int i;
+
+ buf.append(" "); // four spaces
+ buf.append(DIGITS.charAt(bytes[index] >> 4 & 0x0f));
+ buf.append(DIGITS.charAt(bytes[index] & 0x0f));
+ return buf.toString();
+ }
public static boolean equalsBlock(byte[] b1, byte[] b2) {
- if (b1.length != b2.length)
+ if (b1.length != b2.length) {
return false;
+ }
- for (int i=0; i<b1.length; i++) {
- if (b1[i] != b2[i])
+ for (int i = 0; i < b1.length; i++) {
+ if (b1[i] != b2[i]) {
return false;
+ }
}
return true;
@@ -67,9 +80,10 @@
public static boolean equalsBlock(byte[] b1, byte[] b2, int len) {
- for (int i=0; i<len; i++) {
- if (b1[i] != b2[i])
+ for (int i = 0; i < len; i++) {
+ if (b1[i] != b2[i]) {
return false;
+ }
}
return true;
diff --git a/test/com/sun/crypto/provider/Cipher/DES/TextPKCS5PaddingTest.java b/test/com/sun/crypto/provider/Cipher/DES/TextPKCS5PaddingTest.java
new file mode 100644
index 0000000..0afb280
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/DES/TextPKCS5PaddingTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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");
+ }
+
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/JCE/Bugs/4686632/Empty.java b/test/com/sun/crypto/provider/Cipher/JCE/Bugs/4686632/Empty.java
new file mode 100644
index 0000000..4a774ae
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/JCE/Bugs/4686632/Empty.java
@@ -0,0 +1,59 @@
+/*
+ * 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");
+ }
+
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/KeyWrap/TestCipherKeyWrapperTest.java b/test/com/sun/crypto/provider/Cipher/KeyWrap/TestCipherKeyWrapperTest.java
new file mode 100644
index 0000000..363d21d
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/KeyWrap/TestCipherKeyWrapperTest.java
@@ -0,0 +1,316 @@
+/*
+ * 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 java.lang.System.out;
+
+import java.lang.Integer;
+import java.lang.String;
+import java.lang.System;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/*
+ * @test
+ * @bug 8048599
+ * @summary Tests for key wrap and unwrap operations
+ */
+
+public class TestCipherKeyWrapperTest {
+ private static final String SUN_JCE = "SunJCE";
+ // Blowfish Variable key length: 32 bits to 448 bits
+ private static final int BLOWFISH_MIN_KEYSIZE = 32;
+ private static final int BLOWFISH_MAX_KEYSIZE = 448;
+ private static final int LINIMITED_KEYSIZE = 128;
+ private static final String NOPADDING = "NoPaDDing";
+ private static final String[] PBE_ALGORITHM_AR = { "pbeWithMD5ANDdes",
+ "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndTripleDES",
+ "PBEWithMD5AndTripleDES/CBC/PKCS5Padding", "PBEwithSHA1AndDESede",
+ "PBEwithSHA1AndDESede/CBC/PKCS5Padding", "PBEwithSHA1AndRC2_40",
+ "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", "PBEWithSHA1AndRC2_128",
+ "PBEWithSHA1andRC2_128/CBC/PKCS5Padding", "PBEWithSHA1AndRC4_40",
+ "PBEWithsha1AndRC4_40/ECB/NoPadding", "PBEWithSHA1AndRC4_128",
+ "pbeWithSHA1AndRC4_128/ECB/NoPadding", "PBEWithHmacSHA1AndAES_128",
+ "PBEWithHmacSHA224AndAES_128", "PBEWithHmacSHA256AndAES_128",
+ "PBEWithHmacSHA384AndAES_128", "PBEWithHmacSHA512AndAES_128",
+ "PBEWithHmacSHA1AndAES_256", "PBEWithHmacSHA224AndAES_256",
+ "PBEWithHmacSHA256AndAES_256", "PBEWithHmacSHA384AndAES_256",
+ "PBEWithHmacSHA512AndAES_256" };
+ private static final String[] MODEL_AR = { "ECb", "pCbC", "cbC", "cFB",
+ "cFB24", "cFB40", "OfB48", "OFB64" };
+ private static final String[] PADDING_AR = { NOPADDING, "PKCS5Padding" };
+
+ private enum AlgorithmWrapper {
+ AESWrap("AES", "AESWrap", -1),
+ AESWrap_128("AES", "AESWrap_128", 128),
+ AESWrap_192("AES", "AESWrap_192", 192),
+ AESWrap_256("AES", "AESWrap_256", 256),
+ DESedeWrap("desede", "DESedeWrap", -1),
+ NegtiveWrap("AES", "DESedeWrap", -1);
+
+ private final String algorithm;
+ private final String wrapper;
+ private final int keySize;
+
+ private AlgorithmWrapper(String algorithm, String wrapper, int kSize) {
+ this.algorithm = algorithm;
+ this.wrapper = wrapper;
+ this.keySize = kSize;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public String getWrapper() {
+ return wrapper;
+ }
+
+ public int getKeySize() {
+ return keySize;
+ }
+
+ };
+
+ public static void main(String[] args) throws Exception {
+
+ TestCipherKeyWrapperTest test = new TestCipherKeyWrapperTest();
+ // AESWrap and DESedeWrap test
+ for (AlgorithmWrapper algoWrapper : AlgorithmWrapper.values()) {
+ String algo = algoWrapper.getAlgorithm();
+ String wrapper = algoWrapper.getWrapper();
+ try {
+ int keySize = algoWrapper.getKeySize();
+ // only run the tests on longer key lengths if unlimited
+ // version of JCE jurisdiction policy files are installed
+ if (!(Cipher.getMaxAllowedKeyLength(algo) == Integer.MAX_VALUE)
+ && keySize > LINIMITED_KEYSIZE) {
+ out.println(algo + " will not run if unlimited version of"
+ + " JCE jurisdiction policy files are installed");
+ continue;
+ }
+ test.wrapperAesDESedeKeyTest(algo, wrapper, keySize);
+ if (algoWrapper == AlgorithmWrapper.NegtiveWrap) {
+ throw new RuntimeException("Expected not throw when algo"
+ + " and wrapAlgo are not match:" + algo);
+ }
+ } catch (InvalidKeyException e) {
+ if (algoWrapper == AlgorithmWrapper.NegtiveWrap) {
+ out.println("Expepted exception when algo"
+ + " and wrapAlgo are not match:" + algo);
+ } else {
+ throw e;
+ }
+ }
+ }
+ test.wrapperBlowfishKeyTest();
+ // PBE and public wrapper test.
+ String[] publicPrivateAlgos = new String[] { "DiffieHellman", "DSA",
+ "RSA" };
+ Provider provider = Security.getProvider(SUN_JCE);
+ if (provider == null) {
+ throw new RuntimeException("SUN_JCE provider not exist");
+ }
+
+ test.wrapperPBEKeyTest(provider);
+ // Public and private key wrap test
+ test.wrapperPublicPriviteKeyTest(provider, publicPrivateAlgos);
+ }
+
+ private void wrapperAesDESedeKeyTest(String algo, String wrapAlgo,
+ int keySize) throws InvalidKeyException, NoSuchAlgorithmException,
+ NoSuchPaddingException, IllegalBlockSizeException,
+ InvalidAlgorithmParameterException {
+ // Initialization
+ KeyGenerator kg = KeyGenerator.getInstance(algo);
+ if (keySize != -1) {
+ kg.init(keySize);
+ }
+ SecretKey key = kg.generateKey();
+ wrapTest(algo, wrapAlgo, key, key, Cipher.SECRET_KEY, false);
+ }
+
+ private void wrapperBlowfishKeyTest() throws InvalidKeyException,
+ NoSuchAlgorithmException, NoSuchPaddingException,
+ IllegalBlockSizeException, InvalidAlgorithmParameterException {
+ // how many kinds of padding mode
+ int padKinds;
+ // Keysize should be multiple of 8 bytes.
+ int KeyCutter = 8;
+ int kSize = BLOWFISH_MIN_KEYSIZE;
+ String algorithm = "Blowfish";
+ int maxAllowKeyLength = Cipher.getMaxAllowedKeyLength(algorithm);
+ boolean unLimitPolicy = maxAllowKeyLength == Integer.MAX_VALUE;
+ SecretKey key = null;
+ while (kSize <= BLOWFISH_MAX_KEYSIZE) {
+ for (String mode : MODEL_AR) {
+ // PKCS5padding is meaningful only for ECB, CBC, PCBC
+ if (mode.equalsIgnoreCase(MODEL_AR[0])
+ || mode.equalsIgnoreCase(MODEL_AR[1])
+ || mode.equalsIgnoreCase(MODEL_AR[2])) {
+ padKinds = PADDING_AR.length;
+ } else {
+ padKinds = 1;
+ }
+ // Initialization
+ KeyGenerator kg = KeyGenerator.getInstance(algorithm);
+ for (int k = 0; k < padKinds; k++) {
+ String transformation = algorithm + "/" + mode + "/"
+ + PADDING_AR[k];
+ if (NOPADDING.equals(PADDING_AR[k]) && kSize % 64 != 0) {
+ out.println(transformation
+ + " will not run if input length not multiple"
+ + " of 8 bytes when padding is " + NOPADDING);
+ continue;
+ }
+ kg.init(kSize);
+ key = kg.generateKey();
+ // only run the tests on longer key lengths if unlimited
+ // version of JCE jurisdiction policy files are installed
+ if (!unLimitPolicy && kSize > LINIMITED_KEYSIZE) {
+ out.println("keyStrength > 128 within " + algorithm
+ + " will not run under global policy");
+ } else {
+ wrapTest(transformation, transformation, key, key,
+ Cipher.SECRET_KEY, false);
+ }
+ }
+ }
+ if (kSize <= LINIMITED_KEYSIZE) {
+ KeyCutter = 8;
+ } else {
+ KeyCutter = 48;
+ }
+ kSize += KeyCutter;
+ }
+ }
+
+ private void wrapperPBEKeyTest(Provider p) throws InvalidKeySpecException,
+ InvalidKeyException, NoSuchPaddingException,
+ IllegalBlockSizeException, InvalidAlgorithmParameterException,
+ NoSuchAlgorithmException {
+ for (String alg : PBE_ALGORITHM_AR) {
+ String baseAlgo = alg.split("/")[0].toUpperCase();
+ // only run the tests on longer key lengths if unlimited version
+ // of JCE jurisdiction policy files are installed
+
+ if (Cipher.getMaxAllowedKeyLength(alg) < Integer.MAX_VALUE
+ && (baseAlgo.endsWith("TRIPLEDES") || alg
+ .endsWith("AES_256"))) {
+ out.println("keyStrength > 128 within " + alg
+ + " will not run under global policy");
+ continue;
+ }
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p);
+ SecretKey key = skf.generateSecret(new PBEKeySpec("Secret Lover"
+ .toCharArray()));
+ wrapTest(alg, alg, key, key, Cipher.SECRET_KEY, true);
+ }
+ }
+
+ private void wrapperPublicPriviteKeyTest(Provider p, String[] algorithms)
+ throws NoSuchAlgorithmException, InvalidKeyException,
+ NoSuchPaddingException, IllegalBlockSizeException,
+ InvalidAlgorithmParameterException {
+ for (String algo : algorithms) {
+ // Key pair generated
+ System.out.println("Generate key pair (algorithm: " + algo
+ + ", provider: " + p.getName() + ")");
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(algo);
+ kpg.initialize(512);
+ KeyPair kp = kpg.genKeyPair();
+ // key generated
+ String algoWrap = "DES";
+ KeyGenerator kg = KeyGenerator.getInstance(algoWrap, p);
+ Key key = kg.generateKey();
+ wrapTest(algo, algoWrap, key, kp.getPrivate(), Cipher.PRIVATE_KEY,
+ false);
+ wrapTest(algo, algoWrap, key, kp.getPublic(), Cipher.PUBLIC_KEY,
+ false);
+ }
+ }
+
+ private void wrapTest(String transformation, String wrapAlgo, Key initKey,
+ Key wrapKey, int keyType, boolean isPBE)
+ throws NoSuchAlgorithmException, NoSuchPaddingException,
+ InvalidKeyException, IllegalBlockSizeException,
+ InvalidAlgorithmParameterException {
+ String algo = transformation.split("/")[0];
+ boolean isAESBlowfish = algo.indexOf("AES") != -1
+ || algo.indexOf("Blowfish") != -1;
+ AlgorithmParameters aps = null;
+ AlgorithmParameterSpec pbeParams = null;
+ if (isPBE) {
+ byte[] salt = new byte[8];
+ int iterCnt = 1000;
+ new Random().nextBytes(salt);
+ pbeParams = new PBEParameterSpec(salt, iterCnt);
+ }
+ // Wrap & UnWrap operation
+ Cipher wrapCI = Cipher.getInstance(wrapAlgo);
+ if (isPBE && !isAESBlowfish) {
+ wrapCI.init(Cipher.WRAP_MODE, initKey, pbeParams);
+ } else if (isAESBlowfish) {
+ wrapCI.init(Cipher.WRAP_MODE, initKey);
+ aps = wrapCI.getParameters();
+ } else {
+ wrapCI.init(Cipher.WRAP_MODE, initKey);
+ }
+ out.println("keysize : " + wrapKey.getEncoded().length);
+ byte[] keyWrapper = wrapCI.wrap(wrapKey);
+ if (isPBE && !isAESBlowfish) {
+ wrapCI.init(Cipher.UNWRAP_MODE, initKey, pbeParams);
+ } else if (isAESBlowfish) {
+ wrapCI.init(Cipher.UNWRAP_MODE, initKey, aps);
+ } else {
+ wrapCI.init(Cipher.UNWRAP_MODE, initKey);
+ }
+ Key unwrappedKey = wrapCI.unwrap(keyWrapper, algo, keyType);
+ // Comparison
+ if (!Arrays.equals(wrapKey.getEncoded(), unwrappedKey.getEncoded())) {
+ throw new RuntimeException("Comparation failed testing "
+ + transformation + ":" + wrapAlgo + ":" + keyType);
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/AESPBEWrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/AESPBEWrapper.java
new file mode 100644
index 0000000..16dd69a
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/AESPBEWrapper.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012, 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.PrintStream;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Provider;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Wrapper class to test a given AES-based PBE algorithm.
+ *
+ * @author Alexander Fomin
+ */
+public class AESPBEWrapper extends PBEWrapper {
+
+ private AlgorithmParameters pbeParams;
+
+ /**
+ * Constructor. Instantiate Cipher using the given AES-based PBE algorithms.
+ *
+ * @param p security Provider
+ * @param algo PKDF2 algorithm
+ * @param passwd password phrase
+ * @param out print stream
+ * @throws Exception all exceptions are thrown
+ */
+ public AESPBEWrapper(Provider p, String algo, String passwd,
+ PrintStream out) throws Exception {
+ super(algo,
+ SecretKeyFactory.getInstance(algo, p).generateSecret(
+ new PBEKeySpec(passwd.toCharArray())),
+ Cipher.getInstance(algo, p), out);
+ }
+
+ /**
+ * Perform encryption/decryption operation (depending on the specified
+ * edMode) on the same byte buffer. Compare result with the result at an
+ * allocated buffer. If both results are equal - return true, otherwise
+ * return false.
+ *
+ * @param edMode specified mode
+ * @param inputText text to decrypt
+ * @param offset offset in the text
+ * @param len input length
+ * @return ture - test passed; false - test failed
+ */
+ @Override
+ public boolean execute(int edMode, byte[] inputText, int offset, int len) {
+ try {
+ // init Cipher
+ if (Cipher.ENCRYPT_MODE == edMode) {
+ ci.init(Cipher.ENCRYPT_MODE, this.key);
+ pbeParams = ci.getParameters();
+ } else {
+ ci.init(Cipher.DECRYPT_MODE, this.key, pbeParams);
+ }
+
+ // First, generate the cipherText at an allocated buffer
+ byte[] outputText = ci.doFinal(inputText, offset, len);
+
+ // Second, generate cipherText again at the same buffer of plainText
+ int myoff = offset / 2;
+ int off = ci.update(inputText, offset, len, inputText, myoff);
+ ci.doFinal(inputText, myoff + off);
+
+ if (this.algo.endsWith("AES_256")) {
+ out.print("Expected exception uncaught, "
+ + "keyStrength > 128 within " + this.algo);
+
+ return false;
+ }
+
+ // Compare to see whether the two results are the same or not
+ return equalsBlock(inputText, myoff, outputText, 0,
+ outputText.length);
+ } catch (Exception ex) {
+ if ((ex instanceof InvalidKeyException)
+ && this.algo.endsWith("AES_256")) {
+ out.println("Expected InvalidKeyException exception: "
+ + ex.getMessage());
+
+ return true;
+ }
+
+ out.println("Catch unexpected exception within " + algo);
+ ex.printStackTrace(out);
+
+ return false;
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBECipherWrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBECipherWrapper.java
new file mode 100644
index 0000000..e4a8509
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBECipherWrapper.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * @author Valerie PENG
+ * @author Yun Ke
+ * @author Alexander Fomin
+ * @author rhalade
+ */
+import java.security.spec.AlgorithmParameterSpec;
+
+import java.util.StringTokenizer;
+
+import java.security.InvalidKeyException;
+import java.security.Provider;
+
+import java.io.PrintStream;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+public class PBECipherWrapper extends PBEWrapper {
+
+ private final AlgorithmParameterSpec aps;
+
+ public PBECipherWrapper(
+ Provider p, String algo, String passwd, PrintStream out)
+ throws Exception {
+ super(algo,
+ SecretKeyFactory.getInstance(
+ new StringTokenizer(algo, "/").nextToken(), p).generateSecret(
+ new PBEKeySpec(passwd.toCharArray())),
+ Cipher.getInstance(algo, p), out);
+
+ int SALT_SIZE = 8;
+ aps = new PBEParameterSpec(generateSalt(SALT_SIZE), ITERATION_COUNT);
+ }
+
+ @Override
+ public boolean execute(int edMode, byte[] inputText, int offset,
+ int len) {
+ StringTokenizer st = new StringTokenizer(algo, "/");
+ String baseAlgo = st.nextToken().toUpperCase();
+
+ // Perform encryption or decryption depends on the specified edMode
+ try {
+ ci.init(edMode, key, aps);
+
+ // First, generate the cipherText at an allocated buffer
+ byte[] outputText = ci.doFinal(inputText, offset, len);
+
+ // Second, generate cipherText again at the same buffer of
+ // plainText
+ int myoff = offset / 2;
+ int off = ci.update(inputText, offset, len, inputText, myoff);
+
+ ci.doFinal(inputText, myoff + off);
+
+ if (baseAlgo.endsWith("TRIPLEDES")
+ || baseAlgo.endsWith("AES_256")) {
+ out.print("Expected exception uncaught,"
+ + "keyStrength > 128 within " + this.algo);
+
+ return false;
+ }
+
+ // Compare to see whether the two results are the same or not
+ boolean result = equalsBlock(inputText, myoff, outputText, 0,
+ outputText.length);
+
+ return result;
+ } catch (Exception ex) {
+ if ((ex instanceof InvalidKeyException)
+ && (baseAlgo.endsWith("TRIPLEDES")
+ || baseAlgo.endsWith("AES_256"))) {
+ out.println("Expected InvalidKeyException exception: "
+ + ex.getMessage());
+
+ return true;
+ }
+
+ out.println("Catch unexpected exception within " + algo);
+ ex.printStackTrace(out);
+
+ return false;
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java
new file mode 100644
index 0000000..4fe20f8
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBESameBuffer.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2012, 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 8041787
+ * @library .
+ * @build PBEWrapper PBEWrapperCreator PBKDF2Wrapper AESPBEWrapper PBECipherWrapper
+ * @summary Verify that same encrypt/decrypt buffer can be used for PBE ciphers
+ * @author Alexander Fomin
+ * @author rhalade
+ * @run main PBESameBuffer
+ */
+import java.io.PrintStream;
+import java.security.*;
+import java.util.Random;
+import javax.crypto.Cipher;
+
+public class PBESameBuffer {
+
+ private static final String[] pbeAlgorithms = {
+ "pbeWithMD5ANDdes", "PBEWithMD5AndDES/CBC/PKCS5Padding",
+ "pbeWithMD5ANDtripledes", "PBEWithMD5AndTRIPLEDES/CBC/PKCS5Padding",
+ "PBEwithSHA1AndDESede", "PBEwithSHA1AndDESede/CBC/PKCS5Padding",
+ "PBEwithSHA1AndRC2_40", "PBEwithSHA1AndRC2_40/CBC/PKCS5Padding",
+ "PBEWithSHA1AndRC2_128", "PBEWithSHA1AndRC2_128/CBC/PKCS5Padding",
+ "PBEWithSHA1AndRC4_40", "PBEWithSHA1AndRC4_40/ECB/NoPadding",
+ "PBEWithSHA1AndRC4_128", "PBEWithSHA1AndRC4_128/ECB/NoPadding",
+ "PBEWithHmacSHA1AndAES_128",
+ "PBEWithHmacSHA224AndAES_128",
+ "PBEWithHmacSHA256AndAES_128",
+ "PBEWithHmacSHA384AndAES_128",
+ "PBEWithHmacSHA512AndAES_128",
+ "PBEWithHmacSHA1AndAES_256",
+ "PBEWithHmacSHA224AndAES_256",
+ "PBEWithHmacSHA256AndAES_256",
+ "PBEWithHmacSHA384AndAES_256",
+ "PBEWithHmacSHA512AndAES_256",
+ "PBKDF2WithHmacSHA1",
+ "PBKDF2WithHmacSHA224",
+ "PBKDF2WithHmacSHA256",
+ "PBKDF2WithHmacSHA384",
+ "PBKDF2WithHmacSHA512"
+ };
+
+ private static final String PBEPASS = "Hush, it's supposed to be a secret!";
+
+ private static final int INPUT_LENGTH = 800;
+ private static final int[] OFFSETS = {0, 1, 2, 3};
+ private static final int NUM_PAD_BYTES = 8;
+ private static final int PBKDF2_ADD_PAD_BYTES = 8;
+
+ private static int OUTPUT_OFFSET;
+
+ public static void main(String[] args) {
+ if (!(new PBESameBuffer().test(args, System.out))) {
+ throw new RuntimeException("Some PBE algorithm tests failed");
+ }
+ }
+
+ public boolean test(String[] args, PrintStream out) {
+ boolean result = true;
+
+ Provider p = Security.getProvider("SunJCE");
+
+ for (int loop : OFFSETS) {
+ OUTPUT_OFFSET = loop;
+
+ // generate input data
+ byte[] inputText = new byte[INPUT_LENGTH + NUM_PAD_BYTES
+ + OUTPUT_OFFSET * 2 + PBKDF2_ADD_PAD_BYTES];
+ new Random().nextBytes(inputText);
+
+ for (String algorithm : pbeAlgorithms) {
+ out.println("=> Testing algorithm " + algorithm + " and offset "
+ + OUTPUT_OFFSET + ":");
+
+ try {
+ // Initialize Cipher and key for this algorithm
+ PBEWrapper pbeCi = PBEWrapperCreator.createWrapper(p,
+ algorithm,
+ PBEPASS,
+ out);
+
+ // Encrypt
+ if ((pbeCi != null) && (!pbeCi.execute(Cipher.ENCRYPT_MODE,
+ inputText,
+ OUTPUT_OFFSET * 2,
+ INPUT_LENGTH))) {
+ result = false;
+ }
+
+ // PBKDF2 required 16 byte padding
+ int padLength = getPadLength(algorithm);
+
+ // Decrypt
+ // Note: inputText is implicitly padded by the above encrypt
+ // operation so decrypt operation can safely proceed
+ if ((pbeCi != null) && (!pbeCi.execute(Cipher.DECRYPT_MODE,
+ inputText,
+ OUTPUT_OFFSET,
+ INPUT_LENGTH + padLength))) {
+ result = false;
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace(out);
+ result = false;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Get the padding length for the given algorithm
+ *
+ * @param theAlgName algorithm name
+ * @return padding length for the given algorithm
+ */
+ private int getPadLength(String theAlgName) {
+ if (theAlgName.toUpperCase().contains("PBKDF2")) {
+ return NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES;
+ }
+
+ if (theAlgName.toUpperCase().contains("AES")) {
+ return NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES;
+ }
+
+ return NUM_PAD_BYTES;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapper.java
new file mode 100644
index 0000000..9e76584
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapper.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 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.PrintStream;
+import java.util.Random;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
+/**
+ * PBEWrapper is the abstract class for all concrete PBE Cipher wrappers. A
+ * PBEWrapper object encapsulates the information and behavior needed to test if
+ * the multiple-part encryption/decryption is performing by expected way on the
+ * same byte buffer.
+ *
+ * @author Alexandr Fomin
+ * @author rhalade
+ */
+public abstract class PBEWrapper {
+
+ protected final static int ITERATION_COUNT = 1000;
+
+ protected final SecretKey key;
+ protected final Cipher ci;
+ protected final String algo;
+ protected final PrintStream out;
+
+ public PBEWrapper(String pAlgo, SecretKey pKey, Cipher pCi,
+ PrintStream pOut ){
+ this.algo = pAlgo;
+ this.key = pKey;
+ this.ci = pCi;
+ this.out = pOut;
+ }
+
+ /**
+ * Abstract method need to be implemented in the subclasses.
+ *
+ * @param edMode Cipher mode - encrypt/decrypt
+ * @param inputText byte buffer to process
+ * @param offset offset in byte the inputText
+ * @param len length of byte to process in inputText
+ * @return true if cipher operation is successful, false otherwise
+ */
+ public abstract boolean execute(int edMode, byte[] inputText, int offset,
+ int len);
+
+ /**
+ * An utility method to prepare "salt" for following Secret Key generation.
+ *
+ * @param numberOfBytes number of bytes in salt
+ * @return randomly generated byte array
+ */
+ protected static byte[] generateSalt(int numberOfBytes) {
+ byte[] salt = new byte[numberOfBytes];
+ new Random().nextBytes(salt);
+ return salt;
+ }
+
+ /**
+ * An utility method to check if two byte arrays are equal
+ *
+ * @param b1 first byte array
+ * @param off1 offset to compare from in b1
+ * @param b2 second byte array
+ * @param off2 offset to compare from in b2
+ * @param len length to compare
+ * @return true of arrays are equal, false otherwise
+ */
+ protected boolean equalsBlock(byte[] b1, int off1,
+ byte[] b2, int off2, int len) {
+ for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) {
+ if (b1[i] != b2[j]) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapperCreator.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapperCreator.java
new file mode 100644
index 0000000..85a19c9
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBEWrapperCreator.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, 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.security.Provider;
+import java.io.PrintStream;
+
+/**
+ * An utility class to create PBEWrapper object for the TestCipherSameBuffer
+ * test.
+ *
+ * @author Alexander Fomin
+ */
+public class PBEWrapperCreator {
+
+ private static final String PBKDF2 = "PBKDF2";
+ private static final String AES = "AES";
+
+ /**
+ * Create PBEWrapper for the TestCipherSameBuffer test using given
+ * parameters.
+ *
+ * @param p security provider
+ * @param algo algorithms to test
+ * @param passwd a password phrase
+ * @param out print stream object
+ * @return PBEWrapper in accordance to requested algorithm
+ * @throws Exception all exception are thrown.
+ */
+ public static PBEWrapper createWrapper(Provider p, String algo,
+ String passwd, PrintStream out) throws Exception {
+ if (algo.toUpperCase().contains(PBKDF2)) {
+ return new PBKDF2Wrapper(p, algo, passwd, out);
+ } else if (algo.toUpperCase().contains(AES)) {
+ return new AESPBEWrapper(p, algo, passwd, out);
+ } else {
+ return new PBECipherWrapper(p, algo, passwd, out);
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBKDF2Wrapper.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBKDF2Wrapper.java
new file mode 100644
index 0000000..6a2110d
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESameBuffer/PBKDF2Wrapper.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012, 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.PrintStream;
+import java.security.Provider;
+import javax.crypto.Cipher;
+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.
+ *
+ * @author Alexander Fomin
+ */
+public class PBKDF2Wrapper extends PBEWrapper {
+ private static final String CIPHER_TANSFORMATION = "AES/CBC/PKCS5Padding";
+ private static final int SALT_SIZE = 64;
+ private static final int PKDF2_DEFAULT_KEY_LEN = 128;
+
+ private static volatile byte[] iv;
+
+ /**
+ * PBKDF2Wrapper constructor. Instantiate Cipher using
+ * "AES/CBC/PKCS5Padding" transformation. Generate a secret key using given
+ * PKDF2 algorithms.
+ *
+ * @param p security Provider
+ * @param algo PKDF2 algorithm
+ * @param passwd password phrase
+ * @param out print stream
+ * @throws Exception all exceptions are thrown
+ */
+ public PBKDF2Wrapper(Provider p, String algo, String passwd,
+ PrintStream out) throws Exception {
+ super(algo,
+ SecretKeyFactory.getInstance(algo, p).generateSecret(
+ new PBEKeySpec(passwd.toCharArray(),
+ generateSalt(SALT_SIZE), ITERATION_COUNT, PKDF2_DEFAULT_KEY_LEN)),
+ Cipher.getInstance(CIPHER_TANSFORMATION, p), out);
+ }
+
+ /**
+ * Perform encryption/decryption operation (depending on the specified
+ * edMode) on the same byte buffer. Compare result with the result at an
+ * allocated buffer. If both results are equal - return true, otherwise
+ * return false.
+ *
+ * @param edMode specified mode
+ * @param inputText text to decrypt
+ * @param offset offset in the text
+ * @param len input length
+ * @return ture - test passed; false - test failed
+ */
+ @Override
+ public boolean execute(int edMode, byte[] inputText, int offset, int len) {
+ int needBytesForResult = -1;
+ String KEY_ALGORITHM = "AES";
+
+ try {
+ // init Cipher
+ if (Cipher.ENCRYPT_MODE == edMode) {
+ ci.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncoded(),
+ KEY_ALGORITHM));
+ iv = ci.getParameters().getParameterSpec(IvParameterSpec.class).
+ getIV();
+ } else {
+ ci.init(Cipher.DECRYPT_MODE,
+ new SecretKeySpec(key.getEncoded(), KEY_ALGORITHM),
+ new IvParameterSpec(iv));
+ }
+
+ // First, generate the cipherText at an allocated buffer
+ byte[] outputText = ci.doFinal(inputText, offset, len);
+
+ // Second, generate cipherText again at the same buffer of plainText
+ int myoff = offset / 2;
+ int off = ci.update(inputText, offset, len, inputText, myoff);
+ ci.doFinal(inputText, myoff + off);
+
+ // Compare to see whether the two results are the same or not
+ return equalsBlock(inputText, myoff, outputText, 0,
+ outputText.length);
+ } catch (Exception ex) {
+ out.println("Catch unexpected exception within " + algo
+ + " " + edMode + ": " + ex.getMessage()
+ + ". getOutputSize()" + "returned " + needBytesForResult);
+ ex.printStackTrace(out);
+
+ return false;
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBESealedObject.java b/test/com/sun/crypto/provider/Cipher/PBE/PBESealedObject.java
new file mode 100644
index 0000000..2420b9b
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBESealedObject.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2012, 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.PrintStream;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.StringTokenizer;
+import javax.crypto.Cipher;
+import javax.crypto.SealedObject;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/**
+ * @test
+ * @bug 8041781
+ * @summary test if seal/unseal works correctly with PBE algorithms
+ * @author Yun Ke
+ * @author Bill Situ
+ * @author Alexander Fomin
+ * @run main PBESealedObject
+ */
+public class PBESealedObject {
+
+ private static final String[] PBEAlgorithms = {
+ "pbeWithMD5ANDdes",
+ "PBEWithMD5AndDES/CBC/PKCS5Padding",
+ "PBEWithMD5AndTripleDES",
+ "PBEWithMD5AndTripleDES/CBC/PKCS5Padding",
+ "PBEwithSHA1AndDESede",
+ "PBEwithSHA1AndDESede/CBC/PKCS5Padding",
+ "PBEwithSHA1AndRC2_40",
+ "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding",
+ "PBEWithSHA1AndRC2_128",
+ "PBEWithSHA1andRC2_128/CBC/PKCS5Padding",
+ "PBEWithSHA1AndRC4_40",
+ "PBEWithsha1AndRC4_40/ECB/NoPadding",
+ "PBEWithSHA1AndRC4_128",
+ "pbeWithSHA1AndRC4_128/ECB/NoPadding",
+ "PBEWithHmacSHA1AndAES_128",
+ "PBEWithHmacSHA224AndAES_128",
+ "PBEWithHmacSHA256AndAES_128",
+ "PBEWithHmacSHA384AndAES_128",
+ "PBEWithHmacSHA512AndAES_128",
+ "PBEWithHmacSHA1AndAES_256",
+ "PBEWithHmacSHA224AndAES_256",
+ "PBEWithHmacSHA256AndAES_256",
+ "PBEWithHmacSHA384AndAES_256",
+ "PBEWithHmacSHA512AndAES_256"
+ };
+
+ public static void main(String[] args) {
+ PBESealedObject test = new PBESealedObject();
+ Provider sunjce = Security.getProvider("SunJCE");
+
+ if (!test.runAll(sunjce, System.out)) {
+ throw new RuntimeException("One or more tests have failed....");
+ }
+ }
+
+ public boolean runAll(Provider p, PrintStream out) {
+ boolean finalResult = true;
+
+ for (String algorithm : PBEAlgorithms) {
+ out.println("Running test with " + algorithm + ":");
+ try {
+ if (!runTest(p, algorithm, out)) {
+ finalResult = false;
+ out.println("STATUS: Failed");
+ } else {
+ out.println("STATUS: Passed");
+ }
+ } catch (Exception ex) {
+ finalResult = false;
+ ex.printStackTrace(out);
+ out.println("STATUS:Failed");
+ }
+ }
+
+ return finalResult;
+ }
+
+ // Have a generic throws Exception as it can throw many different exceptions
+ public boolean runTest(Provider p, String algo, PrintStream out)
+ throws Exception {
+
+ byte[] salt = new byte[8];
+ int ITERATION_COUNT = 1000;
+ AlgorithmParameters pbeParams = null;
+
+ String baseAlgo
+ = new StringTokenizer(algo, "/").nextToken().toUpperCase();
+ boolean isAES = baseAlgo.contains("AES");
+
+ try {
+ // Initialization
+ Cipher ci = Cipher.getInstance(algo, p);
+ new Random().nextBytes(salt);
+ AlgorithmParameterSpec aps = new PBEParameterSpec(salt,
+ ITERATION_COUNT);
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p);
+ SecretKey key = skf.generateSecret(
+ new PBEKeySpec("Secret Lover".toCharArray()));
+
+ // Seal
+ if (isAES) {
+ ci.init(Cipher.ENCRYPT_MODE, key);
+ pbeParams = ci.getParameters();
+ } else {
+ ci.init(Cipher.ENCRYPT_MODE, key, aps);
+ }
+
+ SealedObject so = new SealedObject(key, ci);
+
+ // Unseal and compare
+ if (isAES) {
+ ci.init(Cipher.DECRYPT_MODE, key, pbeParams);
+ } else {
+ ci.init(Cipher.DECRYPT_MODE, key, aps);
+ }
+
+ SecretKey unsealedKey;
+
+ unsealedKey = (SecretKey) so.getObject(ci);
+ if (!Arrays.equals(unsealedKey.getEncoded(), key.getEncoded())) {
+ return false;
+ }
+
+ unsealedKey = (SecretKey) so.getObject(key);
+ if (!Arrays.equals(unsealedKey.getEncoded(), key.getEncoded())) {
+ return false;
+ }
+
+ unsealedKey = (SecretKey) so.getObject(key, "SunJCE");
+ return Arrays.equals(unsealedKey.getEncoded(), key.getEncoded());
+ } catch (InvalidKeyException ex) {
+ if (baseAlgo.endsWith("TRIPLEDES") || baseAlgo.endsWith("AES_256")) {
+ out.println(
+ "Expected exception , keyStrength > 128 within" + algo);
+ return true;
+ }
+
+ throw ex;
+ }
+ }
+
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java b/test/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java
new file mode 100644
index 0000000..3668159
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBKDF2Translate.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2012, 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.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;
+
+/**
+ * @test
+ * @bug 8041781
+ * @summary Verify if the SecretKeyFactory.translateKey() method works
+ * @author Alexander Fomin
+ * @run main PBKDF2Translate
+ */
+public class PBKDF2Translate {
+
+ private static final String[] ALGO_TO_TEST = {
+ "PBKDF2WithHmacSHA1",
+ "PBKDF2WithHmacSHA224",
+ "PBKDF2WithHmacSHA256",
+ "PBKDF2WithHmacSHA384",
+ "PBKDF2WithHmacSHA512"
+ };
+
+ private static final String PASS_PHRASE = "some hidden string";
+ private static final int ITERATION_COUNT = 1000;
+ private static final int KEY_SIZE = 128;
+
+ private final String algoToTest;
+ private final byte[] salt = new byte[8];
+
+ public static void main(String[] args) throws Exception {
+
+ boolean failed = false;
+
+ for (String algo : ALGO_TO_TEST) {
+
+ System.out.println("Testing " + algo + ":");
+ PBKDF2Translate theTest = new PBKDF2Translate(algo);
+
+ try {
+ if (!theTest.testMyOwnSecretKey()
+ || !theTest.generateAndTranslateKey()
+ || !theTest.translateSpoiledKey()) {
+ // we don't want to set failed to false
+ failed = true;
+ }
+ } catch (InvalidKeyException | NoSuchAlgorithmException |
+ InvalidKeySpecException e) {
+ e.printStackTrace(System.err);
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ throw new RuntimeException("One or more tests failed....");
+ }
+ }
+
+ public PBKDF2Translate(String algoToTest) {
+ this.algoToTest = algoToTest;
+ new Random().nextBytes(this.salt);
+ }
+
+ /**
+ * 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.
+ *
+ * @return true if the test case passed; false - otherwise.
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ * @throws InvalidKeyException
+ */
+ public boolean generateAndTranslateKey() throws NoSuchAlgorithmException,
+ InvalidKeySpecException, InvalidKeyException {
+ // derive PBKDF2 key
+ SecretKey key1 = getSecretKeyForPBKDF2(algoToTest);
+
+ // translate key
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest);
+ SecretKey key2 = skf.translateKey(key1);
+
+ // check if it still the same after translation
+ if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
+ System.err.println("generateAndTranslateKey test case failed: the "
+ + "key1 and key2 values in its primary encoding format are "
+ + "not the same for " + algoToTest + "algorithm.");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * 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.
+ *
+ * @return true if the test case passed; false - otherwise.
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ * @throws InvalidKeyException
+ */
+ public boolean testMyOwnSecretKey()
+ throws NoSuchAlgorithmException, InvalidKeySpecException,
+ InvalidKeyException {
+ SecretKey key1 = getSecretKeyForPBKDF2(algoToTest);
+ SecretKey key2 = getMyOwnSecretKey();
+
+ // Is it actually the same?
+ if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
+ System.err.println("We shouldn't be here. The key1 and key2 values "
+ + "in its primary encoding format have to be the same!");
+ return false;
+ }
+
+ // Translate key
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest);
+ SecretKey key3 = skf.translateKey(key2);
+
+ // Check if it still the same after translation
+ if (!Arrays.equals(key1.getEncoded(), key3.getEncoded())) {
+ System.err.println("testMyOwnSecretKey test case failed: the key1 "
+ + "and key3 values in its primary encoding format are not "
+ + "the same for " + algoToTest + "algorithm.");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * 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.
+ *
+ * @return true if InvalidKeyException occurred; false - otherwise.
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ */
+ public boolean translateSpoiledKey() throws NoSuchAlgorithmException,
+ InvalidKeySpecException {
+ // derive the key
+ SecretKey key1 = getMyOwnSecretKey();
+
+ // spoil the key
+ ((MyPBKDF2SecretKey) key1).spoil();
+
+ // translate key
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToTest);
+ try {
+ SecretKey key2 = skf.translateKey(key1);
+ } catch (InvalidKeyException ike) {
+ // this is expected
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Generate a PBKDF2 secret key using given algorithm.
+ *
+ * @param algoToDeriveKey PBKDF2 algorithm
+ * @return PBKDF2 secret key
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ */
+ private SecretKey getSecretKeyForPBKDF2(String algoToDeriveKey)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(algoToDeriveKey);
+
+ PBEKeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(),
+ this.salt, ITERATION_COUNT, KEY_SIZE);
+
+ return skf.generateSecret(spec);
+ }
+
+ /**
+ * Generate a secrete key as an instance of a class implements PBEKey.
+ *
+ * @return secrete key
+ * @throws InvalidKeySpecException
+ * @throws NoSuchAlgorithmException
+ */
+ private SecretKey getMyOwnSecretKey() throws InvalidKeySpecException,
+ NoSuchAlgorithmException {
+ return new MyPBKDF2SecretKey(PASS_PHRASE, this.algoToTest, this.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 keySize, keyLength;
+ private int itereationCount;
+ private final String pass;
+
+ @Override
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ @Override
+ public String getFormat() {
+ return "RAW";
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ byte[] copy = new byte[keyLength];
+ System.arraycopy(this.key, 0, copy, 0, keyLength);
+ return copy;
+ }
+
+ /**
+ * 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 algorithm.
+ *
+ * @param passPhrase some string intended to be a password
+ * @param algo PBKDF2 algorithm
+ * @param salt slat for PBKDF2
+ * @param iterationCount iteration count
+ * @param keySize key size in bits
+ * @throws InvalidKeySpecException
+ * @throws NoSuchAlgorithmException
+ */
+ public MyPBKDF2SecretKey(String passPhrase, String algo, byte[] salt,
+ int iterationCount, int keySize)
+ throws InvalidKeySpecException, NoSuchAlgorithmException {
+ this.algorithm = algo;
+ this.salt = salt;
+ this.itereationCount = iterationCount;
+ this.keySize = keySize;
+ this.pass = passPhrase;
+
+ PBEKeySpec spec = new PBEKeySpec(passPhrase.toCharArray(),
+ this.salt, iterationCount, this.keySize);
+
+ SecretKeyFactory keyFactory
+ = SecretKeyFactory.getInstance(algo);
+
+ SecretKey realKey = keyFactory.generateSecret(spec);
+
+ this.keyLength = realKey.getEncoded().length;
+
+ this.key = new byte[this.keyLength];
+ System.arraycopy(realKey.getEncoded(), 0, this.key, 0,
+ this.keyLength);
+ }
+
+ @Override
+ public int getIterationCount() {
+ return itereationCount;
+ }
+
+ @Override
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ @Override
+ public char[] getPassword() {
+ return this.pass.toCharArray();
+ }
+
+ /**
+ * Spoil the generated key (before translation) to cause an
+ * InvalidKeyException
+ */
+ public void spoil() {
+ this.itereationCount = -1;
+ }
+
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java b/test/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java
new file mode 100644
index 0000000..fc0256e
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBMacBuffer.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2012, 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.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Random;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * @test
+ * @bug 8041787
+ * @summary verify that Mac.update works with different size ByteBuffer
+ * @author Alexander Fomin
+ * @run main PBMacBuffer
+ */
+public class PBMacBuffer {
+
+ private final int LARGE_SIZE = 500000;
+
+ public static void main(String[] args) {
+ String[] PBMAC1Algorithms = {
+ "HmacPBESHA1",
+ "PBEWithHmacSHA1",
+ "PBEWithHmacSHA224",
+ "PBEWithHmacSHA256",
+ "PBEWithHmacSHA384",
+ "PBEWithHmacSHA512"
+ };
+
+ String[] PBKDF2Algorithms = {
+ "PBKDF2WithHmacSHA1",
+ "PBKDF2WithHmacSHA224",
+ "PBKDF2WithHmacSHA256",
+ "PBKDF2WithHmacSHA384",
+ "PBKDF2WithHmacSHA512"
+ };
+
+ PBMacBuffer testRunner = new PBMacBuffer();
+ boolean failed = false;
+
+ for (String thePBMacAlgo : PBMAC1Algorithms) {
+
+ for (String thePBKDF2Algo : PBKDF2Algorithms) {
+
+ System.out.println("Running test with " + thePBMacAlgo
+ + " and " + thePBKDF2Algo + ":");
+ try {
+ if (!testRunner.doTest(thePBMacAlgo, thePBKDF2Algo)) {
+ failed = true;
+ }
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ InvalidKeySpecException e) {
+ failed = true;
+ e.printStackTrace(System.out);
+ System.out.println("Test FAILED.");
+ }
+ }
+ }
+
+ if (failed) {
+ throw new RuntimeException("One or more tests failed....");
+ }
+ }
+
+ /**
+ * Tests Mac.update(ByteBuffer input) method. Three test cases are
+ * performed: - large ByteBuffer test case to test if the update() method
+ * process a large ByteBuffer correctly; - empty ByteBuffer test case to
+ * test if the update() method process an empty ByteBuffer correctly; - NULL
+ * ByteBuffer test case to test if the update() method throws expected
+ * IllegalArgumentException exception.
+ *
+ * @param theMacAlgo PBMAC algorithm to test
+ * @param thePBKDF2Algo PBKDF2 algorithm to test
+ * @return true - test passed; false - otherwise.
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws InvalidKeySpecException
+ * @see javax.crypto.Mac
+ */
+ protected boolean doTest(String theMacAlgo, String thePBKDF2Algo)
+ throws NoSuchAlgorithmException, InvalidKeyException,
+ InvalidKeySpecException {
+ // obtain a SecretKey using PBKDF2
+ SecretKey key = getSecretKey(thePBKDF2Algo);
+
+ // Instantiate Mac object and init it with a SecretKey
+ Mac theMac = Mac.getInstance(theMacAlgo);
+ theMac.init(key);
+
+ // Do large ByteBuffer test case
+ if (!largeByteBufferTest(theMac)) {
+ System.out.println("Large ByteBuffer test case failed.");
+ return false;
+ }
+
+ // Do empty ByteBuffer test case
+ if (!emptyByteBufferTest(theMac)) {
+ System.out.println("Empty ByteBuffer test case failed.");
+ return false;
+ }
+
+ // Do null ByteBuffer test case
+ if (!nullByteBufferTest(theMac)) {
+ System.out.println("NULL ByteBuffer test case failed.");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Large ByteBuffer test case. Generate random ByteBuffer of LARGE_SIZE
+ * size. Performs MAC operation with the given Mac object (theMac
+ * parameter).Verifies the assertion "Upon return, the buffer's position
+ * will be equal to its limit; its limit will not have changed".
+ *
+ * @param theMac MAC object to test.
+ * @return true - test case passed; false - otherwise;
+ */
+ protected boolean largeByteBufferTest(Mac theMac) {
+ ByteBuffer buf = generateRandomByteBuffer(LARGE_SIZE);
+ int limitBefore = buf.limit();
+
+ theMac.update(buf);
+ theMac.doFinal();
+
+ int limitAfter = buf.limit();
+ int positonAfter = buf.position();
+
+ if (limitAfter != limitBefore) {
+ System.out.println("FAIL: Buffer's limit has been chenged.");
+ return false;
+ }
+
+ if (positonAfter != limitAfter) {
+ System.out.println("FAIL: "
+ + "Buffer's position isn't equal to its limit");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Empty ByteBuffer test case. Generates an empty ByteBuffer. Perform MAC
+ * operation. No exceptions are expected.
+ *
+ * @param theMac
+ * @return true - test case pass; exception otherwise
+ */
+ protected boolean emptyByteBufferTest(Mac theMac) {
+ ByteBuffer buf = generateRandomByteBuffer(0);
+ theMac.update(buf);
+ theMac.doFinal();
+ return true;
+ }
+
+ /**
+ * NULL ByteBuffer test case. Pass NULL ByteBuffer to Mac.update(ByteBuffer
+ * buffer) method. An IllegalArgumentException expected.
+ *
+ * @param theMac Mac object to test.
+ * @return true - test case pass; false - otherwise.
+ */
+ protected boolean nullByteBufferTest(Mac theMac) {
+ try {
+ ByteBuffer buf = null;
+ theMac.update(buf);
+ theMac.doFinal();
+ } catch (IllegalArgumentException e) {
+ // expected exception has been thrown
+ return true;
+ }
+
+ System.out.println("FAIL: "
+ + "IllegalArgumentException hasn't been thrown as expected");
+
+ return false;
+ }
+
+ /**
+ * Get SecretKey for the given PBKDF2 algorithm.
+ *
+ * @param thePBKDF2Algorithm - PBKDF2 algorithm
+ * @return SecretKey according to thePBKDF2Algorithm
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ */
+ protected SecretKey getSecretKey(String thePBKDF2Algorithm)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ // Prepare salt
+ byte[] salt = new byte[64]; // PKCS #5 v2.1 recommendation
+ new SecureRandom().nextBytes(salt);
+
+ // Generate secret key
+ PBEKeySpec pbeKeySpec = new PBEKeySpec(
+ "A #pwd# implied to be hidden!".toCharArray(),
+ salt, 1000, 128);
+ SecretKeyFactory keyFactory
+ = SecretKeyFactory.getInstance(thePBKDF2Algorithm);
+ return keyFactory.generateSecret(pbeKeySpec);
+ }
+
+ /**
+ * An utility method to generate a random ByteBuffer of the requested size.
+ *
+ * @param size size of the ByteBuffer.
+ * @return ByteBuffer populated random data;
+ */
+ private ByteBuffer generateRandomByteBuffer(int size) {
+ // generate randome byte array
+ byte[] data = new byte[size];
+ new Random().nextBytes(data);
+
+ // create ByteBuffer
+ ByteBuffer bb = ByteBuffer.wrap(data);
+
+ return bb;
+ }
+
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/PBMacDoFinalVsUpdate.java b/test/com/sun/crypto/provider/Cipher/PBE/PBMacDoFinalVsUpdate.java
new file mode 100644
index 0000000..1f67f16
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/PBMacDoFinalVsUpdate.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2012, 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.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * @test
+ * @bug 8041787
+ * @summary Check if doFinal and update operation result in same PBMac
+ * @author Alexander Fomin
+ * @run main PBMacDoFinalVsUpdate
+ */
+public class PBMacDoFinalVsUpdate {
+
+ public static void main(String[] args) {
+ String[] PBMAC1Algorithms = {
+ "HmacPBESHA1",
+ "PBEWithHmacSHA1",
+ "PBEWithHmacSHA224",
+ "PBEWithHmacSHA256",
+ "PBEWithHmacSHA384",
+ "PBEWithHmacSHA512"
+ };
+
+ String[] PBKDF2Algorithms = {
+ "PBKDF2WithHmacSHA1",
+ "PBKDF2WithHmacSHA224",
+ "PBKDF2WithHmacSHA256",
+ "PBKDF2WithHmacSHA384",
+ "PBKDF2WithHmacSHA512"
+ };
+
+ PBMacDoFinalVsUpdate testRunner = new PBMacDoFinalVsUpdate();
+ boolean failed = false;
+
+ for (String thePBMacAlgo : PBMAC1Algorithms) {
+
+ for (String thePBKDF2Algo : PBKDF2Algorithms) {
+
+ System.out.println("Running test with " + thePBMacAlgo
+ + " and " + thePBKDF2Algo + ":");
+ try {
+ if (!testRunner.doTest(thePBMacAlgo, thePBKDF2Algo)) {
+ failed = true;
+ }
+ } catch (NoSuchAlgorithmException | InvalidKeyException |
+ InvalidKeySpecException e) {
+ failed = true;
+ e.printStackTrace(System.out);
+ System.out.println("Test FAILED.");
+ }
+ }
+ }
+
+ if (failed) {
+ throw new RuntimeException("One or more tests failed....");
+ }
+ }
+
+ /**
+ * Uses a random generator to initialize a message, instantiate a Mac object
+ * according to the given PBMAC1 algorithm, initialize the object with a
+ * SecretKey derived using PBKDF2 algorithm (see PKCS #5 v21, chapter 7.1),
+ * feed the message into the Mac object all at once and get the output MAC
+ * as result1. Reset the Mac object, chop the message into three pieces,
+ * feed into the Mac object sequentially, and get the output MAC as result2.
+ * Finally, compare result1 and result2 and see if they are the same.
+ *
+ * @param theMacAlgo PBMAC algorithm to test
+ * @param thePBKDF2Algo PBKDF2 algorithm to test
+ * @return true - the test is passed; false - otherwise.
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws InvalidKeySpecException
+ */
+ protected boolean doTest(String theMacAlgo, String thePBKDF2Algo)
+ throws NoSuchAlgorithmException, InvalidKeyException,
+ InvalidKeySpecException {
+ int OFFSET = 5;
+
+ // Some message for which a MAC result will be calculated
+ byte[] plain = new byte[25];
+ new SecureRandom().nextBytes(plain);
+
+ // Form tail - is one of the three pieces
+ byte[] tail = new byte[plain.length - OFFSET];
+ System.arraycopy(plain, OFFSET, tail, 0, tail.length);
+
+ // Obtain a SecretKey using PBKDF2
+ SecretKey key = getSecretKey(thePBKDF2Algo);
+
+ // Instantiate Mac object and init it with a SecretKey and calc result1
+ Mac theMac = Mac.getInstance(theMacAlgo);
+ theMac.init(key);
+ byte[] result1 = theMac.doFinal(plain);
+
+ if (!isMacLengthExpected(theMacAlgo, result1.length)) {
+ return false;
+ }
+
+ // Reset Mac and calculate result2
+ theMac.reset();
+ theMac.update(plain[0]);
+ theMac.update(plain, 1, OFFSET - 1);
+ byte[] result2 = theMac.doFinal(tail);
+
+ // Return result
+ if (!java.util.Arrays.equals(result1, result2)) {
+ System.out.println("result1 and result2 are not the same:");
+ System.out.println("result1: " + dumpByteArray(result1));
+ System.out.println("result2: " + dumpByteArray(result2));
+ return false;
+ } else {
+ System.out.println("Resulted MAC with update and doFinal is same");
+ }
+
+ return true;
+ }
+
+ /**
+ * Get SecretKey for the given PBKDF2 algorithm.
+ *
+ * @param thePBKDF2Algorithm - PBKDF2 algorithm
+ * @return SecretKey according to thePBKDF2Algorithm
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ */
+ protected SecretKey getSecretKey(String thePBKDF2Algorithm)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ // Prepare salt
+ byte[] salt = new byte[64]; // PKCS #5 v2.1 recommendation
+ new SecureRandom().nextBytes(salt);
+
+ // Generate secret key
+ PBEKeySpec pbeKeySpec = new PBEKeySpec(
+ "A #pwd# implied to be hidden!".toCharArray(),
+ salt, 1000, 128);
+ SecretKeyFactory keyFactory
+ = SecretKeyFactory.getInstance(thePBKDF2Algorithm);
+ return keyFactory.generateSecret(pbeKeySpec);
+ }
+
+ /**
+ * Check if the lengthToCheck is expected length for the given MACAlgo.
+ *
+ * @param MACAlgo PBMAC algorithm
+ * @param lengthToCheck the length of MAC need to check
+ * @return true - lengthToCheck is expected length for the MACAlgo; false -
+ * otherwise.
+ */
+ protected boolean isMacLengthExpected(String MACAlgo, int lengthToCheck) {
+ java.util.regex.Pattern p = java.util.regex.Pattern.compile("(\\d+)",
+ java.util.regex.Pattern.CASE_INSENSITIVE);
+ java.util.regex.Matcher m = p.matcher(MACAlgo);
+ int val = 0;
+
+ if (m.find()) {
+ val = Integer.parseInt(m.group(1));
+ }
+
+ // HmacPBESHA1 should return MAC 20 byte length
+ if ((val == 1) && (lengthToCheck == 20)) {
+ return true;
+ }
+
+ return (val / 8) == lengthToCheck;
+ }
+
+ /**
+ * An utility method to dump a byte array for debug output.
+ *
+ * @param theByteArray the byte array to dump
+ * @return string representation of the theByteArray in Hex.
+ */
+ protected String dumpByteArray(byte[] theByteArray) {
+ StringBuilder buf = new StringBuilder();
+
+ for (byte b : theByteArray) {
+ buf.append(Integer.toHexString(b));
+ }
+
+ return buf.toString();
+ }
+
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java
new file mode 100644
index 0000000..cc237d0
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherKeyWrapperPBEKey.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2012, 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.PrintStream;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.StringTokenizer;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/**
+ * @test
+ * @bug 8041781
+ * @summary Test to see if key wrapper works correctly with PBEKey
+ * @author Yu-Ching (Valerie) PENG
+ * @author Bill Situ
+ * @author Yun Ke
+ * @run main TestCipherKeyWrapperPBEKey
+ */
+public class TestCipherKeyWrapperPBEKey {
+
+ private static final String[] PBEAlgorithms = {
+ "pbeWithMD5ANDdes",
+ "PBEWithMD5AndDES/CBC/PKCS5Padding",
+ "PBEWithMD5AndTripleDES",
+ "PBEWithMD5AndTripleDES/CBC/PKCS5Padding",
+ "PBEwithSHA1AndDESede",
+ "PBEwithSHA1AndDESede/CBC/PKCS5Padding",
+ "PBEwithSHA1AndRC2_40",
+ "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding",
+ "PBEWithSHA1AndRC2_128",
+ "PBEWithSHA1andRC2_128/CBC/PKCS5Padding",
+ "PBEWithSHA1AndRC4_40",
+ "PBEWithsha1AndRC4_40/ECB/NoPadding",
+ "PBEWithSHA1AndRC4_128",
+ "pbeWithSHA1AndRC4_128/ECB/NoPadding",
+ "PBEWithHmacSHA1AndAES_128",
+ "PBEWithHmacSHA224AndAES_128",
+ "PBEWithHmacSHA256AndAES_128",
+ "PBEWithHmacSHA384AndAES_128",
+ "PBEWithHmacSHA512AndAES_128",
+ "PBEWithHmacSHA1AndAES_256",
+ "PBEWithHmacSHA224AndAES_256",
+ "PBEWithHmacSHA256AndAES_256",
+ "PBEWithHmacSHA384AndAES_256",
+ "PBEWithHmacSHA512AndAES_256"
+ };
+
+ public static void main(String[] args) {
+
+ TestCipherKeyWrapperPBEKey test = new TestCipherKeyWrapperPBEKey();
+ Provider sunjce = Security.getProvider("SunJCE");
+
+ if (!test.runAll(sunjce, System.out)) {
+ throw new RuntimeException("One or more tests have failed....");
+ }
+ }
+
+ public boolean runAll(Provider p, PrintStream out) {
+ boolean finalResult = true;
+
+ for (String algorithm : PBEAlgorithms) {
+ out.println("Running test with " + algorithm + ":");
+ try {
+ if (!runTest(p, algorithm, out)) {
+ finalResult = false;
+ out.println("STATUS: Failed");
+ } else {
+ out.println("STATUS: Passed");
+ }
+ } catch (Exception ex) {
+ finalResult = false;
+ ex.printStackTrace(out);
+ out.println("STATUS:Failed");
+ }
+ }
+
+ return finalResult;
+ }
+
+ // Have a generic throws Exception as it can throw many different exceptions
+ public boolean runTest(Provider p, String algo, PrintStream out)
+ throws Exception {
+
+ byte[] salt = new byte[8];
+ int ITERATION_COUNT = 1000;
+ AlgorithmParameters pbeParams = null;
+
+ String baseAlgo
+ = new StringTokenizer(algo, "/").nextToken().toUpperCase();
+ boolean isAES = baseAlgo.contains("AES");
+
+ try {
+ // Initialization
+ new Random().nextBytes(salt);
+ AlgorithmParameterSpec aps = new PBEParameterSpec(salt,
+ ITERATION_COUNT);
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p);
+ SecretKey key = skf.generateSecret(new PBEKeySpec(
+ "Secret Key".toCharArray()));
+ Cipher ci = Cipher.getInstance(algo);
+
+ if (isAES) {
+ ci.init(Cipher.WRAP_MODE, key);
+ pbeParams = ci.getParameters();
+ } else {
+ ci.init(Cipher.WRAP_MODE, key, aps);
+ }
+
+ byte[] keyWrapper = ci.wrap(key);
+ if (isAES) {
+ ci.init(Cipher.UNWRAP_MODE, key, pbeParams);
+ } else {
+ ci.init(Cipher.UNWRAP_MODE, key, aps);
+ }
+
+ Key unwrappedKey = ci.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
+
+ if (baseAlgo.endsWith("TRIPLEDES")
+ || baseAlgo.endsWith("AES_256")) {
+ out.print(
+ "InvalidKeyException not thrown when keyStrength > 128");
+ return false;
+ }
+
+ return (Arrays.equals(key.getEncoded(), unwrappedKey.getEncoded()));
+
+ } catch (InvalidKeyException ex) {
+
+ if ((baseAlgo.endsWith("TRIPLEDES")
+ || baseAlgo.endsWith("AES_256"))) {
+ out.println("Expected InvalidKeyException, keyStrength > 128");
+ return true;
+ } else {
+ throw ex;
+ }
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java
new file mode 100644
index 0000000..c429523
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2012, 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.PrintStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * @test
+ * @bug 8041787
+ * @summary Verify that for PBEWithMD5AndDES cipher, only CBC mode and
+ * PKCS#5Padding is allowed
+ * @author Yun Ke
+ * @author Bill Situ
+ * @author Yu-Ching (Valerie) PENG
+ * @run main TestCipherKeyWrapperPBEKey
+ */
+public class TestCipherPBECons {
+
+ private static final String[] PBEAlgorithms = {"pbeWithMD5ANDdes",
+ "PBEWithMD5AndTripleDES"};
+ private static final String[] cipherModes = {"ECb", "cbC", "cFB", "Cfb32",
+ "OfB", "oFb64", "pCbC"};
+ private static final String[] cipherPaddings = {"Pkcs5Padding", "NoPaDDing"};
+
+ public static void main(String[] args) {
+ TestCipherPBECons test = new TestCipherPBECons();
+ Provider sunjce = Security.getProvider("SunJCE");
+
+ if (!test.runAll(sunjce, System.out)) {
+ throw new RuntimeException("One or more tests have failed....");
+ }
+ }
+
+ public boolean runAll(Provider p, PrintStream out) {
+ boolean finalResult = true;
+
+ for (String algorithm : PBEAlgorithms) {
+ for (String mode : cipherModes) {
+ for (String padding : cipherPaddings) {
+ out.println("Running test with " + algorithm
+ + "/" + mode + "/" + padding);
+ try {
+ if (!runTest(p, algorithm, mode, padding, out)) {
+ finalResult = false;
+ out.println("STATUS: Failed");
+ } else {
+ out.println("STATUS: Passed");
+ }
+ } catch (Exception ex) {
+ finalResult = false;
+ ex.printStackTrace(out);
+ out.println("STATUS:Failed");
+ }
+ }
+ }
+ }
+
+ return finalResult;
+ }
+
+ public boolean runTest(Provider p, String algo, String mo, String pad,
+ PrintStream out) throws Exception {
+ try {
+ // Initialization
+ Cipher ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
+
+ // No exception thrown, must be of the right mode and right
+ // padding scheme
+ return (mo.equalsIgnoreCase("CBC"))
+ && (pad.equalsIgnoreCase("PKCS5Padding"));
+ } catch (NoSuchAlgorithmException ex) {
+ if (p.getName().compareTo("SunJCE") == 0) {
+ if (!(mo.equalsIgnoreCase("CBC")
+ && pad.equalsIgnoreCase("PKCS5Padding"))) {
+ out.println("NoSuchAlgorithmException is as expected");
+ return true;
+ }
+ }
+
+ out.println("Caught exception: " + ex.getMessage());
+ throw ex;
+ } catch (NoSuchPaddingException ex) {
+ if (mo.equalsIgnoreCase("CBC")
+ && pad.equalsIgnoreCase("NoPadding")) {
+ out.println("NoSuchPaddingException is as expected");
+ return true;
+ } else {
+ out.println("Caught unexpected exception: " + ex.getMessage());
+ return false;
+ }
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/KeyAgreement/SameDHKeyStressTest.java b/test/com/sun/crypto/provider/KeyAgreement/SameDHKeyStressTest.java
new file mode 100644
index 0000000..f0067da
--- /dev/null
+++ b/test/com/sun/crypto/provider/KeyAgreement/SameDHKeyStressTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java b/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java
new file mode 100644
index 0000000..062c34c
--- /dev/null
+++ b/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java
@@ -0,0 +1,194 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java b/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java
new file mode 100644
index 0000000..2db96a5
--- /dev/null
+++ b/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java
@@ -0,0 +1,154 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java b/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java
new file mode 100644
index 0000000..15110d7
--- /dev/null
+++ b/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/test/com/sun/jdi/RedefineAddPrivateMethod.sh b/test/com/sun/jdi/RedefineAddPrivateMethod.sh
new file mode 100644
index 0000000..d91f74a
--- /dev/null
+++ b/test/com/sun/jdi/RedefineAddPrivateMethod.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+#
+# 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 8149743
+# @summary crash when adding a breakpoint after redefining to add a private static method
+# @run shell RedefineAddPrivateMethod.sh
+
+compileOptions=-g
+
+createJavaFile()
+{
+ cat <<EOF > $1.java.1
+public class $1 {
+ static public void main(String[] args) {
+ System.out.println("@1 breakpoint");
+ System.out.println("@2 breakpoint");
+ }
+
+ // @1 uncomment private static void test() {}
+}
+EOF
+}
+
+# This is called to feed cmds to jdb.
+dojdbCmds()
+{
+ setBkpts @1
+ runToBkpt @1
+ redefineClass @1
+ setBkpts @2
+ runToBkpt @2
+ cmd exitJdb
+}
+
+
+mysetup()
+{
+ if [ -z "$TESTSRC" ] ; then
+ TESTSRC=.
+ fi
+
+ for ii in . $TESTSRC $TESTSRC/.. ; do
+ if [ -r "$ii/ShellScaffold.sh" ] ; then
+ . $ii/ShellScaffold.sh
+ break
+ fi
+ done
+}
+
+# You could replace this next line with the contents
+# of ShellScaffold.sh and this script will run just the same.
+mysetup
+
+runit
+debuggeeFailIfPresent "Internal exception:"
+pass
diff --git a/test/java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java b/test/java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java
new file mode 100644
index 0000000..186b572
--- /dev/null
+++ b/test/java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest/ComponentIsNotDrawnAfterRemoveAddTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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 8139581
+ @summary AWT components are not drawn after removal and addition to a container
+ @author Anton Litvinov
+ */
+
+import java.awt.Button;
+import java.awt.Color;
+import java.awt.Canvas;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Panel;
+import java.util.ArrayList;
+
+public class ComponentIsNotDrawnAfterRemoveAddTest {
+ private final Frame frame;
+ private final Panel panel;
+ private final ArrayList<Testable> compList = new ArrayList<Testable>();
+
+ public ComponentIsNotDrawnAfterRemoveAddTest() {
+ frame = new Frame("ComponentIsNotDrawnAfterRemoveAddTest");
+ frame.setSize(500, 500);
+ frame.setLocation(200, 200);
+ frame.setLayout(null);
+ frame.setBackground(Color.RED);
+
+ panel = new Panel();
+ panel.setLayout(null);
+ panel.setBounds(25, 100, 455, 295);
+ panel.setBackground(Color.GREEN);
+
+ for (int i = 0; i < 10; i++) {
+ TestCanvas canv1 = new TestCanvas();
+ canv1.setBounds(i * 45 + 5, 15, 30 + i, 30 + i);
+ panel.add(canv1);
+ compList.add(canv1);
+
+ TestButton btn1 = new TestButton();
+ btn1.setBounds(i * 45 + 5, 60, 30 + i, 30 + i);
+ panel.add(btn1);
+ compList.add(btn1);
+
+ TestCanvas canv2 = new TestCanvas();
+ canv2.setBounds(i * 45 + 5, 105, 30 + i, 30 + i);
+ panel.add(canv2);
+ compList.add(canv2);
+
+ TestButton btn2 = new TestButton();
+ btn2.setBounds(i * 45 + 5, 150, 30 + i, 30 + i);
+ panel.add(btn2);
+ compList.add(btn2);
+
+ TestCanvas canv3 = new TestCanvas();
+ canv3.setBounds(i * 45 + 5, 195, 30 + i, 30 + i);
+ panel.add(canv3);
+ compList.add(canv3);
+
+ TestButton btn3 = new TestButton();
+ btn3.setBounds(i * 45 + 5, 240, 30 + i, 30 + i);
+ panel.add(btn3);
+ compList.add(btn3);
+ }
+
+ frame.add(panel);
+ frame.setVisible(true);
+ }
+
+ private void runTest() {
+ try {
+ doSleep(1500);
+ checkTestableComponents();
+
+ for (int i = 0; i < 5; i++) {
+ System.err.println(String.format("Test iteration #%d:", i));
+
+ frame.remove(panel);
+ frame.invalidate();
+ frame.validate();
+ frame.add(panel);
+
+ doSleep(1500);
+ checkTestableComponents();
+ }
+ } finally {
+ frame.dispose();
+ }
+ }
+
+ private void doSleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ }
+
+ private void checkTestableComponents() throws RuntimeException {
+ int notDrawnCompsCount = 0;
+ for (Testable comp : compList) {
+ if (!comp.wasPaintCalled()) {
+ notDrawnCompsCount++;
+ } else {
+ comp.resetPaintCalledFlag();
+ }
+ }
+ if (notDrawnCompsCount > 0) {
+ throw new RuntimeException(String.format(
+ "'paint' method of %d components was not called.", notDrawnCompsCount));
+ }
+ }
+
+ private interface Testable {
+ boolean wasPaintCalled();
+ void resetPaintCalledFlag();
+ }
+
+ private static class TestCanvas extends Canvas implements Testable {
+ private volatile boolean paintWasCalled = false;
+
+ @Override
+ public void paint(Graphics g) {
+ paintWasCalled = true;
+ super.paint(g);
+ g.setColor(Color.BLUE);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ }
+
+ @Override
+ public boolean wasPaintCalled() {
+ return paintWasCalled;
+ }
+
+ @Override
+ public void resetPaintCalledFlag() {
+ paintWasCalled = false;
+ }
+ }
+
+ private static class TestButton extends Button implements Testable {
+ private volatile boolean paintWasCalled = false;
+
+ @Override
+ public void paint(Graphics g) {
+ paintWasCalled = true;
+ super.paint(g);
+ g.setColor(Color.YELLOW);
+ g.fillRect(0, 0, 15, 15);
+ }
+
+ @Override
+ public boolean wasPaintCalled() {
+ return paintWasCalled;
+ }
+
+ @Override
+ public void resetPaintCalledFlag() {
+ paintWasCalled = false;
+ }
+ }
+
+ public static void main(String[] args) {
+ new ComponentIsNotDrawnAfterRemoveAddTest().runTest();
+ }
+}
diff --git a/test/java/lang/StringBuilder/Capacity.java b/test/java/lang/StringBuilder/Capacity.java
new file mode 100644
index 0000000..e23e915
--- /dev/null
+++ b/test/java/lang/StringBuilder/Capacity.java
@@ -0,0 +1,182 @@
+/*
+ * 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 8149330
+ * @summary Basic set of tests of capacity management
+ * @run testng Capacity
+ */
+
+import java.lang.reflect.Field;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.SplittableRandom;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+public class Capacity {
+ static final int DEFAULT_CAPACITY = 16;
+
+ private static int newCapacity(int oldCapacity,
+ int desiredCapacity)
+ {
+ return Math.max(oldCapacity * 2 + 2, desiredCapacity);
+ }
+
+ private static int nextNewCapacity(int oldCapacity) {
+ return newCapacity(oldCapacity, oldCapacity + 1);
+ }
+
+ @Test(dataProvider = "singleChar")
+ public void defaultCapacity(Character ch) {
+ StringBuilder sb = new StringBuilder();
+ assertEquals(sb.capacity(), DEFAULT_CAPACITY);
+ for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), DEFAULT_CAPACITY);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(DEFAULT_CAPACITY));
+ }
+
+ @Test(dataProvider = "charCapacity")
+ public void explicitCapacity(Character ch, int initCapacity) {
+ StringBuilder sb = new StringBuilder(initCapacity);
+ assertEquals(sb.capacity(), initCapacity);
+ for (int i = 0; i < initCapacity; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), initCapacity);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(initCapacity));
+ }
+
+ @Test(dataProvider = "singleChar")
+ public void sbFromString(Character ch) {
+ String s = "string " + ch;
+ int expectedCapacity = s.length() + DEFAULT_CAPACITY;
+ StringBuilder sb = new StringBuilder(s);
+ assertEquals(sb.capacity(), expectedCapacity);
+ for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), expectedCapacity);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(expectedCapacity));
+ }
+
+ @Test(dataProvider = "singleChar")
+ public void sbFromCharSeq(Character ch) {
+ CharSequence cs = new MyCharSeq("char seq " + ch);
+ int expectedCapacity = cs.length() + DEFAULT_CAPACITY;
+ StringBuilder sb = new StringBuilder(cs);
+ assertEquals(sb.capacity(), expectedCapacity);
+ for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+ sb.append(ch);
+ assertEquals(sb.capacity(), expectedCapacity);
+ }
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(expectedCapacity));
+ }
+
+ @Test(dataProvider = "charCapacity")
+ public void ensureCapacity(Character ch, int cap) {
+ StringBuilder sb = new StringBuilder(0);
+ assertEquals(sb.capacity(), 0);
+ sb.ensureCapacity(cap); // only has effect if cap > 0
+ int newCap = (cap == 0) ? 0 : newCapacity(0, cap);
+ assertEquals(sb.capacity(), newCap);
+ sb.ensureCapacity(newCap + 1);
+ assertEquals(sb.capacity(), nextNewCapacity(newCap));
+ sb.append(ch);
+ assertEquals(sb.capacity(), nextNewCapacity(newCap));
+ }
+
+ @Test(dataProvider = "negativeCapacity",
+ expectedExceptions = NegativeArraySizeException.class)
+ public void negativeInitialCapacity(int negCap) {
+ StringBuilder sb = new StringBuilder(negCap);
+ }
+
+ @Test(dataProvider = "negativeCapacity")
+ public void ensureNegativeCapacity(int negCap) {
+ StringBuilder sb = new StringBuilder();
+ sb.ensureCapacity(negCap);
+ assertEquals(sb.capacity(), DEFAULT_CAPACITY);
+ }
+
+ @Test(dataProvider = "charCapacity")
+ public void trimToSize(Character ch, int cap) {
+ StringBuilder sb = new StringBuilder(cap);
+ int halfOfCap = cap / 2;
+ for (int i = 0; i < halfOfCap; i++) {
+ sb.append(ch);
+ }
+ sb.trimToSize();
+ // according to the spec, capacity doesn't have to
+ // become exactly the size
+ assertTrue(sb.capacity() >= halfOfCap);
+ }
+
+ @DataProvider
+ public Object[][] singleChar() {
+ return new Object[][] { {'J'}, {'\u042b'} };
+ }
+
+ @DataProvider
+ public Object[][] charCapacity() {
+ return new Object[][] {
+ {'J', 0},
+ {'J', 1},
+ {'J', 15},
+ {'J', DEFAULT_CAPACITY},
+ {'J', 1024},
+ {'\u042b', 0},
+ {'\u042b', 1},
+ {'\u042b', 15},
+ {'\u042b', DEFAULT_CAPACITY},
+ {'\u042b', 1024},
+ };
+ }
+
+ @DataProvider
+ public Object[][] negativeCapacity() {
+ return new Object[][] { {-1}, {Integer.MIN_VALUE} };
+ }
+
+ private static class MyCharSeq implements CharSequence {
+ private CharSequence s;
+ public MyCharSeq(CharSequence s) { this.s = s; }
+ public char charAt(int i) { return s.charAt(i); }
+ public int length() { return s.length(); }
+ public CharSequence subSequence(int st, int e) {
+ return s.subSequence(st, e);
+ }
+ public String toString() { return s.toString(); }
+ }
+}
diff --git a/test/java/lang/StringBuilder/HugeCapacity.java b/test/java/lang/StringBuilder/HugeCapacity.java
new file mode 100644
index 0000000..4140a02
--- /dev/null
+++ b/test/java/lang/StringBuilder/HugeCapacity.java
@@ -0,0 +1,66 @@
+/*
+ * 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 8149330
+ * @summary Capacity should not get close to Integer.MAX_VALUE unless
+ * necessary
+ * @run main/othervm -Xmx10G HugeCapacity
+ * @ignore This test has huge memory requirements
+ */
+
+public class HugeCapacity {
+ private static int failures = 0;
+
+ public static void main(String[] args) {
+ testLatin1();
+ testUtf16();
+ if (failures > 0) {
+ throw new RuntimeException(failures + " tests failed");
+ }
+ }
+
+ private static void testLatin1() {
+ try {
+ StringBuilder sb = new StringBuilder();
+ sb.ensureCapacity(Integer.MAX_VALUE / 2);
+ sb.ensureCapacity(Integer.MAX_VALUE / 2 + 1);
+ } catch (OutOfMemoryError oom) {
+ oom.printStackTrace();
+ failures++;
+ }
+ }
+
+ private static void testUtf16() {
+ try {
+ StringBuilder sb = new StringBuilder();
+ sb.append('\u042b');
+ sb.ensureCapacity(Integer.MAX_VALUE / 4);
+ sb.ensureCapacity(Integer.MAX_VALUE / 4 + 1);
+ } catch (OutOfMemoryError oom) {
+ oom.printStackTrace();
+ failures++;
+ }
+ }
+}
diff --git a/test/java/lang/invoke/AccessControlTest.java b/test/java/lang/invoke/AccessControlTest.java
index 891710f..06da815 100644
--- a/test/java/lang/invoke/AccessControlTest.java
+++ b/test/java/lang/invoke/AccessControlTest.java
@@ -23,9 +23,7 @@
/* @test
* @summary test access checking by java.lang.invoke.MethodHandles.Lookup
- * @library ../../../..
- * @build test.java.lang.invoke.AccessControlTest
- * @build test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote
+ * @compile AccessControlTest.java AccessControlTest_subpkg/Acquaintance_remote.java
* @run testng/othervm test.java.lang.invoke.AccessControlTest
*/
diff --git a/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh b/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh
index d05a759..b584c08 100644
--- a/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh
+++ b/test/java/lang/management/MemoryMXBean/LowMemoryTest2.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 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
@@ -25,7 +25,7 @@
# @test
# @bug 4982128
# @summary Test low memory detection of non-heap memory pool
-#
+# @requires vm.gc=="null"
# @run build LowMemoryTest2 MemoryUtil
# @run shell/timeout=600 LowMemoryTest2.sh
#
diff --git a/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh b/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh
index 8db7814..a80f2c4 100644
--- a/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh
+++ b/test/java/lang/management/MemoryMXBean/MemoryManagementConcMarkSweepGC.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,7 +26,7 @@
# @bug 4530538
# @summary Run MemoryManagement test with concurrent mark sweep GC
# @author Mandy Chung
-#
+# @requires vm.gc=="ConcMarkSweep" | vm.gc=="null"
# @run build MemoryManagement
# @run shell/timeout=600 MemoryManagementConcMarkSweepGC.sh
#
diff --git a/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh b/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh
index 0435302..f315c96 100644
--- a/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh
+++ b/test/java/lang/management/MemoryMXBean/MemoryManagementParallelGC.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,7 +26,7 @@
# @bug 4530538
# @summary Run MemoryManagement test with parallel GC
# @author Mandy Chung
-#
+# @requires vm.gc=="Parallel" | vm.gc=="null"
# @run build MemoryManagement
# @run shell/timeout=600 MemoryManagementParallelGC.sh
#
diff --git a/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh b/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh
index e7ea40a..0433230 100644
--- a/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh
+++ b/test/java/lang/management/MemoryMXBean/MemoryManagementSerialGC.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,7 +26,7 @@
# @bug 4530538
# @summary Run MemoryManagement test with serial GC
# @author Mandy Chung
-#
+# @requires vm.gc=="Serial" | vm.gc=="null"
# @run build MemoryManagement
# @run shell/timeout=600 MemoryManagementSerialGC.sh
#
diff --git a/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh b/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh
index be0827a..6dbbc16 100644
--- a/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh
+++ b/test/java/lang/management/MemoryMXBean/MemoryTestAllGC.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,7 +26,7 @@
# @bug 4530538
# @summary
# @author Mandy Chung
-#
+# @requires vm.gc=="Parallel" | vm.gc=="null"
# @run compile MemoryTest.java
# @run shell MemoryTestAllGC.sh
#
@@ -52,7 +52,5 @@
# Test MemoryTest with parallel scavenger collector
runOne -XX:+UseParallelGC MemoryTest 2
-# Test MemoryTest with concurrent collector
-#runOne -XX:+UseConcMarkSweepGC MemoryTest 3
exit 0
diff --git a/test/java/lang/management/MemoryMXBean/PendingAllGC.sh b/test/java/lang/management/MemoryMXBean/PendingAllGC.sh
index edf18b3..2a1ccc3 100644
--- a/test/java/lang/management/MemoryMXBean/PendingAllGC.sh
+++ b/test/java/lang/management/MemoryMXBean/PendingAllGC.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,7 +26,7 @@
# @bug 4530538
# @summary
# @author Mandy Chung
-#
+# @requires vm.gc=="null"
# @run compile Pending.java
# @run shell PendingAllGC.sh
#
diff --git a/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh b/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh
index 5c57e48..6c13541 100644
--- a/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh
+++ b/test/java/lang/management/RuntimeMXBean/TestInputArgument.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,7 +26,6 @@
# @bug 4530538
# @summary
# @author Mandy Chung
-#
# @run compile InputArgument.java
# @run shell TestInputArgument.sh
#
@@ -48,8 +47,8 @@
runOne InputArgument
-runOne -XX:+UseParallelGC -XX:+PrintGCDetails InputArgument -XX:+PrintGCDetails
-runOne -XX:+UseParallelGC -XX:+PrintGCDetails InputArgument -XX:+UseParallelGC
+runOne -XX:+UseFastJNIAccessors -XX:+PrintGCDetails InputArgument -XX:+PrintGCDetails
+runOne -XX:+UseFastJNIAccessors -XX:+PrintGCDetails InputArgument -XX:+UseFastJNIAccessors
runOne "-Dprops=one two three" InputArgument "-Dprops=one two three"
exit 0
diff --git a/test/java/lang/management/ThreadMXBean/Locks.java b/test/java/lang/management/ThreadMXBean/Locks.java
index 9223364..1c8da46 100644
--- a/test/java/lang/management/ThreadMXBean/Locks.java
+++ b/test/java/lang/management/ThreadMXBean/Locks.java
@@ -170,6 +170,9 @@
private static CheckerThread checker;
static class WaitingThread extends Thread {
private final Phaser p;
+
+ volatile boolean waiting = false;
+
public WaitingThread(Phaser p) {
super("WaitingThread");
this.p = p;
@@ -180,7 +183,9 @@
log("WaitingThread about to wait on objC");
try {
// Signal checker thread, about to wait on objC.
+ waiting = false;
p.arriveAndAwaitAdvance(); // Phase 1 (waiting)
+ waiting = true;
objC.wait();
} catch (InterruptedException e) {
e.printStackTrace();
@@ -199,7 +204,9 @@
synchronized(objC) {
try {
// signal checker thread, about to wait on objC
+ waiting = false;
p.arriveAndAwaitAdvance(); // Phase 3 (waiting)
+ waiting = true;
objC.wait();
} catch (InterruptedException e) {
e.printStackTrace();
@@ -208,25 +215,35 @@
}
log("WaitingThread about to exit waiting on objC 2");
}
- }
- static class CheckerThread extends Thread {
- private final Phaser p;
- public CheckerThread(Phaser p) {
- super("CheckerThread");
- this.p = p;
+
+ public void waitForWaiting() {
+ p.arriveAndAwaitAdvance();
+ while (!waiting) {
+ goSleep(10);
+ }
+ waitForState(State.WAITING);
+ }
+
+ public void waitForBlocked() {
+ p.arriveAndAwaitAdvance();
+ waitForState(State.BLOCKED);
}
private void waitForState(Thread.State state) {
- p.arriveAndAwaitAdvance();
while (!waiter.isInterrupted() && waiter.getState() != state) {
- goSleep(10);
+ Thread.yield();
}
}
+ }
+ static class CheckerThread extends Thread {
+ public CheckerThread() {
+ super("CheckerThread");
+ }
public void run() {
synchronized (ready) {
// wait until WaitingThread about to wait for objC
- waitForState(Thread.State.WAITING); // Phase 1 (waiting)
+ waiter.waitForWaiting(); // Phase 1 (waiting)
checkBlockedObject(waiter, objC, null, Thread.State.WAITING);
synchronized (objC) {
@@ -235,13 +252,13 @@
// wait for waiter thread to about to enter
// synchronized object ready.
- waitForState(Thread.State.BLOCKED); // Phase 2 (waiting)
+ waiter.waitForBlocked(); // Phase 2 (waiting)
checkBlockedObject(waiter, ready, this, Thread.State.BLOCKED);
}
// wait for signal from waiting thread that it is about
// wait for objC.
- waitForState(Thread.State.WAITING); // Phase 3 (waiting)
+ waiter.waitForWaiting(); // Phase 3 (waiting)
synchronized(objC) {
checkBlockedObject(waiter, objC, Thread.currentThread(), Thread.State.WAITING);
objC.notify();
@@ -289,7 +306,7 @@
waiter = new WaitingThread(p);
waiter.start();
- checker = new CheckerThread(p);
+ checker = new CheckerThread();
checker.start();
try {
diff --git a/test/java/lang/ref/EnqueuePollRace.java b/test/java/lang/ref/EnqueuePollRace.java
index c19a366..5171e13 100644
--- a/test/java/lang/ref/EnqueuePollRace.java
+++ b/test/java/lang/ref/EnqueuePollRace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -25,7 +25,7 @@
* @bug 8014890
* @summary Verify that a race between ReferenceQueue.enqueue() and poll() does not occur.
* @author thomas.schatzl@oracle.com
- * @run main/othervm -XX:+UseSerialGC -Xmx10M EnqueuePollRace
+ * @run main/othervm -Xmx10M EnqueuePollRace
*/
import java.lang.ref.*;
diff --git a/test/java/net/InetAddress/B6246242.java b/test/java/net/InetAddress/B6246242.java
index 8ca8017..77e9628 100644
--- a/test/java/net/InetAddress/B6246242.java
+++ b/test/java/net/InetAddress/B6246242.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6246242
+ * @bug 6246242 8135259
* @summary UnknownHostException contains wrong error message
*/
@@ -36,7 +36,7 @@
a = InetAddress.getByName("foo.bar");
} catch (UnknownHostException e) {
String s = e.getMessage();
- if (s.indexOf("foo.bar: foo.bar") >= 0)
+ if (s.contains("foo.bar: foo.bar") || s.contains("unknown error"))
throw new RuntimeException("UnknownHostException has wrong message: " + s);
}
}
diff --git a/test/java/net/SetFactoryPermission/SetFactoryPermission.java b/test/java/net/SetFactoryPermission/SetFactoryPermission.java
new file mode 100644
index 0000000..9477962
--- /dev/null
+++ b/test/java/net/SetFactoryPermission/SetFactoryPermission.java
@@ -0,0 +1,87 @@
+/*
+ * 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");
+ }
+ }
+ }
+}
diff --git a/test/java/net/SetFactoryPermission/policy.fail b/test/java/net/SetFactoryPermission/policy.fail
new file mode 100644
index 0000000..a4c6d11
--- /dev/null
+++ b/test/java/net/SetFactoryPermission/policy.fail
@@ -0,0 +1,3 @@
+grant {
+
+};
diff --git a/test/java/net/SetFactoryPermission/policy.success b/test/java/net/SetFactoryPermission/policy.success
new file mode 100644
index 0000000..d382afc
--- /dev/null
+++ b/test/java/net/SetFactoryPermission/policy.success
@@ -0,0 +1,4 @@
+grant {
+ permission java.lang.RuntimePermission "setFactory";
+};
+
diff --git a/test/java/net/SocketPermission/SocketPermissionTest.java b/test/java/net/SocketPermission/SocketPermissionTest.java
new file mode 100644
index 0000000..1552acc
--- /dev/null
+++ b/test/java/net/SocketPermission/SocketPermissionTest.java
@@ -0,0 +1,339 @@
+/*
+ * 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 8047031
+ * @summary SocketPermission tests for legacy socket types
+ * @run testng/othervm SocketPermissionTest
+ */
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketPermission;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+public class SocketPermissionTest {
+
+ @BeforeMethod
+ public void setupSecurityManager() throws Exception {
+ // All permissions, a specific ACC will be used to when testing
+ // with a reduced permission set.
+ Policy.setPolicy(new Policy() {
+ final PermissionCollection perms = new Permissions();
+ { perms.add(new java.security.AllPermission()); }
+ public PermissionCollection getPermissions(ProtectionDomain domain) {
+ return perms;
+ }
+ public PermissionCollection getPermissions(CodeSource codesource) {
+ return perms;
+ }
+ public boolean implies(ProtectionDomain domain, Permission perm) {
+ return perms.implies(perm);
+ }
+ } );
+ System.setSecurityManager(new SecurityManager());
+ }
+
+ static final AccessControlContext RESTRICTED_ACC = getAccessControlContext();
+
+ @Test
+ public void connectSocketTest() throws Exception {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ int port = ss.getLocalPort();
+
+ String addr = "localhost:" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen,connect,resolve"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (Socket client = new Socket(InetAddress.getLocalHost(), port)) {
+ }
+ return null;
+ }, acc);
+
+ //Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ Socket client = new Socket(InetAddress.getLocalHost(), port);
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+ }
+
+ @Test
+ public void connectDatagramSocketTest() throws Exception {
+ byte[] msg = "Hello".getBytes(UTF_8);
+ InetAddress lh = InetAddress.getLocalHost();
+
+ try (DatagramSocket ds = new DatagramSocket(0)) {
+ int port = ds.getLocalPort();
+
+ String addr = lh.getHostAddress() + ":" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "connect,resolve"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port);
+ ds.send(dp);
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port);
+ ds.send(dp);
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+ }
+
+ @Test
+ public void acceptServerSocketTest() throws Exception {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ int port = ss.getLocalPort();
+
+ String addr = "localhost:" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen,connect,resolve"),
+ new SocketPermission("localhost:1024-", "accept"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ InetAddress me = InetAddress.getLocalHost();
+ try (Socket client = new Socket(me, port)) {
+ ss.accept();
+ }
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ InetAddress me = InetAddress.getLocalHost();
+ try (Socket client = new Socket(me, port)) {
+ ss.accept();
+ }
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+ }
+
+ @Test
+ public void sendDatagramPacketTest() throws Exception {
+ byte[] msg = "Hello".getBytes(UTF_8);
+ InetAddress group = InetAddress.getByName("229.227.226.221");
+
+ try (DatagramSocket ds = new DatagramSocket(0)) {
+ int port = ds.getLocalPort();
+
+ String addr = "localhost:" + port;
+ //test for SocketPermission "229.227.226.221", "connect,accept"
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen,resolve"),
+ new SocketPermission("229.227.226.221", "connect,accept"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port);
+ ds.send(hi);
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port);
+ ds.send(hi);
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+ }
+
+ @Test
+ public void joinGroupMulticastTest() throws Exception {
+ InetAddress group = InetAddress.getByName("229.227.226.221");
+ try (MulticastSocket s = new MulticastSocket(0)) {
+ int port = s.getLocalPort();
+
+ String addr = "localhost:" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen,resolve"),
+ new SocketPermission("229.227.226.221", "connect,accept"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ s.joinGroup(group);
+ s.leaveGroup(group);
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ s.joinGroup(group);
+ s.leaveGroup(group);
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+
+ }
+
+ @Test
+ public void listenDatagramSocketTest() throws Exception {
+ // the hardcoded port number doesn't really matter since we expect the
+ // security permission to be checked before the underlying operation.
+ int port = 8899;
+ String addr = "localhost:" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (DatagramSocket ds = new DatagramSocket(port)) { }
+ catch (IOException intermittentlyExpected) { /* ignore */ }
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (DatagramSocket ds = new DatagramSocket(port)) { }
+ catch (IOException intermittentlyExpected) { /* ignore */ }
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+
+ @Test
+ public void listenMulticastSocketTest() throws Exception {
+ // the hardcoded port number doesn't really matter since we expect the
+ // security permission to be checked before the underlying operation.
+ int port = 8899;
+ String addr = "localhost:" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (MulticastSocket ms = new MulticastSocket(port)) { }
+ catch (IOException intermittentlyExpected) { /* ignore */ }
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (MulticastSocket ms = new MulticastSocket(port)) { }
+ catch (IOException intermittentlyExpected) { /* ignore */ }
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+ }
+
+ @Test
+ public void listenServerSocketTest() throws Exception {
+ // the hardcoded port number doesn't really matter since we expect the
+ // security permission to be checked before the underlying operation.
+ int port = 8899;
+ String addr = "localhost:" + port;
+ AccessControlContext acc = getAccessControlContext(
+ new SocketPermission(addr, "listen"));
+
+ // Positive
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (ServerSocket ss = new ServerSocket(port)) { }
+ catch (IOException intermittentlyExpected) { /* ignore */ }
+ return null;
+ }, acc);
+
+ // Negative
+ try {
+ AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ try (ServerSocket ss = new ServerSocket(port)) { }
+ catch (IOException intermittentlyExpected) { /* ignore */ }
+ fail("Expected SecurityException");
+ return null;
+ }, RESTRICTED_ACC);
+ } catch (SecurityException expected) { }
+
+ }
+
+ private static AccessControlContext getAccessControlContext(Permission... ps) {
+ Permissions perms = new Permissions();
+ for (Permission p : ps) {
+ perms.add(p);
+ }
+ /*
+ *Create an AccessControlContext that consist a single protection domain
+ * with only the permissions calculated above
+ */
+ ProtectionDomain pd = new ProtectionDomain(null, perms);
+ return new AccessControlContext(new ProtectionDomain[]{pd});
+ }
+
+ // Standalone entry point for running with, possibly older, JDKs.
+ public static void main(String[] args) throws Throwable {
+ SocketPermissionTest test = new SocketPermissionTest();
+ test.setupSecurityManager();
+ for (java.lang.reflect.Method m : SocketPermissionTest.class.getDeclaredMethods()) {
+ if (m.getAnnotation(Test.class) != null) {
+ System.out.println("Invoking " + m.getName());
+ m.invoke(test);
+ }
+ }
+ }
+}
diff --git a/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java b/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
index 82eeab0..bc1c2dc 100644
--- a/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
+++ b/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4017232
+ * @bug 4017232 8046339
* @summary If, after returning a reference to a remote object in the current
* VM (which gets implicitly converted to a remote stub), the client fails to
* both send a DGC dirty call and to send a "DGC acknowledgment", the RMI
@@ -36,10 +36,14 @@
import java.io.*;
import java.net.*;
+import java.lang.reflect.Field;
import java.lang.ref.*;
import java.rmi.*;
import java.rmi.server.*;
+import java.util.Map;
+
+import sun.rmi.transport.DGCAckHandler;
interface ReturnRemote extends Remote {
Object returnRemote() throws RemoteException;
@@ -48,6 +52,7 @@
public class DGCAckFailure implements ReturnRemote {
private static final long TIMEOUT = 20000;
+ private static final long ACK_TIMEOUT = TIMEOUT / 2;
public Object returnRemote() {
return new Wrapper(this);
@@ -55,7 +60,8 @@
public static void main(String[] args) throws Exception {
- System.setProperty("sun.rmi.dgc.ackTimeout", "10000");
+ System.setProperty("sun.rmi.dgc.ackTimeout",
+ Long.toString(ACK_TIMEOUT));
/*
* Set a socket factory that has a hook for shutting down all client
@@ -93,12 +99,31 @@
break;
}
}
- if (ref == weakRef) {
- System.err.println("TEST PASSED");
- } else {
+ if (ref != weakRef) {
throw new RuntimeException("TEST FAILED: " +
"timed out, remote object not garbage collected");
}
+
+ // 8046339
+ // All DGCAckHandlers must be properly released after timeout
+ Thread.sleep(ACK_TIMEOUT + 100);
+ try {
+ Field field =
+ DGCAckHandler.class.getDeclaredField("idTable");
+ field.setAccessible(true);
+ Object obj = field.get(null);
+ Map<?,?> idTable = (Map<?,?>)obj;
+
+ if (!idTable.isEmpty()) {
+ throw new RuntimeException("TEST FAILED: " +
+ "DGCAckHandler.idTable isn't empty");
+ }
+ } catch (ReflectiveOperationException roe) {
+ throw new RuntimeException(roe);
+ }
+
+ System.err.println("TEST PASSED");
+
} finally {
try {
UnicastRemoteObject.unexportObject((Remote) weakRef.get(),
diff --git a/test/java/security/AccessController/DoPrivAccomplice.java b/test/java/security/AccessController/DoPrivAccomplice.java
new file mode 100644
index 0000000..6cc2846
--- /dev/null
+++ b/test/java/security/AccessController/DoPrivAccomplice.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007, 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. 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.
+ */
+
+public class DoPrivAccomplice {
+
+ public String go() {
+ String name = (String)java.security.AccessController.
+ doPrivileged((java.security.PrivilegedAction)() ->
+ System.getProperty("user.name"));
+ return name;
+ }
+}
diff --git a/test/java/security/AccessController/DoPrivAccompliceTest.java b/test/java/security/AccessController/DoPrivAccompliceTest.java
new file mode 100644
index 0000000..d18038c
--- /dev/null
+++ b/test/java/security/AccessController/DoPrivAccompliceTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2007, 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. 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.FileWriter;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @test
+ * @bug 8048362
+ * @compile ../../../lib/testlibrary/JavaToolUtils.java
+ * DoPrivAccomplice.java DoPrivTest.java
+ * @summary Tests the doPrivileged with accomplice Generate two jars
+ * (DoPrivTest.jar and DoPrivAccomplice.jar) and grant permission to
+ * DoPrivAccmplice.jar for reading user.home property from a PrivilagedAction.
+ * Run DoPrivTest.jar and try to access user.home property using
+ * DoPrivAccmplice.jar.
+ * @run main/othervm DoPrivAccompliceTest
+ */
+
+public class DoPrivAccompliceTest {
+
+ private static final String PWD = System.getProperty("test.classes", "./");
+ private static final String ACTION_SOURCE = "DoPrivAccomplice";
+ private static final String TEST_SOURCE = "DoPrivTest";
+
+ public static void createPolicyFile(URI codebaseURL) throws IOException {
+ String codebase = codebaseURL.toString();
+ String quotes = "\"";
+ StringBuilder policyFile = new StringBuilder();
+ policyFile.append("grant codeBase ").append(quotes).
+ append(codebase).append(quotes).append("{\n").
+ append("permission java.util.PropertyPermission ").
+ append(quotes).append("user.name").append(quotes).
+ append(",").append(quotes).append("read").append(quotes).
+ append(";\n};");
+ try (FileWriter writer = new FileWriter(new File(PWD, "java.policy"))) {
+ writer.write(policyFile.toString());
+ writer.close();
+ } catch (IOException e) {
+ System.err.println("Error while creating policy file");
+ throw e;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ final File class1 = new File(PWD, ACTION_SOURCE + ".class");
+ final File class2 = new File(PWD, TEST_SOURCE + ".class");
+ final File jarFile1 = new File(PWD, ACTION_SOURCE + ".jar");
+ final File jarFile2 = new File(PWD, TEST_SOURCE + ".jar");
+ System.out.println("Compilation successfull");
+ JavaToolUtils.createJar(jarFile1, Arrays.asList(new File[]{class1}));
+ System.out.println("Created jar file " + jarFile1);
+ JavaToolUtils.createJar(jarFile2, Arrays.asList(new File[]{class2}));
+ System.out.println("Created jar file " + jarFile2);
+ createPolicyFile(jarFile1.toURI());
+
+ List<String> commands = new ArrayList<>();
+ final String pathSepartor = System.getProperty("path.separator");
+ commands.add("-Djava.security.manager");
+ commands.add("-Djava.security.policy=" + PWD + "/java.policy");
+ commands.add("-classpath");
+ commands.add(PWD + "/" + TEST_SOURCE + ".jar" + pathSepartor
+ + PWD + "/" + ACTION_SOURCE + ".jar");
+ commands.add(TEST_SOURCE);
+ if (JavaToolUtils.runJava(commands) == 0) {
+ System.out.println("Test PASSES");
+ }
+ }
+
+}
diff --git a/test/java/security/AccessController/DoPrivTest.java b/test/java/security/AccessController/DoPrivTest.java
new file mode 100644
index 0000000..9ed0f97
--- /dev/null
+++ b/test/java/security/AccessController/DoPrivTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2007, 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. 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.
+ */
+
+public class DoPrivTest {
+
+ public static void main(String[] args) {
+ String name = new DoPrivAccomplice().go();
+ System.out.println("Received Name : " + name);
+ }
+}
diff --git a/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java b/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java
new file mode 100644
index 0000000..13b2db4
--- /dev/null
+++ b/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013,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 8050281
+ * @summary Test that NullPointerException is thrown if any element of perms
+ * parameter is null
+ * @run testng LimitedDoPrivilegedWithNullPerms
+ */
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.PropertyPermission;
+import org.testng.annotations.Test;
+
+public class LimitedDoPrivilegedWithNullPerms {
+
+ AccessControlContext acc = AccessController.getContext();
+ Permission p1 = new PropertyPermission("user.name", "read");
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test1() {
+ AccessController.doPrivileged(
+ (PrivilegedAction<Void>) () -> null, acc, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test2() {
+ AccessController.doPrivileged(
+ (PrivilegedAction<Void>) () -> null, acc, p1, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test3() {
+ AccessController.doPrivilegedWithCombiner(
+ (PrivilegedAction<Void>) () -> null, acc, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test4() {
+ AccessController.doPrivilegedWithCombiner(
+ (PrivilegedAction<Void>) () -> null, acc, p1, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test5() throws PrivilegedActionException {
+ AccessController.doPrivileged(
+ (PrivilegedExceptionAction<Void>) () -> null,
+ acc, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test6() throws PrivilegedActionException {
+ AccessController.doPrivileged(
+ (PrivilegedExceptionAction<Void>) () -> null,
+ acc, p1, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test7() throws PrivilegedActionException {
+ AccessController.doPrivilegedWithCombiner(
+ (PrivilegedExceptionAction<Void>) () -> null,
+ acc, null);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test8() throws PrivilegedActionException {
+ AccessController.doPrivilegedWithCombiner(
+ (PrivilegedExceptionAction<Void>) () -> null,
+ acc, p1, null);
+ }
+}
diff --git a/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java b/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java
new file mode 100644
index 0000000..955f39d
--- /dev/null
+++ b/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013,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 8050281
+ * @summary Test limited doprivileged action with trhead calls.
+ * @run main/othervm/policy=policy LimitedDoPrivilegedWithThread
+ */
+import java.io.FilePermission;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.PropertyPermission;
+
+public class LimitedDoPrivilegedWithThread {
+
+ private static final Permission PROPERTYPERM
+ = new PropertyPermission("user.name", "read");
+ private static final Permission FILEPERM
+ = new FilePermission("*", "read");
+ private static final AccessControlContext ACC
+ = new AccessControlContext(
+ new ProtectionDomain[]{new ProtectionDomain(null, null)});
+
+ public static void main(String args[]) {
+ //parent thread without any permission
+ AccessController.doPrivileged(
+ (PrivilegedAction) () -> {
+ Thread ct = new Thread(
+ new ChildThread(PROPERTYPERM, FILEPERM));
+ ct.start();
+ try {
+ ct.join();
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ ie.printStackTrace();
+ throw new RuntimeException("Unexpected InterruptedException");
+ }
+ return null;
+ }, ACC);
+ }
+}
+
+class ChildThread implements Runnable {
+
+ private final Permission P1;
+ private final Permission P2;
+ private boolean catchACE = false;
+
+ public ChildThread(Permission p1, Permission p2) {
+ this.P1 = p1;
+ this.P2 = p2;
+ }
+
+ @Override
+ public void run() {
+ //Verified that child thread has permission p1,
+ runTest(null, P1, false, 1);
+ //Verified that child thread inherits parent thread's access control context
+ AccessControlContext childAcc = AccessController.getContext();
+ runTest(childAcc, P1, true, 2);
+ //Verified that we can give permision p2 to limit the "privilege" of the
+ //class calling doprivileged action, stack walk will continue
+ runTest(null, P2, true, 3);
+
+ }
+
+ public void runTest(AccessControlContext acc, Permission perm,
+ boolean expectACE, int id) {
+
+ AccessController.doPrivileged(
+ (PrivilegedAction) () -> {
+ try {
+ AccessController.getContext().checkPermission(P1);
+ } catch (AccessControlException ace) {
+ catchACE = true;
+ }
+ if (catchACE ^ expectACE) {
+ throw new RuntimeException("test" + id + " failed");
+ }
+ return null;
+ }, acc, perm);
+ }
+}
diff --git a/test/java/security/AccessController/policy b/test/java/security/AccessController/policy
new file mode 100644
index 0000000..83ed146
--- /dev/null
+++ b/test/java/security/AccessController/policy
@@ -0,0 +1,4 @@
+grant{
+ permission java.util.PropertyPermission "user.name", "read";
+ permission java.io.FilePermission "*", "read";
+};
diff --git a/test/java/security/KeyStore/PKCS12/CheckDefaults.java b/test/java/security/KeyStore/PKCS12/CheckDefaults.java
new file mode 100644
index 0000000..59a7b80
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/CheckDefaults.java
@@ -0,0 +1,67 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/ConvertP12Test.java b/test/java/security/KeyStore/PKCS12/ConvertP12Test.java
new file mode 100644
index 0000000..f5334bf
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/ConvertP12Test.java
@@ -0,0 +1,234 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/EntryProtectionTest.java b/test/java/security/KeyStore/PKCS12/EntryProtectionTest.java
new file mode 100644
index 0000000..586eda3
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/EntryProtectionTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/KeytoolReaderP12Test.java b/test/java/security/KeyStore/PKCS12/KeytoolReaderP12Test.java
new file mode 100644
index 0000000..4c7e55b
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/KeytoolReaderP12Test.java
@@ -0,0 +1,155 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/KeytoolWriteP12Test.java b/test/java/security/KeyStore/PKCS12/KeytoolWriteP12Test.java
new file mode 100644
index 0000000..b35751f
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/KeytoolWriteP12Test.java
@@ -0,0 +1,128 @@
+/*
+ * 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();
+ }
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/MetadataEmptyTest.java b/test/java/security/KeyStore/PKCS12/MetadataEmptyTest.java
new file mode 100644
index 0000000..1874241
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/MetadataEmptyTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/MetadataStoreLoadTest.java b/test/java/security/KeyStore/PKCS12/MetadataStoreLoadTest.java
new file mode 100644
index 0000000..729c5fb
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/MetadataStoreLoadTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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", " ");
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/ReadP12Test.java b/test/java/security/KeyStore/PKCS12/ReadP12Test.java
new file mode 100644
index 0000000..429a498
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/ReadP12Test.java
@@ -0,0 +1,193 @@
+/*
+ * 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");
+ }
+
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/StoreTrustedCertAPITest.java b/test/java/security/KeyStore/PKCS12/StoreTrustedCertAPITest.java
new file mode 100644
index 0000000..68efa2b
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/StoreTrustedCertAPITest.java
@@ -0,0 +1,97 @@
+/*
+ * 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();
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/StoreTrustedCertKeytool.java b/test/java/security/KeyStore/PKCS12/StoreTrustedCertKeytool.java
new file mode 100644
index 0000000..1b1672d
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/StoreTrustedCertKeytool.java
@@ -0,0 +1,128 @@
+/*
+ * 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();
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/Utils.java b/test/java/security/KeyStore/PKCS12/Utils.java
new file mode 100644
index 0000000..2689415
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/Utils.java
@@ -0,0 +1,137 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/test/java/security/KeyStore/PKCS12/WriteP12Test.java b/test/java/security/KeyStore/PKCS12/WriteP12Test.java
new file mode 100644
index 0000000..f402409
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/WriteP12Test.java
@@ -0,0 +1,371 @@
+/*
+ * 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);
+ }
+ }
+
+}
diff --git a/test/java/security/KeyStore/PKCS12/api_cert_chain.p12.data b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12.data
new file mode 100644
index 0000000..b4da479
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12.data
@@ -0,0 +1,76 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data
new file mode 100644
index 0000000..7cf01d6
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data
@@ -0,0 +1,7 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/api_private_key.p12.data b/test/java/security/KeyStore/PKCS12/api_private_key.p12.data
new file mode 100644
index 0000000..4daf029
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_private_key.p12.data
@@ -0,0 +1,31 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data
new file mode 100644
index 0000000..d579bc5
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data
@@ -0,0 +1,3 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12.data b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12.data
new file mode 100644
index 0000000..899a4e3
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12.data
@@ -0,0 +1,21 @@
+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==
diff --git a/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data
new file mode 100644
index 0000000..d25641f
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data
@@ -0,0 +1,3 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/api_two_pass.p12.data b/test/java/security/KeyStore/PKCS12/api_two_pass.p12.data
new file mode 100644
index 0000000..453b66e
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_two_pass.p12.data
@@ -0,0 +1,46 @@
+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
++FjQ0fq7d/D+Ilu6e2EBG1y/ngICBAA=
diff --git a/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data b/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data
new file mode 100644
index 0000000..4113ade
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data
@@ -0,0 +1,3 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jceks_chain.pfx.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jceks_chain.pfx.data
new file mode 100644
index 0000000..3dbe7e4
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jceks_chain.pfx.data
@@ -0,0 +1,61 @@
+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
+CxwCAgfQ
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jks_chain.pfx.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jks_chain.pfx.data
new file mode 100644
index 0000000..3dbe7e4
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/ie_jks_chain.pfx.data
@@ -0,0 +1,61 @@
+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
+CxwCAgfQ
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_selfsigned.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_selfsigned.p12.data
new file mode 100644
index 0000000..e64b3b4
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_selfsigned.p12.data
@@ -0,0 +1,30 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twoentry.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twoentry.p12.data
new file mode 100644
index 0000000..9d58b00
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twoentry.p12.data
@@ -0,0 +1,69 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twopass.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twopass.p12.data
new file mode 100644
index 0000000..e26169f
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jceks_twopass.p12.data
@@ -0,0 +1,45 @@
+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
+1QoCAgQA
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_selfsigned.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_selfsigned.p12.data
new file mode 100644
index 0000000..362a88e
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_selfsigned.p12.data
@@ -0,0 +1,45 @@
+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
+xp4CAgQA
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twoentry.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twoentry.p12.data
new file mode 100644
index 0000000..9d58b00
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twoentry.p12.data
@@ -0,0 +1,69 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twopass.p12.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twopass.p12.data
new file mode 100644
index 0000000..e26169f
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/jdk_jks_twopass.p12.data
@@ -0,0 +1,45 @@
+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
+1QoCAgQA
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/convertP12/keystoreCA.jceks.data b/test/java/security/KeyStore/PKCS12/certs/convertP12/keystoreCA.jceks.data
new file mode 100644
index 0000000..be06f6a
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/convertP12/keystoreCA.jceks.data
@@ -0,0 +1,38 @@
+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
+FgNW1MI40XfEdWafFXeJ+yQTHPyoNdk=
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/ie_chain.pfx.data b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_chain.pfx.data
new file mode 100644
index 0000000..3dbe7e4
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_chain.pfx.data
@@ -0,0 +1,61 @@
+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
+CxwCAgfQ
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/ie_self.pfx.data b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_self.pfx.data
new file mode 100644
index 0000000..acde65c
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/ie_self.pfx.data
@@ -0,0 +1,47 @@
+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
+/FfU1hlVl8YCAgfQ
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_chain.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_chain.p12.data
new file mode 100644
index 0000000..f379d2b
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_chain.p12.data
@@ -0,0 +1,62 @@
+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
+IsNed5PjTXd1/rQmWIcCDOy9lgICBAA=
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_self.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_self.p12.data
new file mode 100644
index 0000000..b643ba4
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/jdk_self.p12.data
@@ -0,0 +1,45 @@
+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
+I6oCAgQA
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_chain.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_chain.p12.data
new file mode 100644
index 0000000..623d470
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_chain.p12.data
@@ -0,0 +1,73 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_self.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_self.p12.data
new file mode 100644
index 0000000..c36f26b
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_self.p12.data
@@ -0,0 +1,54 @@
+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
+0AQQxrOtDDKIzjpW4+rATcwNPAAA
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_twoentries.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_twoentries.p12.data
new file mode 100644
index 0000000..d0c451b
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/mozilla_twoentries.p12.data
@@ -0,0 +1,125 @@
+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
+AoiyQ6u3imI281gAAA==
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_chain.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_chain.p12.data
new file mode 100644
index 0000000..af0557a
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_chain.p12.data
@@ -0,0 +1,73 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_self.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_self.p12.data
new file mode 100644
index 0000000..bdc9483
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_self.p12.data
@@ -0,0 +1,54 @@
+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
+HwQQ6Vxq63yfCeamza5PZKytWQAA
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_twoentries.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_twoentries.p12.data
new file mode 100644
index 0000000..cdc8438
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/netscape_twoentries.p12.data
@@ -0,0 +1,125 @@
+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
+LK2fdlxrCGzUHTgAAA==
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/readP12/openssl.p12.data b/test/java/security/KeyStore/PKCS12/certs/readP12/openssl.p12.data
new file mode 100644
index 0000000..101a039
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/readP12/openssl.p12.data
@@ -0,0 +1,41 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreCA.jks.data b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreCA.jks.data
new file mode 100644
index 0000000..1d6b5a4
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreCA.jks.data
@@ -0,0 +1,38 @@
+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
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreEU.jks.data b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreEU.jks.data
new file mode 100644
index 0000000..c8e4ecf
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/certs/writeP12/keystoreEU.jks.data
@@ -0,0 +1,79 @@
+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
+VL+NWQOgtME=
\ No newline at end of file
diff --git a/test/java/security/KeyStore/PKCS12/ie_chain.pfx.data b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.data
new file mode 100644
index 0000000..a509e05
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.data
@@ -0,0 +1,65 @@
+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
+fAQEFPL7KYm4NrHpQSKpto5+pPs7NgLWAgIEAA==
diff --git a/test/java/security/KeyStore/PKCS12/ie_chain.pfx.pem b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.pem
new file mode 100644
index 0000000..6caea3f
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/ie_chain.pfx.pem
@@ -0,0 +1,23 @@
+-----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-----
diff --git a/test/java/security/KeyStore/PKCS12/ie_self.pfx.data b/test/java/security/KeyStore/PKCS12/ie_self.pfx.data
new file mode 100644
index 0000000..0500db5
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/ie_self.pfx.data
@@ -0,0 +1,31 @@
+MIIGwAIBAzCCBnoGCSqGSIb3DQEHAaCCBmsEggZnMIIGYzCCAzAGCSqGSIb3DQEHAaCCAyEEggMd
+MIIDGTCCAxUGCyqGSIb3DQEMCgECoIICqjCCAqYwKAYKKoZIhvcNAQwBAzAaBBSZNW+Sd+0mytcN
+A/vZXbBxiRZHxgICBAAEggJ4YAYE4bHqC0rxj3w6eUmXqp/tebM75dLfm/YyOQqKTE5bPJNWAT2E
+njhtDTNDigxhLjy4tH1sligytYgABTOcBotniRGM9yZ/52JR7bv6NxGCbv+SU2v10Srug+onIhFM
+639E7bG1yRfNW7IATgKLX1KxIBWFX973MBnsDVK5gZEhy17hzLUdaJRk3AyiCIB17R3d0SthtIW+
+WR/1rYUDOUe4weJYPsVW+WwtYtdOllcDLopS+B/QgXPrv9FOLUfEHtNO9crLMnGU8Kr9uqMyHu99
+ZdIgH1wuuK3Na7noc4KI4Q3JoTsRRfWpl6nEt5FERpRY8Q1spNwzo9mZ9NwtVyMkjGfSnZP8RE7M
+2csqZESd88PGVcnrMzNb/y+5X1qgj+bx56v+6m91QcIcv3RMK645Wiow9WjtmZL5sGl0SNUcwzP1
+zYGjZrWnTICjMmuNDIDznX2yrtHLxoM8AzhUwIvirTROv+RaqO+gopDxTBy9kymPiHS6PLllC3hL
+GYqZ1CFCIkn7nf9DP4tKJmfvOhrURCFnbXSlIbu7d5j8TNI+6CLuD9H1c8vlp6kdvaJejLzAVFt8
+eY8A/zIDUKcyKXCFPS4F25X6vJ6ZdQOKBVzg8ueAUety6o44eJ7NxusLoMyHneLCTQ7jRobSihss
+eXa182Yk1Q+H7Dx+zbPr6FsNp8wNf90CM6zZAbgBqBzM5eGb2Y/Ich1eG2oLAFurrpqgxXlb6nJS
+nJ7e7NgAqf3S4VbKt3uCvVtrZfUUvCdx4BUfeNSNOGmAtgCRlPn93Gc2+IL7eJYNqDScNjGf/hj+
+rHCL7jNPRvoovzBdUSzJ1Y92r0iUWu4xWDAzBgkqhkiG9w0BCRQxJh4kAHAAawBjAHMAMQAyAHQA
+ZQBzAHQAZQBuAGQAdQBzAGUAcgAxMCEGCSqGSIb3DQEJFTEUBBJUaW1lIDE0MzI3MDQxMTIzNzQw
+ggMrBgkqhkiG9w0BBwagggMcMIIDGAIBADCCAxEGCSqGSIb3DQEHATAoBgoqhkiG9w0BDAEGMBoE
+FNSn/NMdKj9fmg+dMmEFE2rlvLY8AgIEAICCAtiFvAUXr/bKf77WWVx2Y9OnqlUNkXkeE7XEI5XB
+qKid6iUlv4eRWY3PyK5gLIDELGJHOIpHKAkjSef6kBU04E/jcQmg+kA+3GScXFZXTw+jjgGmaX9x
+zbAzXAvEURwh/T0HRtxsxXLf+7D3gdiIAQcVyh50xD58HOOox7mo1NFQ9Vi63f82wyJgQH1tYSid
+ExsC2ZJ2H7mncZrD/RtKgShwEmn8CTappx9iILVGkyRTbliWKxfr5EaEY0yXpDN8aj5N4pgGWg8O
+Qh9axIRFuTxhZ4jIDMEI6VUT0ugBn1rfBbaqWfmM3IfQZsQQsidARCISyajzjEDaiB0wRRCSuoyU
+FJdkCttHj8M85VvsRDN9YQa2ilBDfSjaJT8SQsvmMP8fpohnalGZsADBSTCZp1s6m5vgPErSCmY3
+w347fK3UtnDhtpxy6KvtiosJq2YLszC16O2KaiwvDoOteJSTv3aJfMXuZWF0QCBwN2pPhyPCnQZq
+sUe7YlnaihKqzAj+jyaWRI48HJY3y94zeEESXuY4Y1fgrWfsEuO7oHcqTvy0O10otPOnG5etIvNL
+uFBmYYL3Ag9HNKYHwl1d/lqrh7a3dHi8IuREQ1vY74sFbhefzDsZs4Foz0m60oJY2BeNl1BPtFKW
+yVrwIMKAlLovx5+sH/HvVtchabl0RPlNtYJNEUDVnp40OLE4B7fDQaNOY3hQJErCsE+ffhHMqy0k
+bLVM73XKBhS4GypIBx+GSZauuOXmxBKJCz/00ZUXfeRDqjSUe901eip9fILUmFObBlohbE02xt15
+8b0m+tHgj3aNvF5RkTnendRGh3D+O8hBWz9+AHSpIsXxemuWJ+VQgIeMOERwD+62zkEqLgOsn1pB
+3ZmN3pUl8mIWNDrdC7nGLU6YJt4PNVFRYtJIhuo8fN3I/Fk0CMCwZhZMsP8UcEH9GJOBK5/MtCds
+ZBMUE/UJsjlGCzcq/7OVTDA9MCEwCQYFKw4DAhoFAAQUPQnz3GvfsIzh1/29KwCg+E8LeVAEFMmb
+qHeo0noP26ViWalg3FeT8Lk+AgIEAA==
diff --git a/test/java/security/KeyStore/PKCS12/ie_self.pfx.pem b/test/java/security/KeyStore/PKCS12/ie_self.pfx.pem
new file mode 100644
index 0000000..b877893
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/ie_self.pfx.pem
@@ -0,0 +1,15 @@
+-----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-----
diff --git a/test/java/security/KeyStore/PKCS12/mozilla_self.p12.data b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.data
new file mode 100644
index 0000000..03ef955
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.data
@@ -0,0 +1,31 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/mozilla_self.p12.pem b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.pem
new file mode 100644
index 0000000..fb0c5d1
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/mozilla_self.p12.pem
@@ -0,0 +1,15 @@
+-----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-----
diff --git a/test/java/security/KeyStore/PKCS12/netscape_self.p12.data b/test/java/security/KeyStore/PKCS12/netscape_self.p12.data
new file mode 100644
index 0000000..5c4a0b0
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/netscape_self.p12.data
@@ -0,0 +1,31 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/netscape_self.p12.pem b/test/java/security/KeyStore/PKCS12/netscape_self.p12.pem
new file mode 100644
index 0000000..cd303ff
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/netscape_self.p12.pem
@@ -0,0 +1,16 @@
+-----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-----
+
diff --git a/test/java/security/KeyStore/PKCS12/openssl.p12.data b/test/java/security/KeyStore/PKCS12/openssl.p12.data
new file mode 100644
index 0000000..b4da479
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/openssl.p12.data
@@ -0,0 +1,76 @@
+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
diff --git a/test/java/security/KeyStore/PKCS12/openssl.p12.pem b/test/java/security/KeyStore/PKCS12/openssl.p12.pem
new file mode 100644
index 0000000..0243a37
--- /dev/null
+++ b/test/java/security/KeyStore/PKCS12/openssl.p12.pem
@@ -0,0 +1,22 @@
+-----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-----
diff --git a/test/java/security/MessageDigest/TestDigestIOStream.java b/test/java/security/MessageDigest/TestDigestIOStream.java
new file mode 100644
index 0000000..46028e8
--- /dev/null
+++ b/test/java/security/MessageDigest/TestDigestIOStream.java
@@ -0,0 +1,335 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/test/java/security/Policy/SignedJar/SignedJarTest.java b/test/java/security/Policy/SignedJar/SignedJarTest.java
new file mode 100644
index 0000000..715a96c
--- /dev/null
+++ b/test/java/security/Policy/SignedJar/SignedJarTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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);
+ }
+
+ }
+
+}
diff --git a/test/java/security/Policy/SignedJar/SignedJarTest_1.policy b/test/java/security/Policy/SignedJar/SignedJarTest_1.policy
new file mode 100644
index 0000000..6094fe5
--- /dev/null
+++ b/test/java/security/Policy/SignedJar/SignedJarTest_1.policy
@@ -0,0 +1,10 @@
+keystore "file:both.jks";
+keystorePasswordURL "file:keypass";
+
+grant signedBy "first" {
+ permission java.lang.RuntimePermission "setIO";
+};
+
+grant signedBy "second" {
+ permission java.lang.RuntimePermission "setFactory";
+};
diff --git a/test/java/security/Policy/SignedJar/SignedJarTest_2.policy b/test/java/security/Policy/SignedJar/SignedJarTest_2.policy
new file mode 100644
index 0000000..596dd38
--- /dev/null
+++ b/test/java/security/Policy/SignedJar/SignedJarTest_2.policy
@@ -0,0 +1,11 @@
+keystore "file:first.jks";
+keystorePasswordURL "file:keypass";
+
+grant signedBy "first" {
+ permission java.lang.RuntimePermission "setIO";
+};
+
+grant signedBy "second" {
+ permission java.lang.RuntimePermission "setFactory";
+};
+
diff --git a/test/java/security/Policy/SignedJar/keypass b/test/java/security/Policy/SignedJar/keypass
new file mode 100644
index 0000000..f3097ab
--- /dev/null
+++ b/test/java/security/Policy/SignedJar/keypass
@@ -0,0 +1 @@
+password
diff --git a/test/java/security/SecureRandom/DefaultProvider.java b/test/java/security/SecureRandom/DefaultProvider.java
new file mode 100644
index 0000000..50b4719
--- /dev/null
+++ b/test/java/security/SecureRandom/DefaultProvider.java
@@ -0,0 +1,110 @@
+/*
+ * 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 java.lang.System.out;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * @test
+ * @bug 8048356
+ * @summary Assert default provider used on all OS for SecureRandom
+ */
+public class DefaultProvider {
+
+ private static final String OS_NAME = System.getProperty("os.name");
+ private static final String SUNOS = "SunOS";
+ private static final String WINDOWS = "Windows";
+
+ public static void main(String[] args) throws NoSuchAlgorithmException {
+ out.println("Operating System: " + OS_NAME);
+
+ /* Test default provider used with constructor */
+ out.println("TEST: Default provider with constructor");
+ SecureRandom secureRandom = new SecureRandom();
+ String provider = secureRandom.getProvider().getName();
+ if (OS_NAME.startsWith(SUNOS)) {
+ if (!provider.startsWith("SunPKCS11-")) {
+ throw new RuntimeException("Unexpected provider name: "
+ + provider);
+ }
+ } else if (!provider.equals("SUN")) {
+ throw new RuntimeException("Unexpected provider name: "
+ + provider);
+ }
+ out.println("Passed, default provider with constructor: " + provider);
+
+ /* Test default provider with getInstance(String algorithm) */
+ out.println("TEST: SHA1PRNG supported on all platforms by SUN provider");
+ String algorithm = "SHA1PRNG";
+ provider = "SUN";
+
+ SecureRandom instance = SecureRandom.getInstance(algorithm);
+ assertInstance(instance, algorithm, provider);
+ out.println("Passed.");
+
+ if (!OS_NAME.startsWith(WINDOWS)) {
+ out.println("TEST: NativePRNG supported on all platforms"
+ + "(except Windows), by SUN provider");
+ algorithm = "NativePRNG";
+ provider = "SUN";
+ } else {
+ out.println(
+ "TEST: Windows-PRNG supported on windows by SunMSCAPI provider");
+ algorithm = "Windows-PRNG";
+ provider = "SunMSCAPI";
+ }
+ instance = SecureRandom.getInstance(algorithm);
+ assertInstance(instance, algorithm, provider);
+ out.println("Passed.");
+
+ if (OS_NAME.startsWith(SUNOS)) {
+ out.println(
+ "TEST: PKCS11 is supported on Solaris by SunPKCS11 provider");
+ algorithm = "PKCS11";
+ provider = "SunPKCS11-Solaris";
+ instance = SecureRandom.getInstance(algorithm);
+ assertInstance(instance, algorithm, provider);
+ out.println("Passed.");
+ }
+ }
+
+ private static void assertInstance(SecureRandom instance,
+ String expectedAlgorithm,
+ String expectedProvider) {
+ if (instance != null) {
+ if (!expectedAlgorithm.equalsIgnoreCase(instance.getAlgorithm())) {
+ throw new RuntimeException("Expected algorithm:"
+ + expectedAlgorithm + " actual: " + instance.getAlgorithm());
+ }
+
+ if (!expectedProvider.equalsIgnoreCase(instance.getProvider().getName())) {
+ throw new RuntimeException("Expected provider: "
+ + expectedProvider + " actual: "
+ + instance.getProvider().getName());
+ }
+ } else {
+ throw new RuntimeException("Secure instance is not created");
+ }
+ }
+}
diff --git a/test/java/text/Format/DateFormat/Bug8141243.java b/test/java/text/Format/DateFormat/Bug8141243.java
new file mode 100644
index 0000000..8d156b1
--- /dev/null
+++ b/test/java/text/Format/DateFormat/Bug8141243.java
@@ -0,0 +1,83 @@
+/*
+ * 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 8141243
+ * @summary Make sure that SimpleDateFormat parses "UTC" as the UTC time zone.
+ * @run main Bug8141243
+ */
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+import static java.util.TimeZone.*;
+
+public class Bug8141243 {
+ public static void main(String[] args) {
+ TimeZone UTC = TimeZone.getTimeZone("UTC");
+ TimeZone initTz = TimeZone.getDefault();
+
+ List<String> errors = new ArrayList<>();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+ for (Locale locale : DateFormat.getAvailableLocales()) {
+ // exclude any locales which localize "UTC".
+ String utc = UTC.getDisplayName(false, SHORT, locale);
+ if (!"UTC".equals(utc)) {
+ System.out.println("Skipping " + locale + " due to localized UTC name: " + utc);
+ continue;
+ }
+ SimpleDateFormat fmt = new SimpleDateFormat("z", locale);
+ try {
+ Date date = fmt.parse("UTC");
+ // Parsed one may not exactly be UTC. Universal, UCT, etc. are equivalents.
+ if (!fmt.getTimeZone().getID().matches("(Etc/)?(UTC|Universal|UCT|Zulu)")) {
+ errors.add("timezone: " + fmt.getTimeZone().getID()
+ + ", locale: " + locale);
+ }
+ } catch (ParseException e) {
+ errors.add("parse exception: " + e + ", locale: " + locale);
+ }
+ }
+ } finally {
+ // Restore the default time zone
+ TimeZone.setDefault(initTz);
+ }
+
+ if (!errors.isEmpty()) {
+ System.out.println("Got unexpected results:");
+ for (String s : errors) {
+ System.out.println(" " + s);
+ }
+ throw new RuntimeException("Test failed.");
+ } else {
+ System.out.println("Test passed.");
+ }
+ }
+}
diff --git a/test/java/util/logging/LogManagerAppContextDeadlock.java b/test/java/util/logging/LogManagerAppContextDeadlock.java
index 3e4918e..bb6c471 100644
--- a/test/java/util/logging/LogManagerAppContextDeadlock.java
+++ b/test/java/util/logging/LogManagerAppContextDeadlock.java
@@ -136,6 +136,7 @@
t1.setDaemon(true);
t1.start();
Thread t2 = new Thread() {
+ public Object logger;
public void run() {
sem3.release();
try {
@@ -146,7 +147,10 @@
Thread.interrupted();
}
System.out.println("Logger.getLogger(name).info(name)");
- Logger.getLogger(test.name());//.info(name);
+ // stick the logger in an instance variable to prevent it
+ // from being garbage collected before the main thread
+ // calls LogManager.getLogger() below.
+ logger = Logger.getLogger(test.name());//.info(name);
System.out.println("Done: Logger.getLogger(name).info(name)");
}
};
diff --git a/test/javax/crypto/KeyGenerator/TestKGParity.java b/test/javax/crypto/KeyGenerator/TestKGParity.java
new file mode 100644
index 0000000..0f4c8a5
--- /dev/null
+++ b/test/javax/crypto/KeyGenerator/TestKGParity.java
@@ -0,0 +1,122 @@
+/*
+ * 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.PrintStream;
+import java.lang.String;
+import java.lang.System;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import javax.crypto.KeyGenerator;
+import static java.lang.System.out;
+
+/*
+ * @test
+ * @bug 8048607
+ * @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java
+ * @run main TestKGParity
+ * @summary Test key generation of DES and DESEDE
+ */
+public class TestKGParity {
+
+ private static final String[] ALGORITHM_ARR = {
+ "deS", "DesEDE"
+ };
+
+ public static void main(String argv[]) throws Exception {
+
+ TestKGParity test = new TestKGParity();
+ test.run();
+ }
+
+ private void run() throws Exception {
+ Provider[] providers = Security.getProviders();
+ for (Provider p : providers) {
+ String prvName = p.getName();
+ if (prvName.startsWith("SunJCE")
+ || prvName.startsWith("SunPKCS11-")) {
+ for (String algorithm : ALGORITHM_ARR) {
+ if (!runTest(p, algorithm)) {
+ throw new RuntimeException(
+ "Test failed with provider/algorithm:"
+ + p.getName() + "/" + algorithm);
+ } else {
+ out.println("Test passed with provider/algorithm:"
+ + p.getName() + "/" + algorithm);
+ }
+ }
+ }
+ }
+ }
+
+ public boolean runTest(Provider p, String algo) throws Exception {
+ byte[] keyValue = null;
+ try {
+ // Initialization
+ SecureRandom sRdm = new SecureRandom();
+ KeyGenerator kg = KeyGenerator.getInstance(algo, p);
+ kg.init(sRdm);
+
+ // Generate a SecretKey and retrieve its value
+ keyValue = kg.generateKey().getEncoded();
+
+ // Verify its parity in the unit of byte
+ for (int i = 0; i < keyValue.length; i++) {
+ if (!checkParity(keyValue[i])) {
+ out.println("Testing: "
+ + p.getName()
+ + "/"
+ + algo
+ + " failed when verify its parity in the unit of byte:"
+ + TestUtility.hexDump(keyValue, i));
+ return false;
+ }
+ }
+ return true;
+ } catch (Exception ex) {
+ out.println("Testing: " + p.getName() + "/" + algo
+ + " failed with unexpected exception");
+ ex.printStackTrace();
+ throw ex;
+ }
+ }
+
+ private boolean checkParity(byte keyByte) {
+ boolean even = false;
+ byte[] PARITY_BIT_MASK = {
+ (byte) 0x40, (byte) 0x20, (byte) 0x10, (byte) 0x08,
+ (byte) 0x04, (byte) 0x02, (byte) 0x01
+ };
+
+ for (int i = 0; i < 7; i++) {
+ if ((keyByte & PARITY_BIT_MASK[i]) > 0) {
+ even = !even;
+ }
+ }
+ if (keyByte < 0) {
+ even = !even;
+ }
+
+ return even;
+ }
+}
diff --git a/test/javax/crypto/SealedObject/TestSealedObjectNull.java b/test/javax/crypto/SealedObject/TestSealedObjectNull.java
new file mode 100644
index 0000000..4b6eff2
--- /dev/null
+++ b/test/javax/crypto/SealedObject/TestSealedObjectNull.java
@@ -0,0 +1,57 @@
+/*
+ * 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.");
+ }
+}
diff --git a/test/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java b/test/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java
new file mode 100644
index 0000000..acd2081
--- /dev/null
+++ b/test/javax/crypto/SecretKeyFactory/PBKDF2TranslateTest.java
@@ -0,0 +1,270 @@
+/*
+ * 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
diff --git a/test/javax/crypto/SecretKeyFactory/SecKFTranslateTest.java b/test/javax/crypto/SecretKeyFactory/SecKFTranslateTest.java
new file mode 100644
index 0000000..f1b5c82
--- /dev/null
+++ b/test/javax/crypto/SecretKeyFactory/SecKFTranslateTest.java
@@ -0,0 +1,206 @@
+/*
+ * 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;
+}
diff --git a/test/javax/net/ssl/TLS/CipherTestUtils.java b/test/javax/net/ssl/TLS/CipherTestUtils.java
new file mode 100644
index 0000000..3b6664b
--- /dev/null
+++ b/test/javax/net/ssl/TLS/CipherTestUtils.java
@@ -0,0 +1,689 @@
+/**
+ * Copyright (c) 2010, 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.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+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.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Test that all ciphersuites work in all versions and all client authentication
+ * types. The way this is setup the server is stateless and all checking is done
+ * on the client side.
+ */
+
+public class CipherTestUtils {
+
+ public static final int TIMEOUT = 20 * 1000;
+ public static final SecureRandom secureRandom = new SecureRandom();
+ public static char[] PASSWORD = "passphrase".toCharArray();
+ private static final List<TestParameters> TESTS = new ArrayList<>(3);
+ private static final List<Exception> EXCEPTIONS
+ = Collections.synchronizedList(new ArrayList<>(1));
+ private static final String CLIENT_PUBLIC_KEY
+ = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICtTCCAh4CCQDkYJ46DMcGRjANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n"
+ + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n"
+ + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n"
+ + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n"
+ + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n"
+ + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n"
+ + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n"
+ + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IENsaWVudCAoMTAyNCBiaXQg\n"
+ + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAm5rwjmhO7Nwd5GWs+KvQ\n"
+ + "UnDiqpRDvRriOUFdF0rCI2Op24C+iwUMDGxPsgP7VkUpOdJhw3c72aP0CAWcZ5dN\n"
+ + "UCW7WVDAxnogCahLCir1jjoGdEjiNGOy0L9sypsM9UvBzJN8uvXsxsTZX4Z88cKU\n"
+ + "G7RUvN8LQ88zDljk5zr3c2MCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA7LUDrzHln\n"
+ + "EXuGmwZeeroACB6DVtkClMskF/Pj5GnTxoeNN9DggycX/eOeIDKRloHuMpBeZPJH\n"
+ + "NUwFu4LB6HBDeldQD9iRp8zD/fPakOdN+1Gk5hciIZZJ5hQmeCl7Va2Gr64vUqZG\n"
+ + "MkVU755t+7ByLgzWuhPhhsX9QCuPR5FjvQ==\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CLIENT_PRIVATE_KEY
+ = "-----BEGIN PRIVATE KEY-----\n"
+ + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJua8I5oTuzcHeRl\n"
+ + "rPir0FJw4qqUQ70a4jlBXRdKwiNjqduAvosFDAxsT7ID+1ZFKTnSYcN3O9mj9AgF\n"
+ + "nGeXTVAlu1lQwMZ6IAmoSwoq9Y46BnRI4jRjstC/bMqbDPVLwcyTfLr17MbE2V+G\n"
+ + "fPHClBu0VLzfC0PPMw5Y5Oc693NjAgMBAAECgYA5w73zj8Nk6J3sMNaShe3S/PcY\n"
+ + "TewLopRCnwI46FbDnnbq9pNFtnzvi7HWKuY983THc1M5peTA+b1Y0QRr7F4Vg4x9\n"
+ + "9UM0B/tZcIIcJJ3LS+9fXKCbYLQWq5F05JqeZu+i+QLmJFO5+2p7laeQ4oQfW7QE\n"
+ + "YR4u2mSaLe0SsqHvOQJBAMhgcye9C6pJO0eo2/VtRxAXI7zxNAIjHwKo1cva7bhu\n"
+ + "GdrMaEAJBAsMJ1GEk7/WDI+3KEbTjQdfIJuAvOR4FXUCQQDGzNn/tl2k93v/ugyM\n"
+ + "/tBhCKDipYDIbyJMoG2AOtOGmCsiGo5L7idO4OAcm/QiHBQMXjFIVgTUcH8MhGj4\n"
+ + "blJ3AkA5fUqsxRV6tuYWKkFpif/QgwMS65VDY7Y6+hvVECwSNSyf1PO4I54QWV1S\n"
+ + "ixok+RHDjgY1Q+77hXSCiQ4o8rcdAkBHvjfR+5sx5IpgUGElJPRIgFenU3j1XH3x\n"
+ + "T1gVFaWuhg3S4eiGaGzRH4BhcrqY8K8fg4Kfi0N08yA2gTZsqUujAkEAjuNPTuKx\n"
+ + "ti0LXI09kbGUqOpRMm1zW5TD6LFeEaUN6oxrSZI2YUvu7VyotAqsxX5O0u0f3VQw\n"
+ + "ySF0Q1oZ6qu7cg==\n"
+ + "-----END PRIVATE KEY-----";
+ private static final String SERVER_PUBLIC_KEY
+ = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICtTCCAh4CCQDkYJ46DMcGRTANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n"
+ + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n"
+ + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n"
+ + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n"
+ + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n"
+ + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n"
+ + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n"
+ + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IFNlcnZlciAoMTAyNCBiaXQg\n"
+ + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArsHHeZ1O67yuxQKDSAOC\n"
+ + "Xm271ViwBrXkxe5cvhG8MCCem6Z3XeZ/m6c2ucRwLaQxnmG1m0G6/OYaUXTivjcG\n"
+ + "/K4bc1I+yjghAWQNLBtsOiP9w0LKibg3TSDehpeuuz/lmB5A4HMqQr8KkY4K7peD\n"
+ + "1QkJ2Dn3zhbwQ/0d8f5CCbkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBOd8XojEnu\n"
+ + "eTUHBwqfmnvRQvbICFDNbbL4KuX/JNPSy1WMGAEbNCTLZ+5yP69js8aUYqAk5vVf\n"
+ + "dWRLU3MDiEzW7zxE1ubuKWjVuyGbG8Me0G01Hw+evBcZqB64Fz3OFISVfQh7MqE/\n"
+ + "O0AeakRMH350FRLNl4o6KBSXmF/AADfqQQ==\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String SERVER_PRIVATE_KEY
+ = "-----BEGIN PRIVATE KEY-----\n"
+ + "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK7Bx3mdTuu8rsUC\n"
+ + "g0gDgl5tu9VYsAa15MXuXL4RvDAgnpumd13mf5unNrnEcC2kMZ5htZtBuvzmGlF0\n"
+ + "4r43BvyuG3NSPso4IQFkDSwbbDoj/cNCyom4N00g3oaXrrs/5ZgeQOBzKkK/CpGO\n"
+ + "Cu6Xg9UJCdg5984W8EP9HfH+Qgm5AgMBAAECgYAXUv+3qJo+9mjxHHu/IdDFn6nB\n"
+ + "ONwNmTtWe5DfQWi3l7LznU0zOC9x6+hu9NvwC4kf1XSyqxw04tVCZ/JXZurEmEBz\n"
+ + "YtcQ5idRQDkKYXEDOeVUfvtHO6xilzrhPKxxd0GG/sei2pozikkqnYF3OcP0qL+a\n"
+ + "3nWixZQBRoF2nIRLcQJBAN97TJBr0XTRmE7OCKLUy1+ws7vZB9uQ2efHMsgwOpsY\n"
+ + "3cEW5qd95hrxLU72sBeu9loHQgBrT2Q3OAxnsPXmgO0CQQDIL3u9kS/O3Ukx+n1H\n"
+ + "JdPFQCRxrDm/vtJpQEmq+mLqxxnxCFRIYQ2ieAPokBxWeMDtdWJGD3VxhahjPfZm\n"
+ + "5K59AkEAuDVl0tVMfUIWjT5/F9jXGjUIsZofQ/iN5OLpFOHMLPO+Nd6umPjJpwON\n"
+ + "GT11wM/S+DprSPUrJ6vsYy1FTCuHsQJBAMXtnO07xgdE6AAQaRmVnyMiXmY+IQMj\n"
+ + "CyuhsrToyDDWFyIoWB0QSMjg3QxuoHYnAqpGK5qV4ksSGgG13BCz/okCQQCRHTgn\n"
+ + "DuFG2f7GYLFjI4NaTEzHGp+J9LiNYY1kYYLonpwAC3Z5hzJVanYT3/g23AUZ/fdF\n"
+ + "v5PDIViuPo5ZB1eD\n"
+ + "-----END PRIVATE KEY-----";
+
+ private static final String CA_PUBLIC_KEY
+ = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIDCDCCAnGgAwIBAgIJAIYlGfwNBY6NMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD\n"
+ + "VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAd\n"
+ + "BgNVBAoMFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNy\n"
+ + "b3N5c3RlbXMgTGFib3JhdG9yaWVzMR8wHQYDVQQDDBZUZXN0IENBICgxMDI0IGJp\n"
+ + "dCBSU0EpMB4XDTA5MDQyNzA0MDQwOFoXDTEzMDYwNTA0MDQwOFowgZwxCzAJBgNV\n"
+ + "BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEfMB0G\n"
+ + "A1UECgwWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEmMCQGA1UECwwdU3VuIE1pY3Jv\n"
+ + "c3lzdGVtcyBMYWJvcmF0b3JpZXMxHzAdBgNVBAMMFlRlc3QgQ0EgKDEwMjQgYml0\n"
+ + "IFJTQSkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOK4DJxxb0XX6MJ1CVjp\n"
+ + "9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+gdcOA\n"
+ + "GRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4z1q8\n"
+ + "LYbxyMVD1XNNNymvPM44OjsBAgMBAAGjUDBOMB0GA1UdDgQWBBT27BLUflmfdtbi\n"
+ + "WTgjwWnoxop2MTAfBgNVHSMEGDAWgBT27BLUflmfdtbiWTgjwWnoxop2MTAMBgNV\n"
+ + "HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAEQELNzhZpjnSgigd+QJ6I/3CPDo\n"
+ + "SDkMLdP1BHlT/DkMIZvABm+M09ePNlWiLYCNCsL9nWmX0gw0rFDKsTklZyKTUzaM\n"
+ + "oy/AZCrAaoIc6SO5m1xE1RMyVxd/Y/kg6cbfWxxCJFlMeU5rsSdC97HTE/lDyuoh\n"
+ + "BmlOBB7SdR+1ScjA\n"
+ + "-----END CERTIFICATE-----";
+
+ private static final String CA_PRIVATE_KEY
+ = "-----BEGIN PRIVATE KEY-----\n"
+ + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOK4DJxxb0XX6MJ1\n"
+ + "CVjp9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+g\n"
+ + "dcOAGRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4\n"
+ + "z1q8LYbxyMVD1XNNNymvPM44OjsBAgMBAAECgYEApmMOlk3FrQtsvjGof4GLp3Xa\n"
+ + "tmvs54FzxKhagj0C4UHelNyYpAJ9MLjNiGQ7I31yTeaNrUCAi0XSfsKTSrwbLSnJ\n"
+ + "qsUPKMBrnzcWrOyui2+cupHZXaTlNeYB97teLJYpa6Ql9CZLoTHoim1+//s7diBh\n"
+ + "03Vls+M6Poi5PMvv59UCQQD+k/BiokmbBgWHfBY5cZSlx3Z4VTwSHJmHDTO3Tjso\n"
+ + "EVErXUSVvqD/KHX6eM4VPM8lySV5djWV8lDsESCWMtiLAkEA4/xFNsiOLMQpxW/O\n"
+ + "bt2tukxJkAxldD4lPoFZR+zbXtMtt8OjERtX2wD+nj6h7jfIeSyVuBEcBN8Uj8xe\n"
+ + "kgfgIwJAPbKG4LCqHAsCjgpRrIxNVTwZByLJEy6hOqzFathn19cSj+rjs1Lm28/n\n"
+ + "f9OFRnpdTbAJB/3REM0QNZYVCrG57wJBAN0KuTytZJNouaswhPCew5Kt5mDgc/kp\n"
+ + "S8j3dk2zCto8W8Ygy1iJrzuqEjPxO+UQdrFtlde51vWuKGxnVIW3VwsCQEldqk7r\n"
+ + "8y7PgquPP+k3L0OXno5wGBrPcW1+U0mhIZGnwSzE4SPX2ddqUSEUA/Av4RjAckL/\n"
+ + "fpqmCkpTanyYW9U=\n"
+ + "-----END PRIVATE KEY-----";
+
+ private final SSLSocketFactory factory;
+ private final X509ExtendedKeyManager clientKeyManager;
+ private final X509ExtendedKeyManager serverKeyManager;
+ private final X509TrustManager clientTrustManager;
+ private final X509TrustManager serverTrustManager;
+
+ static abstract class Server implements Runnable {
+
+ final CipherTestUtils cipherTest;
+
+ Server(CipherTestUtils cipherTest) throws Exception {
+ this.cipherTest = cipherTest;
+ }
+
+ @Override
+ public abstract void run();
+
+ void handleRequest(InputStream in, OutputStream out)
+ throws IOException {
+ boolean newline = false;
+ StringBuilder sb = new StringBuilder();
+ while (true) {
+ int ch = in.read();
+ if (ch < 0) {
+ throw new EOFException();
+ }
+ sb.append((char) ch);
+ if (ch == '\r') {
+ // empty
+ } else if (ch == '\n') {
+ if (newline) {
+ // 2nd newline in a row, end of request
+ break;
+ }
+ newline = true;
+ } else {
+ newline = false;
+ }
+ }
+ String request = sb.toString();
+ if (request.startsWith("GET / HTTP/1.") == false) {
+ throw new IOException("Invalid request: " + request);
+ }
+ out.write("HTTP/1.0 200 OK\r\n\r\n".getBytes());
+ out.write("Tested Scenario: ".getBytes());
+ TestParameters tp = (TestParameters) CipherTestUtils.TESTS.get(0);
+ out.write(tp.toString().getBytes());
+ out.write(" Test PASSED.".getBytes());
+ }
+ }
+
+ public static class TestParameters {
+
+ String cipherSuite;
+ String protocol;
+ String clientAuth;
+
+ TestParameters(String cipherSuite, String protocol,
+ String clientAuth) {
+ this.cipherSuite = cipherSuite;
+ this.protocol = protocol;
+ this.clientAuth = clientAuth;
+ }
+
+ boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ String s = cipherSuite + " in " + protocol + " mode";
+ if (clientAuth != null) {
+ s += " with " + clientAuth + " client authentication";
+ }
+ return s;
+ }
+ }
+
+ private static volatile CipherTestUtils instance = null;
+
+ public static CipherTestUtils getInstance() throws IOException,
+ FileNotFoundException, KeyStoreException,
+ NoSuchAlgorithmException, CertificateException,
+ UnrecoverableKeyException, InvalidKeySpecException {
+ if (instance == null) {
+ synchronized (CipherTestUtils.class) {
+ if (instance == null) {
+ instance = new CipherTestUtils();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public static void setTestedArguments(String testedProtocol,
+ String testedCipherSuite) {
+
+ TestParameters testedParams;
+
+ String cipherSuite = testedCipherSuite.trim();
+ if (cipherSuite.startsWith("SSL_")) {
+ testedParams =
+ new TestParameters(cipherSuite, testedProtocol, null);
+ TESTS.add(testedParams);
+
+ } else {
+ System.out.println("Your input Cipher suites is not correct, "
+ + "please try another one .");
+ }
+ }
+
+ public X509ExtendedKeyManager getClientKeyManager() {
+ return clientKeyManager;
+ }
+
+ public X509TrustManager getClientTrustManager() {
+ return clientTrustManager;
+ }
+
+ public X509ExtendedKeyManager getServerKeyManager() {
+ return serverKeyManager;
+ }
+
+ public X509TrustManager getServerTrustManager() {
+ return serverTrustManager;
+ }
+
+ public static void addFailure(Exception e) {
+ EXCEPTIONS.add(e);
+ }
+
+ private CipherTestUtils()
+ throws IOException, FileNotFoundException, KeyStoreException,
+ NoSuchAlgorithmException, CertificateException,
+ UnrecoverableKeyException, InvalidKeySpecException {
+ factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ KeyStore serverKeyStore = createServerKeyStore(SERVER_PUBLIC_KEY,
+ SERVER_PRIVATE_KEY);
+ KeyStore serverTrustStore = createServerKeyStore(CA_PUBLIC_KEY,
+ CA_PRIVATE_KEY);
+
+ if (serverKeyStore != null) {
+ KeyManagerFactory keyFactory1
+ = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ keyFactory1.init(serverKeyStore, PASSWORD);
+ serverKeyManager = (X509ExtendedKeyManager) keyFactory1.
+ getKeyManagers()[0];
+ } else {
+ serverKeyManager = null;
+ }
+ serverTrustManager = serverTrustStore != null
+ ? new AlwaysTrustManager(serverTrustStore) : null;
+
+ KeyStore clientKeyStore, clientTrustStore;
+ clientTrustStore = serverTrustStore;
+ clientKeyStore =
+ createServerKeyStore(CLIENT_PUBLIC_KEY,CLIENT_PRIVATE_KEY);
+ if (clientKeyStore != null) {
+ KeyManagerFactory keyFactory
+ = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ keyFactory.init(clientKeyStore, PASSWORD);
+ clientKeyManager = (X509ExtendedKeyManager) keyFactory.
+ getKeyManagers()[0];
+ } else {
+ clientKeyManager = null;
+ }
+ clientTrustManager = (clientTrustStore != null)
+ ? new AlwaysTrustManager(clientTrustStore) : null;
+ }
+
+ void checkResult(String exception) throws Exception {
+ if (EXCEPTIONS.size() >= 1) {
+ Exception actualException = EXCEPTIONS.get(0);
+ if (exception == null) {
+ throw new RuntimeException("FAILED: got unexpected exception: "
+ + actualException);
+ }
+ if (!exception.equals(actualException.getClass().getName())) {
+ throw new RuntimeException("FAILED: got unexpected exception: "
+ + actualException);
+ }
+
+ System.out.println("PASSED: got expected exception: "
+ + actualException);
+ } else {
+ if (exception != null) {
+ throw new RuntimeException("FAILED: " + exception
+ + " was expected");
+ }
+ System.out.println("PASSED");
+ }
+ }
+
+ SSLSocketFactory getFactory() {
+ return factory;
+ }
+
+ static abstract class Client implements Runnable {
+
+ final CipherTestUtils cipherTest;
+ TestParameters testedParams;
+
+ Client(CipherTestUtils cipherTest) throws Exception {
+ this.cipherTest = cipherTest;
+ }
+
+ Client(CipherTestUtils cipherTest,
+ String testedCipherSuite) throws Exception {
+ this.cipherTest = cipherTest;
+ }
+
+ @Override
+ public final void run() {
+
+ TESTS.stream().map((params) -> {
+ if (!params.isEnabled()) {
+ System.out.println("Skipping disabled test " + params);
+ }
+ return params;
+ }).forEach((params) -> {
+ try {
+ runTest(params);
+ System.out.println("Passed " + params);
+ } catch (Exception e) {
+ CipherTestUtils.addFailure(e);
+ System.out.println("** Failed " + params
+ + "**, got exception:");
+ e.printStackTrace(System.err);
+ }
+ });
+ }
+
+ abstract void runTest(TestParameters params) throws Exception;
+
+ void sendRequest(InputStream in, OutputStream out) throws IOException {
+ out.write("GET / HTTP/1.0\r\n\r\n".getBytes());
+ out.flush();
+ StringBuilder sb = new StringBuilder();
+ while (true) {
+ int ch = in.read();
+ if (ch < 0) {
+ break;
+ }
+ sb.append((char) ch);
+ }
+ String response = sb.toString();
+ if (response.startsWith("HTTP/1.0 200 ") == false) {
+ throw new IOException("Invalid response: " + response);
+ } else {
+ System.out.println();
+ System.out.println("--- Response --- ");
+ System.out.println(response);
+ System.out.println("---------------- ");
+ }
+ }
+ }
+
+ public static void printStringArray(String[] stringArray) {
+ System.out.print(stringArray.length + " : ");
+ for (String stringArray1 : stringArray) {
+ System.out.print(stringArray1);
+ System.out.print(",");
+ }
+ System.out.println();
+ }
+
+ public static void printInfo(SSLServerSocket socket) {
+ System.out.println();
+ System.out.println("--- SSL ServerSocket Info ---");
+ System.out.print("SupportedProtocols : ");
+ printStringArray(socket.getSupportedProtocols());
+ System.out.print("SupportedCipherSuites : ");
+ printStringArray(socket.getSupportedCipherSuites());
+ System.out.print("EnabledProtocols : ");
+ printStringArray(socket.getEnabledProtocols());
+ System.out.print("EnabledCipherSuites : ");
+ String[] supportedCipherSuites = socket.getEnabledCipherSuites();
+ Arrays.sort(supportedCipherSuites);
+ printStringArray(supportedCipherSuites);
+ System.out.println("NeedClientAuth : "
+ + socket.getNeedClientAuth());
+ System.out.println("WantClientAuth : "
+ + socket.getWantClientAuth());
+ System.out.println("-----------------------");
+ }
+
+ public static void printInfo(SSLSocket socket) {
+ System.out.println();
+ System.out.println("--- SSL Socket Info ---");
+ System.out.print(" SupportedProtocols : ");
+ printStringArray(socket.getSupportedProtocols());
+ System.out.println(" EnabledProtocols : "
+ + socket.getEnabledProtocols()[0]);
+ System.out.print(" SupportedCipherSuites : ");
+ String[] supportedCipherSuites = socket.getEnabledCipherSuites();
+ Arrays.sort(supportedCipherSuites);
+ printStringArray(supportedCipherSuites);
+ System.out.println(" EnabledCipherSuites : "
+ + socket.getEnabledCipherSuites()[0]);
+ System.out.println(" NeedClientAuth : "
+ + socket.getNeedClientAuth());
+ System.out.println(" WantClientAuth : "
+ + socket.getWantClientAuth());
+ System.out.println("-----------------------");
+ }
+
+ private static KeyStore createServerKeyStore(String publicKeyStr,
+ String keySpecStr) throws KeyStoreException, IOException,
+ NoSuchAlgorithmException, CertificateException,
+ InvalidKeySpecException {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+ if (publicKeyStr == null || keySpecStr == null) {
+ throw new IllegalArgumentException("publicKeyStr or "
+ + "keySpecStr cannot be null");
+ }
+ String strippedPrivateKey = keySpecStr.substring(
+ keySpecStr.indexOf("\n"), keySpecStr.lastIndexOf("\n"));
+
+ // generate the private key.
+ PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+ Base64.getMimeDecoder().decode(strippedPrivateKey));
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ RSAPrivateKey priKey
+ = (RSAPrivateKey) kf.generatePrivate(priKeySpec);
+
+ // generate certificate chain
+ try (InputStream is =
+ new ByteArrayInputStream(publicKeyStr.getBytes())) {
+ // generate certificate from cert string
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ Certificate keyCert = cf.generateCertificate(is);
+ Certificate[] chain = {keyCert};
+ ks.setKeyEntry("TestEntry", priKey, PASSWORD, chain);
+ }
+
+ return ks;
+ }
+
+ public static void main(PeerFactory peerFactory, String mode,
+ String expectedException)
+ throws Exception {
+ long time = System.currentTimeMillis();
+ setTestedArguments(peerFactory.getTestedProtocol(),
+ peerFactory.getTestedCipher());
+
+ System.out.print(
+ " Initializing test '" + peerFactory.getName() + "'...");
+ secureRandom.nextInt();
+
+ CipherTestUtils cipherTest = CipherTestUtils.getInstance();
+ if (mode.equalsIgnoreCase("Server")) { // server mode
+ Thread serverThread = new Thread(peerFactory.newServer(cipherTest),
+ "Server");
+ serverThread.start();
+ } else if (mode.equalsIgnoreCase("Client")) {
+ peerFactory.newClient(cipherTest).run();
+ cipherTest.checkResult(expectedException);
+ JSSEServer.closeServer = true;
+ } else {
+ throw new RuntimeException("unsupported mode");
+ }
+ time = System.currentTimeMillis() - time;
+ System.out.println("Elapsed time " + time);
+
+ }
+
+ public static abstract class PeerFactory {
+
+ abstract String getName();
+
+ abstract String getTestedProtocol();
+
+ abstract String getTestedCipher();
+
+ abstract Client newClient(CipherTestUtils cipherTest) throws Exception;
+
+ abstract Server newServer(CipherTestUtils cipherTest) throws Exception;
+
+ boolean isSupported(String cipherSuite) {
+ return true;
+ }
+ }
+}
+
+class AlwaysTrustManager implements X509TrustManager {
+
+ X509TrustManager trustManager;
+
+ public AlwaysTrustManager(KeyStore keyStore)
+ throws NoSuchAlgorithmException, KeyStoreException {
+
+ TrustManagerFactory tmf
+ = TrustManagerFactory.getInstance(TrustManagerFactory.
+ getDefaultAlgorithm());
+ tmf.init(keyStore);
+
+ TrustManager tms[] = tmf.getTrustManagers();
+ for (TrustManager tm : tms) {
+ trustManager = (X509TrustManager) tm;
+ return;
+ }
+
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ try {
+ trustManager.checkClientTrusted(chain, authType);
+ } catch (CertificateException excep) {
+ System.out.println("ERROR in client trust manager");
+ }
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ try {
+ trustManager.checkServerTrusted(chain, authType);
+ } catch (CertificateException excep) {
+ System.out.println("ERROR in server Trust manger");
+ }
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return trustManager.getAcceptedIssuers();
+ }
+}
+
+class MyX509KeyManager extends X509ExtendedKeyManager {
+
+ private final X509ExtendedKeyManager keyManager;
+ private String authType;
+
+ MyX509KeyManager(X509ExtendedKeyManager keyManager) {
+ this.keyManager = keyManager;
+ }
+
+ void setAuthType(String authType) {
+ this.authType = "ECDSA".equals(authType) ? "EC" : authType;
+ }
+
+ @Override
+ public String[] getClientAliases(String keyType, Principal[] issuers) {
+ if (authType == null) {
+ return null;
+ }
+ return keyManager.getClientAliases(authType, issuers);
+ }
+
+ @Override
+ public String chooseClientAlias(String[] keyType, Principal[] issuers,
+ Socket socket) {
+ if (authType == null) {
+ return null;
+ }
+ return keyManager.chooseClientAlias(new String[]{authType},
+ issuers, socket);
+ }
+
+ @Override
+ public String chooseEngineClientAlias(String[] keyType,
+ Principal[] issuers, SSLEngine engine) {
+ if (authType == null) {
+ return null;
+ }
+ return keyManager.chooseEngineClientAlias(new String[]{authType},
+ issuers, engine);
+ }
+
+ @Override
+ public String[] getServerAliases(String keyType, Principal[] issuers) {
+ throw new UnsupportedOperationException("Servers not supported");
+ }
+
+ @Override
+ public String chooseServerAlias(String keyType, Principal[] issuers,
+ Socket socket) {
+ throw new UnsupportedOperationException("Servers not supported");
+ }
+
+ @Override
+ public String chooseEngineServerAlias(String keyType, Principal[] issuers,
+ SSLEngine engine) {
+ throw new UnsupportedOperationException("Servers not supported");
+ }
+
+ @Override
+ public X509Certificate[] getCertificateChain(String alias) {
+ return keyManager.getCertificateChain(alias);
+ }
+
+ @Override
+ public PrivateKey getPrivateKey(String alias) {
+ return keyManager.getPrivateKey(alias);
+ }
+}
diff --git a/test/javax/net/ssl/TLS/JSSEClient.java b/test/javax/net/ssl/TLS/JSSEClient.java
new file mode 100644
index 0000000..b08ae91
--- /dev/null
+++ b/test/javax/net/ssl/TLS/JSSEClient.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2010, 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.InputStream;
+import java.io.OutputStream;
+import java.security.cert.Certificate;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+class JSSEClient extends CipherTestUtils.Client {
+
+ private static final String DEFAULT = "DEFAULT";
+ private static final String TLS = "TLS";
+
+ private final SSLContext sslContext;
+ private final MyX509KeyManager keyManager;
+ private final int serverPort;
+ private final String serverHost;
+ private final String testedProtocol;
+
+ JSSEClient(CipherTestUtils cipherTest, String serverHost, int serverPort,
+ String testedProtocols, String testedCipherSuite) throws Exception {
+ super(cipherTest, testedCipherSuite);
+ this.serverHost = serverHost;
+ this.serverPort = serverPort;
+ this.testedProtocol = testedProtocols;
+ this.keyManager =
+ new MyX509KeyManager(cipherTest.getClientKeyManager());
+ sslContext = SSLContext.getInstance(TLS);
+ }
+
+ @Override
+ void runTest(CipherTestUtils.TestParameters params) throws Exception {
+ SSLSocket socket = null;
+ try {
+ System.out.println("Connecting to server...");
+ keyManager.setAuthType(params.clientAuth);
+ sslContext.init(new KeyManager[]{keyManager},
+ new TrustManager[]{cipherTest.getClientTrustManager()},
+ CipherTestUtils.secureRandom);
+ SSLSocketFactory factory = (SSLSocketFactory) sslContext.
+ getSocketFactory();
+ socket = (SSLSocket) factory.createSocket(serverHost,
+ serverPort);
+ socket.setSoTimeout(CipherTestUtils.TIMEOUT);
+ socket.setEnabledCipherSuites(params.cipherSuite.split(","));
+ if (params.protocol != null && !params.protocol.trim().equals("")
+ && !params.protocol.trim().equals(DEFAULT)) {
+ socket.setEnabledProtocols(params.protocol.split(","));
+ }
+ CipherTestUtils.printInfo(socket);
+ InputStream in = socket.getInputStream();
+ OutputStream out = socket.getOutputStream();
+ sendRequest(in, out);
+ SSLSession session = socket.getSession();
+ session.invalidate();
+ String cipherSuite = session.getCipherSuite();
+ if (params.cipherSuite.equals(cipherSuite) == false) {
+ throw new RuntimeException("Negotiated ciphersuite mismatch: "
+ + cipherSuite + " != " + params.cipherSuite);
+ }
+ String protocol = session.getProtocol();
+ if (!DEFAULT.equals(params.protocol)
+ && !params.protocol.contains(protocol)) {
+ throw new RuntimeException("Negotiated protocol mismatch: "
+ + protocol + " != " + params.protocol);
+ }
+ if (!cipherSuite.contains("DH_anon")) {
+ session.getPeerCertificates();
+ }
+ Certificate[] certificates = session.getLocalCertificates();
+ if (params.clientAuth == null) {
+ if (certificates != null) {
+ throw new RuntimeException("Local certificates "
+ + "should be null");
+ }
+ } else {
+ if ((certificates == null) || (certificates.length == 0)) {
+ throw new RuntimeException("Certificates missing");
+ }
+ String keyAlg = certificates[0].getPublicKey().getAlgorithm();
+ if ("EC".equals(keyAlg)) {
+ keyAlg = "ECDSA";
+ }
+ if (params.clientAuth == null ? keyAlg != null
+ : !params.clientAuth.equals(keyAlg)) {
+ throw new RuntimeException("Certificate type mismatch: "
+ + keyAlg + " != " + params.clientAuth);
+ }
+ }
+ } finally {
+ if (socket != null) {
+ socket.close();
+ }
+ }
+ }
+}
diff --git a/test/javax/net/ssl/TLS/JSSEServer.java b/test/javax/net/ssl/TLS/JSSEServer.java
new file mode 100644
index 0000000..f6e55a3
--- /dev/null
+++ b/test/javax/net/ssl/TLS/JSSEServer.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2010, 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+
+public class JSSEServer extends CipherTestUtils.Server {
+
+ private final SSLServerSocket serverSocket;
+ private final int serverPort;
+ static volatile boolean closeServer = false;
+
+ JSSEServer(CipherTestUtils cipherTest, int serverPort,
+ String protocol, String cipherSuite) throws Exception {
+ super(cipherTest);
+ this.serverPort = serverPort;
+ SSLContext serverContext = SSLContext.getInstance("TLS");
+ serverContext.init(new KeyManager[]{cipherTest.getServerKeyManager()},
+ new TrustManager[]{cipherTest.getServerTrustManager()},
+ CipherTestUtils.secureRandom);
+ SSLServerSocketFactory factory =
+ (SSLServerSocketFactory)serverContext.getServerSocketFactory();
+ serverSocket =
+ (SSLServerSocket) factory.createServerSocket(serverPort);
+ serverSocket.setEnabledProtocols(protocol.split(","));
+ serverSocket.setEnabledCipherSuites(cipherSuite.split(","));
+
+ CipherTestUtils.printInfo(serverSocket);
+ }
+
+ @Override
+ public void run() {
+ System.out.println("JSSE Server listening on port " + serverPort);
+ while (!closeServer) {
+ try (final SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+ socket.setSoTimeout(CipherTestUtils.TIMEOUT);
+
+ try (InputStream in = socket.getInputStream();
+ OutputStream out = socket.getOutputStream()) {
+ handleRequest(in, out);
+ out.flush();
+ } catch (IOException e) {
+ CipherTestUtils.addFailure(e);
+ System.out.println("Got IOException:");
+ e.printStackTrace(System.err);
+ }
+ } catch (Exception e) {
+ CipherTestUtils.addFailure(e);
+ System.out.println("Exception:");
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+}
diff --git a/test/javax/net/ssl/TLS/TLSClientPropertyTest.java b/test/javax/net/ssl/TLS/TLSClientPropertyTest.java
new file mode 100644
index 0000000..8d7c1b2
--- /dev/null
+++ b/test/javax/net/ssl/TLS/TLSClientPropertyTest.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2014, 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.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+
+/*
+ * @test
+ * @bug 8049432 8069038
+ * @summary New tests for TLS property jdk.tls.client.protocols
+ * @summary javax/net/ssl/TLS/TLSClientPropertyTest.java needs to be
+ * updated for JDK-8061210
+ * @run main/othervm TLSClientPropertyTest NoProperty
+ * @run main/othervm TLSClientPropertyTest SSLv3
+ * @run main/othervm TLSClientPropertyTest TLSv1
+ * @run main/othervm TLSClientPropertyTest TLSv11
+ * @run main/othervm TLSClientPropertyTest TLSv12
+ * @run main/othervm TLSClientPropertyTest WrongProperty
+ */
+
+/**
+ * Sets the property jdk.tls.client.protocols to one of this protocols:
+ * SSLv3,TLSv1,TLSv1.1,TLSv1.2 and TLSV(invalid) or removes this
+ * property (if any),then validates the default, supported and current
+ * protocols in the SSLContext.
+ */
+public class TLSClientPropertyTest {
+ private final String[] expectedSupportedProtos = new String[] {
+ "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"
+ };
+
+ public static void main(String[] args) throws Exception {
+
+ if (args.length < 1) {
+ throw new RuntimeException(
+ "Incorrect arguments,expected arguments: testCase");
+ }
+
+ String[] expectedDefaultProtos;
+ String testCase = args[0];
+ String contextProtocol;
+ switch (testCase) {
+ case "NoProperty":
+ if (System.getProperty("jdk.tls.client.protocols") != null) {
+ System.getProperties().remove("jdk.tls.client.protocols");
+ }
+ contextProtocol = null;
+ expectedDefaultProtos = new String[] {
+ "TLSv1", "TLSv1.1", "TLSv1.2"
+ };
+ break;
+ case "SSLv3":
+ contextProtocol = "SSLv3";
+ expectedDefaultProtos = new String[] {
+ };
+ break;
+ case "TLSv1":
+ contextProtocol = "TLSv1";
+ expectedDefaultProtos = new String[] {
+ "TLSv1"
+ };
+ break;
+ case "TLSv11":
+ contextProtocol = "TLSv1.1";
+ expectedDefaultProtos = new String[] {
+ "TLSv1", "TLSv1.1"
+ };
+ break;
+ case "TLSv12":
+ contextProtocol = "TLSv1.2";
+ expectedDefaultProtos = new String[] {
+ "TLSv1", "TLSv1.1", "TLSv1.2"
+ };
+ break;
+ case "WrongProperty":
+ expectedDefaultProtos = new String[] {};
+ contextProtocol = "TLSV";
+ break;
+ default:
+ throw new RuntimeException("test case is wrong");
+ }
+ if (contextProtocol != null) {
+ System.setProperty("jdk.tls.client.protocols", contextProtocol);
+ }
+ try {
+ TLSClientPropertyTest test = new TLSClientPropertyTest();
+ test.test(contextProtocol, expectedDefaultProtos);
+ if (testCase.equals("WrongProperty")) {
+ throw new RuntimeException(
+ "Test failed: NoSuchAlgorithmException " +
+ "is expected when input wrong protocol");
+ } else {
+ System.out.println("Test " + contextProtocol + " passed");
+ }
+ } catch (NoSuchAlgorithmException nsae) {
+ if (testCase.equals("WrongProperty")) {
+ System.out.println("NoSuchAlgorithmException is expected,"
+ + contextProtocol + " test passed");
+ } else {
+ throw nsae;
+ }
+ }
+
+ }
+
+ /**
+ * The parameter passed is the user enforced protocol. Does not catch
+ * NoSuchAlgorithmException, WrongProperty test will use it.
+ */
+ public void test(String expectedContextProto,
+ String[] expectedDefaultProtos) throws NoSuchAlgorithmException {
+
+ SSLContext context = null;
+ try {
+ if (expectedContextProto != null) {
+ context = SSLContext.getInstance(expectedContextProto);
+ context.init(null, null, null);
+ } else {
+ context = SSLContext.getDefault();
+ }
+ printContextDetails(context);
+ } catch (KeyManagementException ex) {
+ error(null, ex);
+ }
+
+ validateContext(expectedContextProto, expectedDefaultProtos, context);
+ }
+
+ /**
+ * Simple print utility for SSLContext's protocol details.
+ */
+ private void printContextDetails(SSLContext context) {
+ System.out.println("Default Protocols: "
+ + Arrays.toString(context.getDefaultSSLParameters()
+ .getProtocols()));
+ System.out.println("Supported Protocols: "
+ + Arrays.toString(context.getSupportedSSLParameters()
+ .getProtocols()));
+ System.out.println("Current Protocol : " + context.getProtocol());
+
+ }
+
+ /**
+ * Error handler.
+ */
+ private void error(String msg, Throwable tble) {
+ String finalMsg = "FAILED " + (msg != null ? msg : "");
+ if (tble != null) {
+ throw new RuntimeException(finalMsg, tble);
+ }
+ throw new RuntimeException(finalMsg);
+ }
+
+ /**
+ * Validates the SSLContext's protocols against the user enforced protocol.
+ */
+ private void validateContext(String expectedProto,
+ String[] expectedDefaultProtos, SSLContext context) {
+ if (expectedProto == null) {
+ expectedProto = "Default";
+ }
+ if (!context.getProtocol().equals(expectedProto)) {
+ error("Invalid current protocol: " + context.getProtocol()
+ + ", Expected:" + expectedProto, null);
+ }
+ List<String> actualDefaultProtos = Arrays.asList(context
+ .getDefaultSSLParameters().getProtocols());
+ for (String p : expectedDefaultProtos) {
+ if (!actualDefaultProtos.contains(p)) {
+ error("Default protocol " + p + "missing", null);
+ }
+ }
+ List<String> actualSupportedProtos = Arrays.asList(context
+ .getSupportedSSLParameters().getProtocols());
+
+ for (String p : expectedSupportedProtos) {
+ if (!actualSupportedProtos.contains(p)) {
+ error("Expected to support protocol:" + p, null);
+ }
+ }
+ }
+}
diff --git a/test/javax/net/ssl/TLS/TestJSSE.java b/test/javax/net/ssl/TLS/TestJSSE.java
new file mode 100644
index 0000000..7a776aa
--- /dev/null
+++ b/test/javax/net/ssl/TLS/TestJSSE.java
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2010, 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 static java.lang.System.out;
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * @test
+ * @bug 8049429
+ * @library ../../../../lib/testlibrary/
+ * @build jdk.testlibrary.Utils
+ * @compile CipherTestUtils.java JSSEClient.java JSSEServer.java
+ * @summary Test that all cipher suites work in all versions and all client
+ * authentication types. The way this is setup the server is stateless and
+ * all checking is done on the client side.
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3
+ * -DCLIENT_PROTOCOL=SSLv3
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1
+ * -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1.1
+ * -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1.2
+ * -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1
+ * -DCLIENT_PROTOCOL=TLSv1 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1,TLSv1.1
+ * -DCLIENT_PROTOCOL=TLSv1.1 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3
+ * -DCLIENT_PROTOCOL=TLSv1.1,TLSv1.2
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
+ * TestJSSE javax.net.ssl.SSLHandshakeException
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1
+ * -DCLIENT_PROTOCOL=TLSv1.1,TLSv1.2
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
+ * TestJSSE javax.net.ssl.SSLHandshakeException
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ * -DCLIENT_PROTOCOL=TLSv1.2 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1
+ * -DCLIENT_PROTOCOL=DEFAULT -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ * -DCLIENT_PROTOCOL=DEFAULT -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ * -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1
+ * -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1.2
+ * -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
+ * TestJSSE javax.net.ssl.SSLHandshakeException
+ *
+ */
+
+public class TestJSSE {
+
+ private static final String LOCAL_IP = "127.0.0.1";
+
+ public static void main(String... args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ String serverProtocol = System.getProperty("SERVER_PROTOCOL");
+ String clientProtocol = System.getProperty("CLIENT_PROTOCOL");
+ int port = jdk.testlibrary.Utils.getFreePort();
+ String cipher = System.getProperty("CIPHER");
+ if (serverProtocol == null
+ || clientProtocol == null
+ || cipher == null) {
+ throw new IllegalArgumentException("SERVER_PROTOCOL "
+ + "or CLIENT_PROTOCOL or CIPHER is missing");
+ }
+ out.println("ServerProtocol =" + serverProtocol);
+ out.println("ClientProtocol =" + clientProtocol);
+ out.println("Cipher =" + cipher);
+ server(serverProtocol, cipher, port, args);
+ client(port, clientProtocol, cipher, args);
+
+ }
+
+ public static void client(int testPort,
+ String testProtocols, String testCipher,
+ String... exception) throws Exception {
+ String expectedException = exception.length >= 1
+ ? exception[0] : null;
+ out.println("=========================================");
+ out.println(" Testing - https://" + LOCAL_IP + ":" + testPort);
+ out.println(" Testing - Protocol : " + testProtocols);
+ out.println(" Testing - Cipher : " + testCipher);
+ Provider p = new sun.security.ec.SunEC();
+ Security.insertProviderAt(p, 1);
+ try {
+ CipherTestUtils.main(new JSSEFactory(LOCAL_IP,
+ testPort, testProtocols,
+ testCipher, "client JSSE"),
+ "client", expectedException);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void server(String testProtocol, String testCipher,
+ int testPort,
+ String... exception) throws Exception {
+ String expectedException = exception.length >= 1
+ ? exception[0] : null;
+ out.println(" This is Server");
+ out.println(" Testing Protocol: " + testProtocol);
+ out.println(" Testing Cipher: " + testCipher);
+ out.println(" Testing Port: " + testPort);
+ Provider p = new sun.security.ec.SunEC();
+ Security.insertProviderAt(p, 1);
+ try {
+ CipherTestUtils.main(new JSSEFactory(null, testPort,
+ testProtocol, testCipher, "Server JSSE"),
+ "Server", expectedException);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static class JSSEFactory extends CipherTestUtils.PeerFactory {
+
+ final String testedCipherSuite, testedProtocol, testHost;
+ final int testPort;
+ final String name;
+
+ JSSEFactory(String testHost, int testPort, String testedProtocol,
+ String testedCipherSuite, String name) {
+ this.testedCipherSuite = testedCipherSuite;
+ this.testedProtocol = testedProtocol;
+ this.testHost = testHost;
+ this.testPort = testPort;
+ this.name = name;
+ }
+
+ @Override
+ String getName() {
+ return name;
+ }
+
+ @Override
+ String getTestedCipher() {
+ return testedCipherSuite;
+ }
+
+ @Override
+ String getTestedProtocol() {
+ return testedProtocol;
+ }
+
+ @Override
+ CipherTestUtils.Client newClient(CipherTestUtils cipherTest)
+ throws Exception {
+ return new JSSEClient(cipherTest, testHost, testPort,
+ testedProtocol, testedCipherSuite);
+ }
+
+ @Override
+ CipherTestUtils.Server newServer(CipherTestUtils cipherTest)
+ throws Exception {
+ return new JSSEServer(cipherTest, testPort,
+ testedProtocol, testedCipherSuite);
+ }
+ }
+}
diff --git a/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java b/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java
new file mode 100644
index 0000000..cf5ba47
--- /dev/null
+++ b/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java
@@ -0,0 +1,595 @@
+/*
+ * 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. 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8049321
+ * @summary Support SHA256WithDSA in JSSE
+ * @modules java.base/sun.misc
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256"
+ * TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import javax.net.ssl.*;
+import java.security.Security;
+import java.security.KeyStore;
+import java.security.KeyFactory;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import sun.misc.BASE64Decoder;
+
+
+public class SignatureAlgorithms {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ // Certificates and key (DSA) used in the test.
+ static String trustedCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDYTCCAyGgAwIBAgIJAK8/gw6zg/DPMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+ "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+ "MB4XDTE1MTIwMzEzNTIyNVoXDTM2MTExMjEzNTIyNVowOzELMAkGA1UEBhMCVVMx\n" +
+ "DTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlMIIB\n" +
+ "uDCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG4X+uxu5V\n" +
+ "b3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2eBfUv/hJ\n" +
+ "cLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNAqAB9PO5Y\n" +
+ "zKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAaor8iURd82\n" +
+ "b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I81drnN0Y\n" +
+ "lyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVXW+SEGADC\n" +
+ "J1+z8uqP3lIB6ltdgOiV/GQDgYUAAoGBAOXRppuJSGdt6AiZkb81P1DCUgIUlZFI\n" +
+ "J9GxWrjbbHDmGllMwPNhK6dU7LJKJJuYVPW+95rUGlSJEjRqSlHuyHkNb6e3e7qx\n" +
+ "tmx1/oIyq+oLult50hBS7uBvLLR0JbIKjBzzkudL8Rjze4G/Wq7KDM2T1JOP49tW\n" +
+ "eocCvaC8h8uQo4GtMIGqMB0GA1UdDgQWBBT17HcqLllsqnZzP+kElcGcBGmubjBr\n" +
+ "BgNVHSMEZDBigBT17HcqLllsqnZzP+kElcGcBGmubqE/pD0wOzELMAkGA1UEBhMC\n" +
+ "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+ "ggkArz+DDrOD8M8wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwCQYHKoZI\n" +
+ "zjgEAwMvADAsAhQ6Y1I6LtIEBMqNo8o6GIe4LLEJuwIUbVQUKi8tvtWyRoxm8AFV\n" +
+ "0axJYUU=\n" +
+ "-----END CERTIFICATE-----";
+
+ static String[] targetCertStr = {
+ // DSA-SHA1
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDKTCCAumgAwIBAgIJAOy5c0b+8stFMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+ "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+ "MB4XDTE1MTIwMzEzNTIyNVoXDTM1MDgyMDEzNTIyNVowTzELMAkGA1UEBhMCVVMx\n" +
+ "DTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVzdCBTZXJpdmNlMRIw\n" +
+ "EAYDVQQDDAlsb2NhbGhvc3QwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA8f5v4ZIx\n" +
+ "fopLuNcNF6/NzjrgMUbhf67G7lVvdTjKGxTwDxy4fiDCKfov8gOSZlDs3TMLSNGy\n" +
+ "IZVIywURNOrXQXf2kfZ4F9S/+Elwt8GciMES1WpX90TErzwe6XaxniZCKFDiKyw+\n" +
+ "XuGyuhL0RZiJydfSg0CoAH087ljMpt+kvtMCFQDXdZbjyuWfZQ/8toCC2fMqGpw2\n" +
+ "0wKBgQDdG/QaKtNsBqivyJRF3zZvkWUNN684JO6rtkil9lVXfSd5LtwFg163qb/f\n" +
+ "/hx9SVtuuqFuognYj4jzV2uc3RiXI3gqS7ERwHo5PB9aQhSPqu89oJCsEfxDbXds\n" +
+ "Orcce1g1o/w6h5BTJVdb5IQYAMInX7Py6o/eUgHqW12A6JX8ZAOBhAACgYB+zYqn\n" +
+ "jJwG4GZpBIN/6qhzbp0flChsV+Trlu0SL0agAQzb6XdI/4JnO87Pgbxaxh3VNAj3\n" +
+ "3+Ghr1NLBuBfTKzJ4j9msWT3EpLupkMyNtXvBYM0iyMrll67lSjMdv++wLEw35Af\n" +
+ "/bzVcjGyA5Q0i0cuEzDmHTVfi0OydynbwSLxtKNjMGEwCwYDVR0PBAQDAgPoMB0G\n" +
+ "A1UdDgQWBBQXJI8AxM0qsYCbbkIMuI5zJ+nMEDAfBgNVHSMEGDAWgBT17HcqLlls\n" +
+ "qnZzP+kElcGcBGmubjASBgNVHREBAf8ECDAGhwR/AAABMAkGByqGSM44BAMDLwAw\n" +
+ "LAIUXgyJ0xll4FrZAKXi8bj7Kiz+SA4CFH9WCSZIBYA9lmJkiTgRS7iM/6IC\n" +
+ "-----END CERTIFICATE-----",
+
+ // DSA-SHA224
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDLzCCAuugAwIBAgIJAOy5c0b+8stGMAsGCWCGSAFlAwQDATA7MQswCQYDVQQG\n" +
+ "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+ "Y2UwHhcNMTUxMjAzMTU0NDM5WhcNMzUwODIwMTU0NDM5WjBPMQswCQYDVQQGEwJV\n" +
+ "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+ "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+ "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+ "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+ "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+ "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+ "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+ "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgA81\n" +
+ "CJKEv+pwiqYgxtw/9rkQ9748WP3mKrEC06kjUG+94/Z9dQloNFFfj6LiO1bymc5l\n" +
+ "6QIR8XCi4Po3N80K3+WxhBGFhY+RkVWTh43JV8epb41aH2qiWErarBwBGEh8LyGT\n" +
+ "i30db+Nkz2gfvyz9H/9T0jmYgfLEOlMCusali1qHo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+ "HQYDVR0OBBYEFBqSP0S4+X+zOCTEnlp2hbAjV/W5MB8GA1UdIwQYMBaAFPXsdyou\n" +
+ "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMB\n" +
+ "AzEAMC4CFQChiRaOnAnsCSJFwdpK22jSxU/mhQIVALgLbj/G39+1Ej8UuSWnEQyU\n" +
+ "4DA+\n" +
+ "-----END CERTIFICATE-----",
+
+ // DSA-SHA256
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDLTCCAuugAwIBAgIJAOy5c0b+8stHMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+ "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+ "Y2UwHhcNMTUxMjAzMTU0NjUxWhcNMzUwODIwMTU0NjUxWjBPMQswCQYDVQQGEwJV\n" +
+ "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+ "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+ "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+ "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+ "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+ "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+ "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+ "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgEF7\n" +
+ "2qiYxGrjX4KCOy0k5nK/RYlgLy4gYDChihQpiaa+fbA5JOBOxPWsh7rdtmJuDrEJ\n" +
+ "keacU223+DIhOKC49fa+EvhLNqo6U1oPn8n/yvBsvvnWkcynw5KfNzaLlaPmzugh\n" +
+ "v9xl/GhyZNAXc1QUcW3C+ceHVNrKnkfbTKZz5eRSo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+ "HQYDVR0OBBYEFNMkPrt40oO9Dpy+bcbQdEvOlNlyMB8GA1UdIwQYMBaAFPXsdyou\n" +
+ "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMC\n" +
+ "Ay8AMCwCFCvA2QiKSe/n+6GqSYQwgQ/zL5M9AhQfSiuWdMJKWpgPJKakvzhBUbMb\n" +
+ "vA==\n" +
+ "-----END CERTIFICATE-----"};
+
+ // Private key in the format of PKCS#8, key size is 1024 bits.
+ static String[] targetPrivateKey = {
+ // For cert DSA-SHA1
+ "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+ "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+ "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+ "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+ "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+ "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+ "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOiB7J/lrFrNduQ8nDNTe8VspoAI=",
+
+ // For cert DSA-SHA224
+ "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+ "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+ "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+ "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+ "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+ "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+ "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOj9F5mxWd9W1tiLSdsOAt8BUBzE=",
+
+ // For cert DSA-SHA256
+ "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+ "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+ "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+ "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+ "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+ "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+ "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUQ2WGgg+OO39Aujj0e4lM4pP4/9g="};
+
+
+ static char passphrase[] = "passphrase".toCharArray();
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile boolean serverReady = false;
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+
+ SSLContext context = generateSSLContext(
+ null, targetCertStr, targetPrivateKey);
+ SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+ try (SSLServerSocket sslServerSocket =
+ (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+ sslSocket.setEnabledCipherSuites(
+ sslSocket.getSupportedCipherSuites());
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write('A');
+ sslOS.flush();
+
+ dumpSignatureAlgorithms(sslSocket);
+ }
+ }
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLContext context = generateSSLContext(trustedCertStr, null, null);
+ SSLSocketFactory sslsf = context.getSocketFactory();
+
+ try (SSLSocket sslSocket =
+ (SSLSocket)sslsf.createSocket("localhost", serverPort)) {
+
+ // enable TLSv1.2 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
+
+ // enable a block cipher
+ sslSocket.setEnabledCipherSuites(new String[] {cipherSuite});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+
+ dumpSignatureAlgorithms(sslSocket);
+ }
+ }
+
+ static void dumpSignatureAlgorithms(SSLSocket sslSocket) throws Exception {
+
+ boolean isClient = sslSocket.getUseClientMode();
+ String mode = "[" + (isClient ? "Client" : "Server") + "]";
+ ExtendedSSLSession session =
+ (ExtendedSSLSession)sslSocket.getSession();
+ String[] signAlgs = session.getLocalSupportedSignatureAlgorithms();
+ System.out.println(
+ mode + " local supported signature algorithms: " +
+ Arrays.asList(signAlgs));
+
+ if (!isClient) {
+ signAlgs = session.getPeerSupportedSignatureAlgorithms();
+ System.out.println(
+ mode + " peer supported signature algorithms: " +
+ Arrays.asList(signAlgs));
+ } else {
+ Certificate[] serverCerts = session.getPeerCertificates();
+
+ // server should always send the authentication cert.
+ String sigAlg = ((X509Certificate)serverCerts[0]).getSigAlgName();
+ System.out.println(
+ mode + " the signature algorithm of server certificate: " +
+ sigAlg);
+ if (sigAlg.contains("SHA1")) {
+ if (disabledAlgorithms.contains("SHA-1")) {
+ throw new Exception(
+ "Not the expected server certificate. " +
+ "SHA-1 should be disabled");
+ }
+ } else if (sigAlg.contains("SHA224")) {
+ if (disabledAlgorithms.contains("SHA-224")) {
+ throw new Exception(
+ "Not the expected server certificate. " +
+ "SHA-224 should be disabled");
+ }
+ } else { // SHA-256
+ if (disabledAlgorithms.contains("SHA-256")) {
+ throw new Exception(
+ "Not the expected server certificate. " +
+ "SHA-256 should be disabled");
+ }
+ }
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ private static String tmAlgorithm; // trust manager
+ private static String disabledAlgorithms; // disabled algorithms
+ private static String cipherSuite; // cipher suite
+
+ private static void parseArguments(String[] args) {
+ tmAlgorithm = args[0];
+ disabledAlgorithms = args[1];
+ cipherSuite = args[2];
+ }
+
+ private static SSLContext generateSSLContext(String trustedCertStr,
+ String[] keyCertStrs, String[] keySpecStrs) throws Exception {
+
+ // generate certificate from cert string
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ // create a key store
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+
+ // import the trused cert
+ Certificate trusedCert = null;
+ ByteArrayInputStream is = null;
+ if (trustedCertStr != null) {
+ is = new ByteArrayInputStream(trustedCertStr.getBytes());
+ trusedCert = cf.generateCertificate(is);
+ is.close();
+
+ ks.setCertificateEntry("DSA Signer", trusedCert);
+ }
+
+ if (keyCertStrs != null && keyCertStrs.length != 0) {
+ for (int i = 0; i < keyCertStrs.length; i++) {
+ String keyCertStr = keyCertStrs[i];
+ String keySpecStr = keySpecStrs[i];
+
+ // generate the private key.
+ PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+ new BASE64Decoder().decodeBuffer(keySpecStr));
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPrivateKey priKey =
+ (DSAPrivateKey)kf.generatePrivate(priKeySpec);
+
+ // generate certificate chain
+ is = new ByteArrayInputStream(keyCertStr.getBytes());
+ Certificate keyCert = cf.generateCertificate(is);
+ is.close();
+
+ Certificate[] chain = null;
+ if (trusedCert != null) {
+ chain = new Certificate[2];
+ chain[0] = keyCert;
+ chain[1] = trusedCert;
+ } else {
+ chain = new Certificate[1];
+ chain[0] = keyCert;
+ }
+
+ // import the key entry.
+ ks.setKeyEntry("DSA Entry " + i, priKey, passphrase, chain);
+ }
+ }
+
+ // create SSL context
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
+ tmf.init(ks);
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ if (keyCertStrs != null && keyCertStrs.length != 0) {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
+ kmf.init(ks, passphrase);
+
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ ks = null;
+ } else {
+ ctx.init(null, tmf.getTrustManagers(), null);
+ }
+
+ return ctx;
+ }
+
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ /*
+ * debug option
+ */
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ /*
+ * Get the customized arguments.
+ */
+ parseArguments(args);
+
+
+ /*
+ * Ignore testing on Windows if only SHA-224 is available.
+ */
+ if ((Security.getProvider("SunMSCAPI") != null) &&
+ (disabledAlgorithms.contains("SHA-1")) &&
+ (disabledAlgorithms.contains("SHA-256"))) {
+
+ System.out.println(
+ "Windows system does not support SHA-224 algorithms yet. " +
+ "Ignore the testing");
+
+ return;
+ }
+
+ /*
+ * Expose the target algorithms by diabling unexpected algorithms.
+ */
+ Security.setProperty(
+ "jdk.certpath.disabledAlgorithms", disabledAlgorithms);
+
+ /*
+ * Reset the security property to make sure that the algorithms
+ * and keys used in this test are not disabled by default.
+ */
+ Security.setProperty( "jdk.tls.disabledAlgorithms", "");
+
+ /*
+ * Start the tests.
+ */
+ new SignatureAlgorithms();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SignatureAlgorithms() throws Exception {
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ // swallow for now. Show later
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+ String whichRemote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ whichRemote = "server";
+ } else {
+ remote = clientException;
+ local = serverException;
+ whichRemote = "client";
+ }
+
+ /*
+ * If both failed, return the curthread's exception, but also
+ * print the remote side Exception
+ */
+ if ((local != null) && (remote != null)) {
+ System.out.println(whichRemote + " also threw:");
+ remote.printStackTrace();
+ System.out.println();
+ throw local;
+ }
+
+ if (remote != null) {
+ throw remote;
+ }
+
+ if (local != null) {
+ throw local;
+ }
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died..." + e);
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died..." + e);
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java
new file mode 100644
index 0000000..1a649ea
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASConfigSyntaxTest.java
@@ -0,0 +1,57 @@
+
+/**
+ * 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);
+ }
+ }
+ }
+}
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config
new file mode 100644
index 0000000..6a7219f
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config
@@ -0,0 +1,5 @@
+{
+SampleLoginModule Required;
+SampleLoginModule Required;
+SampleLoginModule Required;
+};
\ No newline at end of file
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config
new file mode 100644
index 0000000..75b6232
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutBraces.config
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest
+SampleLoginModule Required;
+SampleLoginModule Required;
+SampleLoginModule Required;
+;
\ No newline at end of file
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config
new file mode 100644
index 0000000..a3d4b2b
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutFlag.config
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest{
+SampleLoginModule ;
+SampleLoginModule ;
+SampleLoginModule ;
+};
\ No newline at end of file
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config
new file mode 100644
index 0000000..7315d02
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest{
+;
+;
+;
+};
\ No newline at end of file
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config
new file mode 100644
index 0000000..4ccf602
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config
@@ -0,0 +1,5 @@
+JAASConfigSyntaxTest{
+SampleLoginModule Required;
+SampleLoginModule Required
+SampleLoginModule Required;
+};
\ No newline at end of file
diff --git a/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java b/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java
new file mode 100644
index 0000000..7df77b0
--- /dev/null
+++ b/test/javax/security/auth/login/JAASConfigSyntaxCheck/SampleLoginModule.java
@@ -0,0 +1,75 @@
+/**
+ * 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;
+ }
+}
diff --git a/test/javax/security/auth/login/LoginContext/CustomLoginModule.java b/test/javax/security/auth/login/LoginContext/CustomLoginModule.java
new file mode 100644
index 0000000..e47f3de
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/CustomLoginModule.java
@@ -0,0 +1,275 @@
+/*
+ * 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 {}
+}
diff --git a/test/javax/security/auth/login/LoginContext/DummyLoginModule.java b/test/javax/security/auth/login/LoginContext/DummyLoginModule.java
new file mode 100644
index 0000000..ae0334d
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/DummyLoginModule.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+ }
+
+}
diff --git a/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java b/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java
new file mode 100644
index 0000000..c0491bb
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/DynamicConfigurationTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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");
+ }
+ }
+ }
+}
diff --git a/test/javax/security/auth/login/LoginContext/LCTest.jaas.config b/test/javax/security/auth/login/LoginContext/LCTest.jaas.config
new file mode 100644
index 0000000..f63cff5
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/LCTest.jaas.config
@@ -0,0 +1,57 @@
+
+"AbortRequired" {
+ LCTest$LoginModuleAllPass required;
+ LCTest$LoginModuleWithLoginException required;
+ LCTest$LoginModuleAllPass required;
+};
+
+"AbortRequisite" {
+ LCTest$LoginModuleWithLoginException required;
+ LCTest$LoginModuleWithAbortException requisite;
+ LCTest$LoginModuleAllPass required;
+};
+
+"AbortSufficient" {
+ LCTest$LoginModuleWithLoginException required;
+ LCTest$LoginModuleWithLoginException sufficient;
+ LCTest$LoginModuleAllPass required;
+};
+
+"LogoutRequisite" {
+ LCTest$LoginModuleAllPass required;
+ LCTest$LoginModuleWithLogoutException requisite;
+ LCTest$LoginModuleAllPass required;
+};
+
+"LogoutSufficient" {
+ LCTest$LoginModuleAllPass required;
+ LCTest$LoginModuleWithLoginException sufficient;
+ LCTest$LoginModuleAllPass required;
+};
+
+"LogoutRequired" {
+ LCTest$LoginModuleWithLogoutException required;
+ LCTest$LoginModuleWithAbortException required;
+ LCTest$LoginModuleAllPass required;
+};
+
+"LoginRequired" {
+ LCTest$LoginModuleWithLoginException required;
+ LCTest$LoginModuleWithAbortException required;
+ LCTest$LoginModuleAllPass required;
+};
+
+"LoginSufficient" {
+ LCTest$LoginModuleAllPass required;
+ LCTest$LoginModuleWithLoginException sufficient;
+ LCTest$LoginModuleAllPass required;
+};
+
+"LoginRequisite" {
+ LCTest$LoginModuleWithLoginException required;
+ LCTest$LoginModuleWithAbortException requisite;
+ LCTest$LoginModuleAllPass required;
+};
+
+"EmptyModuleConfig" {
+};
diff --git a/test/javax/security/auth/login/LoginContext/LCTest.java b/test/javax/security/auth/login/LoginContext/LCTest.java
new file mode 100644
index 0000000..e5eeb6c
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/LCTest.java
@@ -0,0 +1,337 @@
+/*
+ * 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 com.sun.security.auth.UnixPrincipal;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/*
+ * @test
+ * @bug 8050460
+ * @summary Test checks that proper methods associated with login/logout process
+ * of LoginContext are called for different configurations and circumstances.
+ * @modules jdk.security.auth
+ *
+ * @run main/othervm LCTest EmptyModuleConfig false
+ * @run main/othervm LCTest IncorrectName false
+ * @run main/othervm LCTest AbortRequisite false abort
+ * @run main/othervm LCTest AbortSufficient false abort
+ * @run main/othervm LCTest AbortRequired false abort
+ * @run main/othervm LCTest LogoutRequisite false logout
+ * @run main/othervm LCTest LogoutSufficient true logout
+ * @run main/othervm LCTest LogoutRequired false logout
+ * @run main/othervm LCTest LoginRequisite false login
+ * @run main/othervm LCTest LoginSufficient true login
+ * @run main/othervm LCTest LoginRequired false login
+ */
+
+public class LCTest {
+
+ private static final String USER_NAME = "testUser";
+ private static final String PASSWORD = "testPassword";
+ private static final List<String> loggedActions = new ArrayList<>();
+
+ static {
+ System.setProperty("java.security.auth.login.config",
+ System.getProperty("test.src")
+ + System.getProperty("file.separator")
+ + "LCTest.jaas.config");
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 2) {
+ throw new RuntimeException("Incorrect test params");
+ }
+ String nameOfContext = args[0];
+ boolean isPositive = Boolean.parseBoolean(args[1]);
+ String actionName = null;
+ if (args.length == 3) {
+ actionName = args[2];
+ }
+ try {
+ LoginContext lc = new LoginContext(nameOfContext,
+ new MyCallbackHandler());
+ lc.login();
+ checkPrincipal(lc, true);
+ lc.logout();
+ checkPrincipal(lc, false);
+ if (!isPositive) {
+ throw new RuntimeException("Test failed. Exception expected.");
+ }
+ } catch (LoginException le) {
+ if (isPositive) {
+ throw new RuntimeException("Test failed. Unexpected " +
+ "exception", le);
+ }
+ System.out.println("Expected exception: "
+ + le.getMessage());
+ }
+ checkActions(actionName);
+ System.out.println("Test passed.");
+ }
+
+ /*
+ * Log action from login modules
+ */
+ private static void logAction(String actionName) {
+ loggedActions.add(actionName);
+ }
+
+ /*
+ * Check if logged actions are as expected. We always expected 3 actions
+ * if any.
+ */
+ private static void checkActions(String actionName) {
+ if (actionName == null) {
+ if (loggedActions.size() != 0) {
+ throw new RuntimeException("No logged actions expected");
+ }
+ } else {
+ int loggedActionsFound = 0;
+ System.out.println("Logged actions : " + loggedActions);
+ for (String s : loggedActions) {
+ if (s.equals(actionName)) {
+ loggedActionsFound++;
+ }
+ }
+ if (loggedActionsFound != 3) {
+ throw new RuntimeException("Incorrect number of actions " +
+ actionName + " : " + loggedActionsFound);
+ }
+ }
+ }
+
+ /*
+ * Check context for principal of the test user.
+ */
+ private static void checkPrincipal(LoginContext loginContext, boolean
+ principalShouldExist) {
+ if (!principalShouldExist) {
+ if (loginContext.getSubject().getPrincipals().size() != 0) {
+ throw new RuntimeException("Test failed. Principal was not " +
+ "cleared.");
+ }
+ } else {
+ for (Principal p : loginContext.getSubject().getPrincipals()) {
+ if (p instanceof UnixPrincipal &&
+ USER_NAME.equals(p.getName())) {
+ //Proper principal was found, return.
+ return;
+ }
+ }
+ throw new RuntimeException("Test failed. UnixPrincipal "
+ + USER_NAME + " expected.");
+ }
+ }
+
+ private static class MyCallbackHandler implements CallbackHandler {
+
+ @Override
+ public void handle(Callback[] callbacks) throws IOException,
+ UnsupportedCallbackException {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ ((NameCallback) callback).setName(USER_NAME);
+ } else if (callback instanceof PasswordCallback) {
+ ((PasswordCallback) callback).setPassword(
+ PASSWORD.toCharArray());
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+ }
+
+ /* -------------------------------------------------------------------------
+ * Test login modules
+ * -------------------------------------------------------------------------
+ */
+
+ /*
+ * Login module that should pass through all phases.
+ */
+ public static class LoginModuleAllPass extends LoginModuleBase {
+
+ }
+
+ /*
+ * Login module that throws Exception in abort method.
+ */
+ public static class LoginModuleWithAbortException extends LoginModuleBase {
+
+ @Override
+ public boolean abort() throws LoginException {
+ super.abort();
+ throw new LoginException("Abort failed!");
+ }
+ }
+
+ /*
+ * Login module that throws Exception in login method.
+ */
+ public static class LoginModuleWithLoginException extends LoginModuleBase {
+
+ @Override
+ public boolean login() throws LoginException {
+ super.login();
+ throw new FailedLoginException("Login failed!");
+ }
+ }
+
+ /*
+ * Login module that throws Exception in logout method.
+ */
+ public static class LoginModuleWithLogoutException extends LoginModuleBase {
+
+ @Override
+ public boolean logout() throws LoginException {
+ super.logout();
+ throw new FailedLoginException("Logout failed!");
+ }
+ }
+
+ /*
+ * Base class for login modules
+ */
+ public static abstract class LoginModuleBase implements LoginModule {
+ // initial state
+ private Subject subject;
+ private CallbackHandler callbackHandler;
+ private Map sharedState;
+ private Map options;
+ private UnixPrincipal userPrincipal;
+
+ // username and password
+ private String username;
+ private String password;
+
+ // the authentication status
+ private boolean succeeded = false;
+ private boolean commitSucceeded = false;
+
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
+ Map<String, ?> sharedState, Map<String, ?> options) {
+
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.sharedState = sharedState;
+ this.options = options;
+ System.out.println("Login module initialized.");
+ }
+
+ /*
+ * Authenticate the user by prompting for a username and password.
+ */
+ @Override
+ public boolean login() throws LoginException {
+ LCTest.logAction("login");
+ if (callbackHandler == null) {
+ throw new LoginException("No CallbackHandler available");
+ }
+
+ Callback[] callbacks = new Callback[2];
+ callbacks[0] = new NameCallback("Username: ");
+ callbacks[1] = new PasswordCallback("Password: ", false);
+
+ try {
+ callbackHandler.handle(callbacks);
+ username = ((NameCallback) callbacks[0]).getName();
+ password = new String(((PasswordCallback) callbacks[1])
+ .getPassword());
+ if (username.equals(LCTest.USER_NAME) &&
+ password.equals(LCTest.PASSWORD)) {
+ succeeded = true;
+ return true;
+ }
+ throw new FailedLoginException("Incorrect username/password!");
+ } catch (IOException | UnsupportedCallbackException e) {
+ throw new LoginException("Login failed: " + e.getMessage());
+ }
+ }
+
+ @Override
+ public boolean commit() throws LoginException {
+ LCTest.logAction("commit");
+ if (succeeded == false) {
+ return false;
+ }
+ userPrincipal = new UnixPrincipal(username);
+ final Subject s = subject;
+ final UnixPrincipal up = userPrincipal;
+ java.security.AccessController.doPrivileged
+ ((java.security.PrivilegedAction) () -> {
+ if (!s.getPrincipals().contains(up)) {
+ s.getPrincipals().add(up);
+ }
+ return null;
+ });
+ password = null;
+ commitSucceeded = true;
+ return true;
+ }
+
+ @Override
+ public boolean abort() throws LoginException {
+ LCTest.logAction("abort");
+ if (succeeded == false) {
+ return false;
+ }
+ clearState();
+ return true;
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ LCTest.logAction("logout");
+ clearState();
+ return true;
+ }
+
+ private void clearState() {
+ if (commitSucceeded) {
+ final Subject s = subject;
+ final UnixPrincipal up = userPrincipal;
+ java.security.AccessController.doPrivileged
+ ((java.security.PrivilegedAction) () -> {
+ s.getPrincipals().remove(up);
+ return null;
+ });
+ }
+ username = null;
+ password = null;
+ userPrincipal = null;
+ }
+ }
+
+}
diff --git a/test/javax/security/auth/login/LoginContext/MyConfiguration.java b/test/javax/security/auth/login/LoginContext/MyConfiguration.java
new file mode 100644
index 0000000..5077279
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/MyConfiguration.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+ }
+ }
+
+}
diff --git a/test/javax/security/auth/login/LoginContext/SharedState.java b/test/javax/security/auth/login/LoginContext/SharedState.java
new file mode 100644
index 0000000..d944e5a
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/SharedState.java
@@ -0,0 +1,98 @@
+/*
+ * 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);
+ }
+ }
+
+ }
+}
diff --git a/test/javax/security/auth/login/LoginContext/SmartLoginModule.java b/test/javax/security/auth/login/LoginContext/SmartLoginModule.java
new file mode 100644
index 0000000..aa43ea6
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/SmartLoginModule.java
@@ -0,0 +1,253 @@
+/*
+ * 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();
+ }
+}
diff --git a/test/javax/security/auth/login/LoginContext/StandardCallbacks.java b/test/javax/security/auth/login/LoginContext/StandardCallbacks.java
new file mode 100644
index 0000000..4b69f84
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/StandardCallbacks.java
@@ -0,0 +1,189 @@
+/*
+ * 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");
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/test/javax/security/auth/login/LoginContext/custom.config b/test/javax/security/auth/login/LoginContext/custom.config
new file mode 100644
index 0000000..6ecdc56
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/custom.config
@@ -0,0 +1,4 @@
+StandardCallbacks {
+ DefaultHandlerModule required;
+ CustomLoginModule required username="username" password="password";
+};
diff --git a/test/javax/security/auth/login/LoginContext/shared.config b/test/javax/security/auth/login/LoginContext/shared.config
new file mode 100644
index 0000000..86201e2
--- /dev/null
+++ b/test/javax/security/auth/login/LoginContext/shared.config
@@ -0,0 +1,4 @@
+SharedState {
+ SharedState$FirstModule required;
+ SharedState$SecondModule required;
+};
\ No newline at end of file
diff --git a/test/javax/security/sasl/Sasl/ClientServerTest.java b/test/javax/security/sasl/Sasl/ClientServerTest.java
new file mode 100644
index 0000000..5d1222a
--- /dev/null
+++ b/test/javax/security/sasl/Sasl/ClientServerTest.java
@@ -0,0 +1,477 @@
+/*
+ * 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);
+ }
+ }
+ }
+ }
+
+}
diff --git a/test/javax/swing/JScrollPane/8033000/bug8033000.java b/test/javax/swing/JScrollPane/HorizontalMouseWheelOnShiftPressed/HorizontalMouseWheelOnShiftPressed.java
similarity index 77%
rename from test/javax/swing/JScrollPane/8033000/bug8033000.java
rename to test/javax/swing/JScrollPane/HorizontalMouseWheelOnShiftPressed/HorizontalMouseWheelOnShiftPressed.java
index 190390d..3c42ec7 100644
--- a/test/javax/swing/JScrollPane/8033000/bug8033000.java
+++ b/test/javax/swing/JScrollPane/HorizontalMouseWheelOnShiftPressed/HorizontalMouseWheelOnShiftPressed.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -20,6 +20,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Robot;
@@ -29,22 +30,23 @@
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
+
import sun.awt.OSInfo;
/**
* @test
- * @bug 8033000
+ * @bug 8033000 8147994
* @author Alexander Scherbatiy
* @summary No Horizontal Mouse Wheel Support In BasicScrollPaneUI
- * @run main bug8033000
+ * @run main HorizontalMouseWheelOnShiftPressed
*/
-public class bug8033000 {
+public class HorizontalMouseWheelOnShiftPressed {
private static JScrollPane scrollPane;
private static JTextArea textArea;
private static Point point;
private static final int delta;
+ private static JFrame frame;
static {
delta = OSInfo.getOSType().equals(OSInfo.OSType.MACOSX) ? -30 : 30;
@@ -55,9 +57,17 @@
Robot robot = new Robot();
robot.setAutoDelay(50);
- SwingUtilities.invokeAndWait(bug8033000::createAndShowGUI);
+ SwingUtilities.invokeAndWait(
+ HorizontalMouseWheelOnShiftPressed::createAndShowGUI);
robot.waitForIdle();
+ try {
+ test(robot);
+ } finally {
+ frame.dispose();
+ }
+ }
+ private static void test(Robot robot) throws Exception {
SwingUtilities.invokeAndWait(() -> {
Point locationOnScreen = scrollPane.getLocationOnScreen();
point = new Point(
@@ -73,7 +83,7 @@
robot.waitForIdle();
robot.mouseWheel(delta);
robot.waitForIdle();
- checkScrollPane(true);
+ checkScrollPane(true, false);
// vertical scroll bar is enabled + shift
initScrollPane(true, false);
@@ -82,14 +92,14 @@
robot.mouseWheel(delta);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.waitForIdle();
- checkScrollPane(true);
+ checkScrollPane(false, false);
// horizontal scroll bar is enabled
initScrollPane(false, true);
robot.waitForIdle();
robot.mouseWheel(delta);
robot.waitForIdle();
- checkScrollPane(false);
+ checkScrollPane(false, true);
// horizontal scroll bar is enabled + shift
initScrollPane(false, true);
@@ -98,14 +108,14 @@
robot.mouseWheel(delta);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.waitForIdle();
- checkScrollPane(false);
+ checkScrollPane(false, true);
// both scroll bars are enabled
initScrollPane(true, true);
robot.waitForIdle();
robot.mouseWheel(delta);
robot.waitForIdle();
- checkScrollPane(true);
+ checkScrollPane(true, false);
// both scroll bars are enabled + shift
initScrollPane(true, true);
@@ -114,7 +124,7 @@
robot.mouseWheel(delta);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.waitForIdle();
- checkScrollPane(false);
+ checkScrollPane(false, true);
}
static void initScrollPane(boolean vVisible, boolean hVisible) throws Exception {
@@ -129,17 +139,25 @@
});
}
- static void checkScrollPane(boolean verticalScrolled) throws Exception {
+ static void checkScrollPane(boolean verticalScrolled,
+ boolean horizontalScrolled) throws Exception {
SwingUtilities.invokeAndWait(() -> {
if (verticalScrolled) {
- if (scrollPane.getVerticalScrollBar().getValue() == 0
- || scrollPane.getHorizontalScrollBar().getValue() != 0) {
+ if (scrollPane.getVerticalScrollBar().getValue() == 0) {
throw new RuntimeException("Wrong vertical scrolling!");
}
+ } else{
+ if (scrollPane.getVerticalScrollBar().getValue() != 0) {
+ throw new RuntimeException("Wrong vertical scrolling!");
+ }
+ }
+ if (horizontalScrolled) {
+ if (scrollPane.getHorizontalScrollBar().getValue() == 0) {
+ throw new RuntimeException("Wrong horizontal scrolling!");
+ }
} else {
- if (scrollPane.getVerticalScrollBar().getValue() != 0
- || scrollPane.getHorizontalScrollBar().getValue() == 0) {
+ if (scrollPane.getHorizontalScrollBar().getValue() != 0) {
throw new RuntimeException("Wrong horizontal scrolling!");
}
}
@@ -147,9 +165,10 @@
}
static void createAndShowGUI() {
- JFrame frame = new JFrame();
+ frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
+ frame.setLocationRelativeTo(null);
textArea = new JTextArea("Hello World!");
scrollPane = new JScrollPane(textArea);
JPanel panel = new JPanel(new BorderLayout());
diff --git a/test/javax/xml/bind/jxc/8073872/Foo.java b/test/javax/xml/bind/jxc/8073872/Foo.java
new file mode 100644
index 0000000..9a2e3d6
--- /dev/null
+++ b/test/javax/xml/bind/jxc/8073872/Foo.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java b/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java
new file mode 100644
index 0000000..695fdef
--- /dev/null
+++ b/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java
@@ -0,0 +1,76 @@
+/*
+ * 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);
+
+}
diff --git a/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java b/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
new file mode 100644
index 0000000..7de90ad
--- /dev/null
+++ b/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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;
+}
diff --git a/test/javax/xml/bind/xjc/8145039/testSchema.xsd b/test/javax/xml/bind/xjc/8145039/testSchema.xsd
new file mode 100644
index 0000000..f625d06
--- /dev/null
+++ b/test/javax/xml/bind/xjc/8145039/testSchema.xsd
@@ -0,0 +1,21 @@
+<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>
diff --git a/test/javax/xml/jaxp/common/8144593/TestSAXDriver.java b/test/javax/xml/jaxp/common/8144593/TestSAXDriver.java
new file mode 100644
index 0000000..627fe1a
--- /dev/null
+++ b/test/javax/xml/jaxp/common/8144593/TestSAXDriver.java
@@ -0,0 +1,56 @@
+/*
+ * 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 com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl;
+import javax.xml.XMLConstants;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/*
+ * Test implementation of SAXParser. It is extended from JDK parser and two methods
+ * are overriden to disable support of specific features and properties.
+ * This class is used in ValidationWarningsTest and TransformationWarningsTest
+ * to generate multiple warnings during xml validation and transformation processes.
+*/
+public class TestSAXDriver extends SAXParserImpl.JAXPSAXParser {
+
+ @Override
+ public synchronized void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
+ if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name)) {
+ throw new SAXNotRecognizedException(name+" feature is not recognised by test SAX parser intentionally.");
+ } else {
+ super.setFeature(name, value);
+ }
+ }
+
+ @Override
+ public synchronized void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
+ if (XMLConstants.ACCESS_EXTERNAL_DTD.equals(name) || ENT_EXP_LIMIT_PROP.equals(name)) {
+ throw new SAXNotRecognizedException(name+" property is not recognised by test SAX parser intentionally.");
+ } else {
+ super.setProperty(name, value);
+ }
+ }
+
+ private static final String ENT_EXP_LIMIT_PROP = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
+}
diff --git a/test/javax/xml/jaxp/common/8144593/TransformationWarningsTest.java b/test/javax/xml/jaxp/common/8144593/TransformationWarningsTest.java
new file mode 100644
index 0000000..71c3ed1
--- /dev/null
+++ b/test/javax/xml/jaxp/common/8144593/TransformationWarningsTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeClass;
+
+/*
+ * @test
+ * @bug 8144593
+ * @summary Check that warnings about unsupported properties from parsers
+ * are suppressed during the transformation process.
+ * @compile -XDignore.symbol.file TestSAXDriver.java
+ * @run testng/othervm TransformationWarningsTest
+ */
+public class TransformationWarningsTest extends WarningsTestBase {
+
+ @BeforeClass
+ public void setup() {
+ //Set test SAX driver implementation.
+ System.setProperty("org.xml.sax.driver", "TestSAXDriver");
+ }
+
+ @Test
+ public void testTransformation() throws Exception {
+ startTest();
+ }
+
+ //One iteration of xml transformation test case. It will be called from each
+ //TestWorker task defined in WarningsTestBase class.
+ void doOneTestIteration() throws Exception {
+ // Prepare output stream
+ StringWriter xmlResultString = new StringWriter();
+ StreamResult xmlResultStream = new StreamResult(xmlResultString);
+ // Prepare xml source stream
+ Source src = new StreamSource(new StringReader(xml));
+ Transformer t = createTransformer();
+ //Transform the xml
+ t.transform(src, xmlResultStream);
+ }
+
+ //Create transformer from xsl test string
+ Transformer createTransformer() throws Exception {
+ // Prepare sources for transormation
+ Source xslsrc = new StreamSource(new StringReader(xsl));
+
+ // Create factory and transformer
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer t = tf.newTransformer(xslsrc);
+
+ // Set URI Resolver to return the newly constructed xml
+ // stream source object from xml test string
+ t.setURIResolver((String href, String base) -> new StreamSource(new StringReader(xml)));
+ return t;
+ }
+
+ //Xsl and Xml contents used in the transformation test
+ private static final String xsl = "<xsl:stylesheet version='2.0'"
+ + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+ + " <xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>"
+ + " <xsl:template match='/'>"
+ + " <test>Simple Transformation Result. No warnings should be printed to console</test>"
+ + " </xsl:template>"
+ + "</xsl:stylesheet>";
+ private static final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root></root>";
+}
diff --git a/test/javax/xml/jaxp/common/8144593/ValidationWarningsTest.java b/test/javax/xml/jaxp/common/8144593/ValidationWarningsTest.java
new file mode 100644
index 0000000..28c003c
--- /dev/null
+++ b/test/javax/xml/jaxp/common/8144593/ValidationWarningsTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.StringReader;
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeClass;
+import org.xml.sax.InputSource;
+
+/*
+ * @test
+ * @bug 8144593
+ * @summary Check that warnings about unsupported properties from SAX
+ * parsers are suppressed during the xml validation process.
+ * @compile -XDignore.symbol.file TestSAXDriver.java
+ * @run testng/othervm ValidationWarningsTest
+ */
+public class ValidationWarningsTest extends WarningsTestBase {
+
+ @BeforeClass
+ public void setup() {
+ //Set test SAX driver implementation.
+ System.setProperty("org.xml.sax.driver", "TestSAXDriver");
+ }
+
+ @Test
+ public void testValidation() throws Exception {
+ startTest();
+ }
+
+ //One iteration of xml validation test case. It will be called from each
+ //TestWorker task defined in WarningsTestBase class.
+ void doOneTestIteration() throws Exception {
+ Source src = new StreamSource(new StringReader(xml));
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ SAXSource xsdSource = new SAXSource(new InputSource(new ByteArrayInputStream(xsd.getBytes())));
+ Schema schema = schemaFactory.newSchema(xsdSource);
+ Validator v = schema.newValidator();
+ v.validate(src);
+ }
+
+ //Xsd and Xml contents used in the validation test
+ private static final String xsd = "<?xml version='1.0'?>"
+ + " <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
+ + " <xs:element name='test' type='xs:string'/>\n"
+ + " </xs:schema>";
+ private static final String xml = "<?xml version='1.0'?><test>Element</test>";
+
+}
diff --git a/test/javax/xml/jaxp/common/8144593/WarningsTestBase.java b/test/javax/xml/jaxp/common/8144593/WarningsTestBase.java
new file mode 100644
index 0000000..7f31f62
--- /dev/null
+++ b/test/javax/xml/jaxp/common/8144593/WarningsTestBase.java
@@ -0,0 +1,134 @@
+/*
+ * 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.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.XMLConstants;
+import org.testng.Assert;
+
+/*
+ * This class helps to test suppression of unsupported parser properties
+ * messages printed to standard error output.
+ * It launches THREADS_COUNT tasks. Each task does ITERATIONS_PER_THREAD
+ * sequential calls to doOneIteration method implemented by specific test class.
+ */
+public abstract class WarningsTestBase {
+
+ /*
+ * Abstract method that should be implemented by test class.
+ * It is repeatedly called by each TestWorker task.
+ */
+ abstract void doOneTestIteration() throws Exception;
+
+ /*
+ * Launches parallel test tasks and check the output for the number of
+ * generated warning messages. There should be no more than one message of
+ * each type.
+ */
+ void startTest() throws Exception {
+ //Save standard error stream
+ PrintStream defStdErr = System.err;
+ //Set new byte array stream as standard error stream
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream(5000);
+ System.setErr(new PrintStream(byteStream));
+ //Execute multiple TestWorker tasks
+ for (int id = 0; id < THREADS_COUNT; id++) {
+ EXECUTOR.execute(new TestWorker(id));
+ }
+ //Initiate shutdown of previously submitted task
+ EXECUTOR.shutdown();
+ //Wait for termination of submitted tasks
+ if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) {
+ //If not all tasks terminates during the time out force them to shutdown
+ EXECUTOR.shutdownNow();
+ }
+ //Restore default standard error stream
+ System.setErr(defStdErr);
+ //Print tasks stderr output
+ String errContent = byteStream.toString();
+ System.out.println("Standard error output content:");
+ System.out.println(errContent);
+ //Check tasks stderr output for quatity of warning messages
+ Assert.assertTrue(warningPrintedOnce(XMLConstants.ACCESS_EXTERNAL_DTD, errContent));
+ Assert.assertTrue(warningPrintedOnce(ENT_EXP_PROPERTY, errContent));
+ Assert.assertTrue(warningPrintedOnce(XMLConstants.FEATURE_SECURE_PROCESSING, errContent));
+ }
+
+ // Count occurences of warning messages in standard error and check if warning is printed
+ // not more than once
+ private boolean warningPrintedOnce(String propertyName, String testOutput) {
+ //Count for property name in test output
+ Pattern p = Pattern.compile(propertyName);
+ Matcher m = p.matcher(testOutput);
+ int count = 0;
+ while (m.find()) {
+ count += 1;
+ }
+ System.out.println("'" + propertyName + "' print count: " + count);
+ //If count is more than 1 then consider test failed
+ return count <= 1;
+ }
+
+ //TestWorker task that sequentially calls test method
+ private class TestWorker implements Runnable {
+ // Task id
+ private final int id;
+
+ TestWorker(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public void run() {
+ try {
+ System.out.printf("%d: waiting for barrier%n", id);
+ //Synchronize startup of all tasks
+ BARRIER.await();
+ System.out.printf("%d: starting iterations%n", id);
+ //Call test method multiple times
+ for (int i = 0; i < ITERATIONS_PER_THREAD; i++) {
+ doOneTestIteration();
+ }
+ } catch (Exception ex) {
+ throw new RuntimeException("TestWorker id:" + id + " failed", ex);
+ }
+ }
+ }
+
+ //Entity expansion limit property name
+ private static final String ENT_EXP_PROPERTY = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
+ //Number of simultaneous test threads
+ private static final int THREADS_COUNT = 10;
+ //Number of iterations per one thread
+ private static final int ITERATIONS_PER_THREAD = 4;
+ //Test thread pool
+ private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
+ //Cyclic barrier for threads startup synchronisation
+ private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT);
+}
diff --git a/test/javax/xml/jaxp/parsers/8072081/SupplementaryChars.java b/test/javax/xml/jaxp/parsers/8072081/SupplementaryChars.java
new file mode 100644
index 0000000..288a96b
--- /dev/null
+++ b/test/javax/xml/jaxp/parsers/8072081/SupplementaryChars.java
@@ -0,0 +1,91 @@
+/*
+ * 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.ByteArrayInputStream;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * @test
+ * @bug 8072081
+ * @summary verifies that supplementary characters are supported as character
+ * data in xml 1.0, and also names in xml 1.1.
+ * @run testng/othervm SupplementaryChars
+ */
+/*
+ * Joe Wang (huizhe.wang@oracle.com)
+ */
+
+public class SupplementaryChars {
+
+ @Test(dataProvider = "supported")
+ public void test(String xml) throws Exception {
+ ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
+ getParser().parse(stream, new DefaultHandler());
+ stream.close();
+ }
+
+ @Test(dataProvider = "unsupported", expectedExceptions = SAXParseException.class)
+ public void testInvalid(String xml) throws Exception {
+ ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
+ getParser().parse(stream, new DefaultHandler());
+ stream.close();
+ }
+
+ @DataProvider(name = "supported")
+ private Object[][] supported() {
+
+ return new Object[][] {
+ {"<?xml version=\"1.0\"?><tag>\uD840\uDC0B</tag>"},
+ {"<?xml version=\"1.0\"?><!-- \uD840\uDC0B --><tag/>"},
+ {"<?xml version=\"1.1\"?><tag\uD840\uDC0B>in tag name</tag\uD840\uDC0B>"},
+ {"<?xml version=\"1.1\"?><tag attr\uD840\uDC0B=\"in attribute\">in attribute name</tag>"},
+ {"<?xml version=\"1.1\"?><tag>\uD840\uDC0B</tag>"},
+ {"<?xml version=\"1.1\"?><!-- \uD840\uDC0B --><dontCare/>"}
+ };
+ }
+
+ @DataProvider(name = "unsupported")
+ private Object[][] unsupported() {
+ return new Object[][] {
+ {"<?xml version=\"1.0\"?><tag\uD840\uDC0B>in tag name</tag\uD840\uDC0B>"},
+ {"<?xml version=\"1.0\"?><tag attr\uD840\uDC0B=\"in attribute\">in attribute name</tag>"}
+ };
+ }
+
+ private SAXParser getParser() {
+ SAXParser parser = null;
+ try {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ parser = factory.newSAXParser();
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ return parser;
+ }
+}
diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.ref b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.ref
new file mode 100644
index 0000000..0af2588
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.ref
@@ -0,0 +1 @@
+................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xml b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xml
new file mode 100644
index 0000000..382a25f
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<element>
+ <text>.</text>
+</element>
diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xsl b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xsl
new file mode 100644
index 0000000..f390323
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-1.xsl
@@ -0,0 +1,76 @@
+<?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>
</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>
diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.ref b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.ref
new file mode 100644
index 0000000..b012e31
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.ref
@@ -0,0 +1,83 @@
+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 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xml b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xml
new file mode 100644
index 0000000..19a8381
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xml
@@ -0,0 +1,2438 @@
+<?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>
+
diff --git a/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xsl b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xsl
new file mode 100644
index 0000000..03040b7
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/Bug8150704-2.xsl
@@ -0,0 +1,1935 @@
+<?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>
</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(./*) > 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 > 0051053500) and (invoiceNumber < 0051999999)">KA</xsl:when>
+<xsl:when test="(invoiceNumber > 0054012000) and (invoiceNumber < 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) > 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) > 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) > 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) > 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) > 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) > 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) > 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>
diff --git a/test/javax/xml/jaxp/transform/8150704/TransformerTest.java b/test/javax/xml/jaxp/transform/8150704/TransformerTest.java
new file mode 100644
index 0000000..62ade11
--- /dev/null
+++ b/test/javax/xml/jaxp/transform/8150704/TransformerTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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();
+ }
+ }
+}
diff --git a/test/javax/xml/jaxp/validation/8149915/Bug8149915.xsd b/test/javax/xml/jaxp/validation/8149915/Bug8149915.xsd
new file mode 100644
index 0000000..872033f
--- /dev/null
+++ b/test/javax/xml/jaxp/validation/8149915/Bug8149915.xsd
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xs:annotation>
+ <xs:appinfo>Testapp for XSD annotation issue</xs:appinfo>
+ <xs:documentation xml:lang="en">This is an XSD annotation, just for the sake of it.</xs:documentation>
+</xs:annotation>
+</xs:schema>
diff --git a/test/javax/xml/jaxp/validation/8149915/SchemaTest.java b/test/javax/xml/jaxp/validation/8149915/SchemaTest.java
new file mode 100644
index 0000000..c58d842
--- /dev/null
+++ b/test/javax/xml/jaxp/validation/8149915/SchemaTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * @summary Test Schema creation
+ * @bug 8149915
+ * @run testng/othervm SchemaTest
+ */
+
+import java.io.File;
+import javax.xml.XMLConstants;
+import javax.xml.validation.SchemaFactory;
+import org.testng.annotations.Test;
+
+public class SchemaTest {
+
+ /*
+ * @bug 8149915
+ * Verifies that the annotation validator is initialized with the security manager for schema
+ * creation with http://apache.org/xml/features/validate-annotations=true.
+ */
+ @Test
+ public void testValidation() throws Exception {
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ factory.setFeature("http://apache.org/xml/features/validate-annotations", true);
+ factory.newSchema(new File(getClass().getResource("Bug8149915.xsd").getFile()));
+ }
+}
diff --git a/test/lib/testlibrary/JavaToolUtils.java b/test/lib/testlibrary/JavaToolUtils.java
new file mode 100644
index 0000000..c9736bc
--- /dev/null
+++ b/test/lib/testlibrary/JavaToolUtils.java
@@ -0,0 +1,209 @@
+/*
+ * 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. 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.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Utils class for compiling , creating jar file and executing a java command
+ *
+ * @author Raghu Nair
+ */
+
+public class JavaToolUtils {
+
+ public static final long DEFAULT_WAIT_TIME = 10000;
+
+ private JavaToolUtils() {
+ }
+
+ /**
+ * Takes a list of files and compile these files into the working directory.
+ *
+ * @param files
+ * @throws IOException
+ */
+ public static void compileFiles(List<File> files) throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fileManager = compiler.
+ getStandardFileManager(null, null, null)) {
+ Iterable<? extends JavaFileObject> compilationUnit
+ = fileManager.getJavaFileObjectsFromFiles(files);
+ compiler.getTask(null, fileManager, null, null, null,
+ compilationUnit).call();
+ }
+ }
+
+ /**
+ * Create a jar file using the list of files provided.
+ *
+ * @param jar
+ * @param files
+ * @throws IOException
+ */
+ public static void createJar(File jar, List<File> files)
+ throws IOException {
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION,
+ "1.0");
+ try (JarOutputStream target = new JarOutputStream(
+ new FileOutputStream(jar), manifest)) {
+ for (File file : files) {
+ add(file, target);
+ }
+ }
+ }
+
+ private static void add(File source, JarOutputStream target)
+ throws IOException {
+ Objects.requireNonNull(source, "source cannot be null");
+ Objects.requireNonNull(target, "target cannot be null");
+ // not tested against directories and from different path.
+ String name = source.getName();
+ if (source.isDirectory()) {
+ if (!name.isEmpty()) {
+ if (!name.endsWith("/")) {
+ name += "/";
+ }
+ JarEntry entry = new JarEntry(name);
+ entry.setTime(source.lastModified());
+ target.putNextEntry(entry);
+ target.closeEntry();
+ }
+ for (File nestedFile : source.listFiles()) {
+ add(nestedFile, target);
+ }
+ return;
+ }
+ System.out.println("Adding entry " + name);
+ JarEntry entry = new JarEntry(name);
+ entry.setTime(source.lastModified());
+ target.putNextEntry(entry);
+ Files.copy(source.toPath(), target);
+ target.closeEntry();
+ }
+
+ /**
+ * Runs java command with provided arguments. Caller should not pass java
+ * command in the argument list.
+ *
+ * @param commands
+ * @param waitTime time to wait for the command to exit in milli seconds
+ * @return
+ * @throws Exception
+ */
+ public static int runJava(List<String> commands,long waitTime)
+ throws Exception {
+ String java = System.getProperty("java.home") + "/bin/java";
+ commands.add(0, java);
+ String command = commands.toString().replace(",", " ");
+ System.out.println("Executing the following command \n" + command);
+ ProcessBuilder processBuilder = new ProcessBuilder(commands);
+ final Process process = processBuilder.start();
+ BufferedReader errorStream = new BufferedReader(
+ new InputStreamReader(process.getErrorStream()));
+ BufferedReader outStream = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ String errorLine;
+ StringBuilder errors = new StringBuilder();
+ String outLines;
+ while ((errorLine = errorStream.readLine()) != null) {
+ errors.append(errorLine).append("\n");
+ }
+ while ((outLines = outStream.readLine()) != null) {
+ System.out.println(outLines);
+ }
+ errorLine = errors.toString();
+ System.err.println(errorLine);
+ process.waitFor(waitTime, TimeUnit.MILLISECONDS);
+ int exitStatus = process.exitValue();
+ if (exitStatus != 0 && errorLine != null && errorLine.isEmpty()) {
+ throw new RuntimeException(errorLine);
+ }
+ return exitStatus;
+ }
+
+ /**
+ * Runs java command with provided arguments. Caller should not pass java
+ * command in the argument list.
+ *
+ * @param commands
+ * @return
+ * @throws Exception
+ */
+ public static int runJava(List<String> commands) throws Exception {
+ return runJava(commands, DEFAULT_WAIT_TIME);
+ }
+
+ /**
+ * Run any command
+ * @param commands
+ * @return
+ * @throws Exception
+ */
+ public static int runCommand(List<String> commands) throws Exception {
+ String command = commands.toString().replace(",", " ");
+ System.out.println("Executing the following command \n" + command);
+ ProcessBuilder processBuilder = new ProcessBuilder(commands);
+ final Process process = processBuilder.start();
+ BufferedReader errorStream = new BufferedReader(
+ new InputStreamReader(process.getErrorStream()));
+ BufferedReader outStream = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ String errorLine;
+ StringBuilder errors = new StringBuilder();
+ String outLines;
+ while ((errorLine = errorStream.readLine()) != null) {
+ errors.append(errorLine).append("\n");
+ }
+ while ((outLines = outStream.readLine()) != null) {
+ System.out.println(outLines);
+ }
+ errorLine = errors.toString();
+ System.err.println(errorLine);
+ int exitStatus = process.exitValue();
+ if (exitStatus != 0 && errorLine != null && errorLine.isEmpty()) {
+ throw new RuntimeException(errorLine);
+ }
+ return exitStatus;
+ }
+
+
+}
diff --git a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
index 14599c9..1837cea 100644
--- a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
+++ b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
@@ -26,34 +26,91 @@
import java.util.Arrays;
/**
- * Super class for tests which need to attach jcmd to the current process.
+ * Helper class for starting jcmd process.
+ * <pre>
+ * - jcmd will send diagnostic requests to the current java process:
+ * jcmd pid_to_current_process PerfCounter.print
+ * - jcmd will be run without sending request to any JVM
+ * jcmd -h
+ * </pre>
*/
-public class JcmdBase {
+public final class JcmdBase {
private static ProcessBuilder processBuilder = new ProcessBuilder();
+ private JcmdBase() {
+ // Private constructor to prevent class instantiation
+ }
+
/**
- * Attach jcmd to the current process
+ * Sends the diagnostic command request to the current process
*
- * @param toolArgs
- * jcmd command line parameters, e.g. VM.flags
- * @return jcmd output
+ * @see #jcmd(boolean, String[], String[])
+ */
+ public final static OutputAnalyzer jcmd(String... jcmdArgs)
+ throws Exception {
+ return jcmd(true, null, jcmdArgs);
+ }
+
+ /**
+ * Sends the diagnostic command request to the current process.
+ * jcmd will be run with specified {@code vmArgs}.
+ *
+ * @see #jcmd(boolean, String[], String[])
+ */
+ public final static OutputAnalyzer jcmd(String[] vmArgs,
+ String[] jcmdArgs) throws Exception {
+ return jcmd(true, vmArgs, jcmdArgs);
+ }
+
+ /**
+ * Runs jcmd without sending request to any JVM
+ *
+ * @see #jcmd(boolean, String[], String[])
+ */
+ public final static OutputAnalyzer jcmdNoPid(String[] vmArgs,
+ String[] jcmdArgs) throws Exception {
+ return jcmd(false, vmArgs, jcmdArgs);
+ }
+
+ /**
+ * If {@code requestToCurrentProcess} is {@code true}
+ * sends a diagnostic command request to the current process.
+ * If {@code requestToCurrentProcess} is {@code false}
+ * runs jcmd without sending request to any JVM.
+ *
+ * @param requestToCurrentProcess
+ * Defines if jcmd will send request to the current process
+ * @param vmArgs
+ * jcmd will be run with VM arguments specified,
+ * e.g. -XX:+UsePerfData
+ * @param jcmdArgs
+ * jcmd will be run with option or command and its arguments
+ * specified, e.g. VM.flags
+ * @return The output from {@link OutputAnalyzer} object
* @throws Exception
*/
- public final static OutputAnalyzer jcmd(String... toolArgs)
- throws Exception {
+ private static final OutputAnalyzer jcmd(boolean requestToCurrentProcess,
+ String[] vmArgs, String[] jcmdArgs) throws Exception {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd");
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
- for (String toolArg : toolArgs) {
- launcher.addToolArg(toolArg);
+ if (vmArgs != null) {
+ for (String vmArg : vmArgs) {
+ launcher.addVMArg(vmArg);
+ }
+ }
+ if (requestToCurrentProcess) {
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
+ }
+ if (jcmdArgs != null) {
+ for (String toolArg : jcmdArgs) {
+ launcher.addToolArg(toolArg);
+ }
}
processBuilder.command(launcher.getCommand());
System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
System.out.println(output.getOutput());
- output.shouldHaveExitValue(0);
-
return output;
}
diff --git a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
index d39c0ab..7c0d364 100644
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
+++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
@@ -23,11 +23,14 @@
package jdk.testlibrary;
+import static jdk.testlibrary.Asserts.*;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.Scanner;
/**
* Utility class for verifying output and exit value from a {@code Process}.
@@ -397,22 +400,105 @@
return exitValue;
}
+
/**
* Get the contents of the output buffer (stdout and stderr) as list of strings.
* Output will be split by system property 'line.separator'.
*
* @return Contents of the output buffer as list of strings
*/
- public List<String> asLines() {
- return asLines(getOutput());
- }
+ public List<String> asLines() {
+ return asLines(getOutput());
+ }
- private List<String> asLines(String buffer) {
+ public List<String> asLines(String buffer) {
List<String> l = new ArrayList<>();
+
String[] a = buffer.split(Utils.NEW_LINE);
+
for (String string : a) {
l.add(string);
}
return l;
}
+
+ /**
+ * Check if there is a line matching {@code pattern} and return its index
+ *
+ * @param pattern Matching pattern
+ * @return Index of first matching line
+ */
+ private int indexOf(List<String> lines, String pattern) {
+ for (int i = 0; i < lines.size(); i++) {
+ if (lines.get(i).matches (pattern)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @see #shouldMatchByLine(String, String, String)
+ */
+ public int shouldMatchByLine(String pattern) {
+ return shouldMatchByLine(null, null, pattern);
+ }
+
+ /**
+ * @see #shouldMatchByLine(String, String, String)
+ */
+ public int shouldMatchByLineFrom(String from, String pattern) {
+ return shouldMatchByLine(from, null, pattern);
+ }
+
+ /**
+ * @see #shouldMatchByLine(String, String, String)
+ */
+ public int shouldMatchByLineTo(String to, String pattern) {
+ return shouldMatchByLine(null, to, pattern);
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer match the
+ * {@code pattern} line by line. The whole output could be matched or
+ * just a subset of it.
+ *
+ * @param from
+ * The line from where output will be matched.
+ * Set {@code from} to null for matching from the first line.
+ * @param to
+ * The line until where output will be matched.
+ * Set {@code to} to null for matching until the last line.
+ * @param pattern
+ * Matching pattern
+ * @return Count of lines which match the {@code pattern}
+ */
+ public int shouldMatchByLine(String from, String to, String pattern) {
+ List<String> lines = asLines();
+
+ int fromIndex = 0;
+ if (from != null) {
+ fromIndex = indexOf(lines, from);
+ assertGreaterThan(fromIndex, -1,
+ "The line/pattern '" + from + "' from where the output should match can not be found");
+ }
+
+ int toIndex = lines.size();
+ if (to != null) {
+ toIndex = indexOf(lines, to);
+ assertGreaterThan(toIndex, -1,
+ "The line/pattern '" + to + "' until where the output should match can not be found");
+ }
+
+ List<String> subList = lines.subList(fromIndex, toIndex);
+ int matchedCount = 0;
+ for (String line : subList) {
+ assertTrue(line.matches(pattern),
+ "The line '" + line + "' does not match pattern '" + pattern + "'");
+ matchedCount++;
+ }
+
+ return matchedCount;
+ }
+
}
diff --git a/test/lib/testlibrary/jdk/testlibrary/Utils.java b/test/lib/testlibrary/jdk/testlibrary/Utils.java
index 67af0cd..c219234 100644
--- a/test/lib/testlibrary/jdk/testlibrary/Utils.java
+++ b/test/lib/testlibrary/jdk/testlibrary/Utils.java
@@ -25,6 +25,9 @@
import static jdk.testlibrary.Asserts.assertTrue;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
@@ -241,7 +244,6 @@
* @throws Exception If multiple matching jvms are found.
*/
public static int tryFindJvmPid(String key) throws Throwable {
- ProcessBuilder pb = null;
OutputAnalyzer output = null;
try {
JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
@@ -269,6 +271,25 @@
}
/**
+ * Returns file content as a list of strings
+ *
+ * @param file File to operate on
+ * @return List of strings
+ * @throws IOException
+ */
+ public static List<String> fileAsList(File file) throws IOException {
+ assertTrue(file.exists() && file.isFile(),
+ file.getAbsolutePath() + " does not exist or not a file");
+ List<String> output = new ArrayList<>();
+ try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) {
+ while (reader.ready()) {
+ output.add(reader.readLine().replace(NEW_LINE, ""));
+ }
+ }
+ return output;
+ }
+
+ /**
* Adjusts the provided timeout value for the TIMEOUT_FACTOR
* @param tOut the timeout value to be adjusted
* @return The timeout value adjusted for the value of "test.timeout.factor"
diff --git a/test/sample/TEST.properties b/test/sample/TEST.properties
new file mode 100644
index 0000000..8e5f78a
--- /dev/null
+++ b/test/sample/TEST.properties
@@ -0,0 +1 @@
+external.lib.roots = ../../
diff --git a/test/sample/chatserver/ChatTest.java b/test/sample/chatserver/ChatTest.java
index 05d6f44..9cb2daa 100644
--- a/test/sample/chatserver/ChatTest.java
+++ b/test/sample/chatserver/ChatTest.java
@@ -25,9 +25,9 @@
/* @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
- * @run main ChatTest
+ * @run testng ChatTest
*/
import java.io.*;
@@ -38,10 +38,13 @@
import java.util.List;
import java.util.concurrent.CyclicBarrier;
+import org.testng.annotations.Test;
+
public class ChatTest {
public static int listeningPort = 0;
- public static void main(String[] args) throws Throwable {
+ @Test
+ public static void doTest() throws Throwable {
testStartStop();
testPortOpen();
testAsksForName();
diff --git a/test/sample/mergesort/MergeSortTest.java b/test/sample/mergesort/MergeSortTest.java
index 001e4f0..53b5252 100644
--- a/test/sample/mergesort/MergeSortTest.java
+++ b/test/sample/mergesort/MergeSortTest.java
@@ -25,14 +25,16 @@
/* @test
* @summary Test MergeSort
*
- * @library ../../../src/share/sample/forkjoin/mergesort
+ * @library /src/share/sample/forkjoin/mergesort
* @build MergeSortTest MergeDemo MergeSort
- * @run main MergeSortTest
+ * @run testng MergeSortTest
*/
import java.util.Arrays;
import java.util.Random;
+import org.testng.annotations.Test;
+
public class MergeSortTest {
private Random random;
private MergeSort target;
@@ -42,7 +44,8 @@
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));
test.run();
}
diff --git a/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java b/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java
index cc926c8..d9af913 100644
--- a/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java
+++ b/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java
@@ -37,42 +37,61 @@
public static void main(String[] args) throws Exception {
String[] mimes = new String[] {
+ "text/plain;class=java.nio.ByteBuffer;charset=UTF-8",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-8",
+ "text/plain;class=java.nio.ByteBuffer;charset=UTF-16LE",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-16LE",
+ "application/x-java-text-encoding",
+ "application/x-java-serialized-object;class=java.lang.String",
+ "text/plain;class=java.io.InputStream;charset=UTF-8",
+ "text/uri-list;class=java.io.InputStream;charset=UTF-8",
+ "text/plain;class=java.io.InputStream;charset=windows-1252",
+ "text/uri-list;class=java.io.InputStream;charset=windows-1252",
+ "application/x-java-url;class=java.net.URL",
+ "text/plain;class=java.io.Reader",
+ "text/plain;charset=windows-1252",
+ "text/uri-list;class=java.io.Reader",
+ "text/uri-list;charset=windows-1252",
+ "text/plain;charset=UTF-8",
+ "text/uri-list;charset=UTF-8",
+ "text/plain;class=java.io.InputStream;charset=US-ASCII",
+ "text/uri-list;class=java.io.InputStream;charset=US-ASCII",
+ "text/plain;class=java.io.InputStream;charset=UTF-16LE",
+ "text/plain;charset=US-ASCII",
+ "text/uri-list;class=java.io.InputStream;charset=UTF-16LE",
+ "text/uri-list;charset=US-ASCII",
+ "text/plain;charset=UTF-16LE",
+ "text/uri-list;charset=UTF-16LE",
+ "text/plain;class=java.nio.ByteBuffer;charset=UTF-16BE",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-16BE",
+ "text/plain;class=java.nio.ByteBuffer;charset=ISO-8859-1",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=ISO-8859-1",
"text/plain",
- "text/plain; charset=unicode",
- "text/plain; charset=cp1251",
- "text/plain; charset=unicode; class=java.io.InputStream",
- "text/plain; charset=unicode; class=java.io.Serializable",
- "text/plain; charset=unicode; class=java.lang.Object",
- "text/plain; class=java.lang.String",
- "text/plain; class=java.io.Reader",
- "text/plain; class=java.lang.Object",
- "text/html",
- "text/html; charset=unicode",
- "text/html; charset=cp1251",
- "text/html; charset=unicode; class=java.io.InputStream",
- "text/html; charset=unicode; class=java.io.Serializable",
- "text/html; charset=unicode; class=java.lang.Object",
- "text/html; class=java.lang.String",
- "text/html; class=java.io.Reader",
- "text/html; class=java.lang.Object",
- "text/unknown",
- "text/unknown; charset=unicode",
- "text/unknown; charset=cp1251",
- "text/unknown; charset=unicode; class=java.io.InputStream",
- "text/unknown; charset=unicode; class=java.io.Serializable",
- "text/unknown; charset=unicode; class=java.lang.Object",
- "text/unknown; class=java.lang.String",
- "text/unknown; class=java.io.Reader",
- "text/unknown; class=java.lang.Object",
- "application/unknown; class=java.io.InputStream",
- "application/unknown; class=java.lang.Object",
- "application/unknown",
- "application/x-java-jvm-local-objectref; class=java.io.InputStream",
- "application/x-java-jvm-local-objectref; class=java.lang.Object",
- "application/x-java-jvm-local-objectref",
- "unknown/flavor",
- "unknown/flavor; class=java.io.InputStream",
- "unknown/flavor; class=java.lang.Object",
+ "text/uri-list",
+ "text/plain;class=java.nio.ByteBuffer;charset=UTF-16",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=UTF-16",
+ "text/plain;class=java.io.InputStream;charset=unicode",
+ "text/uri-list;class=java.io.InputStream;charset=UTF-16",
+ "text/plain;class=java.nio.CharBuffer",
+ "text/uri-list;class=java.nio.CharBuffer",
+ "text/plain;class=java.lang.String",
+ "text/plain;charset=UTF-16BE",
+ "text/uri-list;class=java.lang.String",
+ "text/uri-list;charset=UTF-16BE",
+ "text/plain;charset=ISO-8859-1",
+ "text/uri-list;charset=ISO-8859-1",
+ "text/plain;class=java.io.InputStream;charset=UTF-16BE",
+ "text/uri-list;class=java.io.InputStream;charset=UTF-16BE",
+ "text/plain;class=java.nio.ByteBuffer;charset=US-ASCII",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=US-ASCII",
+ "text/plain;class=java.io.InputStream;charset=ISO-8859-1",
+ "text/uri-list;class=java.io.InputStream;charset=ISO-8859-1",
+ "text/plain;charset=UTF-16",
+ "text/plain;class=java.nio.ByteBuffer;charset=windows-1252",
+ "text/uri-list;charset=UTF-16",
+ "text/uri-list;class=java.nio.ByteBuffer;charset=windows-1252",
+ "text/plain;class=java.io.InputStream;charset=windows-1252",
+ "text/uri-list;class=java.io.InputStream;charset=windows-1252",
};
DataFlavor[] flavors = new DataFlavor[mimes.length];
diff --git a/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java b/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java
new file mode 100644
index 0000000..4647f28
--- /dev/null
+++ b/test/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2015, Red Hat Inc
+ * 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.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+
+/**
+ * Tests client connections to the JDK's built-in JMX agent server on the given
+ * ports/interface combinations.
+ *
+ * @see JMXInterfaceBindingTest
+ *
+ * @author Severin Gehwolf <sgehwolf@redhat.com>
+ *
+ * Usage:
+ *
+ * SSL:
+ * java -Dcom.sun.management.jmxremote.ssl.need.client.auth=true \
+ * -Dcom.sun.management.jmxremote.host=127.0.0.1 \
+ * -Dcom.sun.management.jmxremote.port=9111 \
+ * -Dcom.sun.management.jmxremote.rmi.port=9112 \
+ * -Dcom.sun.management.jmxremote.authenticate=false \
+ * -Dcom.sun.management.jmxremote.ssl=true \
+ * -Dcom.sun.management.jmxremote.registry.ssl=true
+ * -Djavax.net.ssl.keyStore=... \
+ * -Djavax.net.ssl.keyStorePassword=... \
+ * JMXAgentInterfaceBinding 127.0.0.1 9111 9112 true
+ *
+ * Non-SSL:
+ * java -Dcom.sun.management.jmxremote.host=127.0.0.1 \
+ * -Dcom.sun.management.jmxremote.port=9111 \
+ * -Dcom.sun.management.jmxremote.rmi.port=9112 \
+ * -Dcom.sun.management.jmxremote.authenticate=false \
+ * -Dcom.sun.management.jmxremote.ssl=false \
+ * JMXAgentInterfaceBinding 127.0.0.1 9111 9112 false
+ *
+ */
+public class JMXAgentInterfaceBinding {
+
+ private final MainThread mainThread;
+
+ public JMXAgentInterfaceBinding(InetAddress bindAddress,
+ int jmxPort,
+ int rmiPort,
+ boolean useSSL) {
+ this.mainThread = new MainThread(bindAddress, jmxPort, rmiPort, useSSL);
+ }
+
+ public void startEndpoint() {
+ mainThread.start();
+ try {
+ mainThread.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Test failed", e);
+ }
+ if (mainThread.isFailed()) {
+ mainThread.rethrowException();
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length != 4) {
+ throw new RuntimeException(
+ "Test failed. usage: java JMXInterfaceBindingTest <BIND_ADDRESS> <JMX_PORT> <RMI_PORT> {true|false}");
+ }
+ int jmxPort = parsePortFromString(args[1]);
+ int rmiPort = parsePortFromString(args[2]);
+ boolean useSSL = Boolean.parseBoolean(args[3]);
+ String strBindAddr = args[0];
+ System.out.println(
+ "DEBUG: Running test for triplet (hostname,jmxPort,rmiPort) = ("
+ + strBindAddr + "," + jmxPort + "," + rmiPort + "), useSSL = " + useSSL);
+ InetAddress bindAddress;
+ try {
+ bindAddress = InetAddress.getByName(args[0]);
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("Test failed. Unknown ip: " + args[0]);
+ }
+ JMXAgentInterfaceBinding test = new JMXAgentInterfaceBinding(bindAddress,
+ jmxPort, rmiPort, useSSL);
+ test.startEndpoint(); // Expect for main test to terminate process
+ }
+
+ private static int parsePortFromString(String port) {
+ try {
+ return Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException(
+ "Invalid port specified. Not an integer! Value was: "
+ + port);
+ }
+ }
+
+ private static class JMXConnectorThread extends Thread {
+
+ private final String addr;
+ private final int jmxPort;
+ private final int rmiPort;
+ private final boolean useSSL;
+ private final CountDownLatch latch;
+ private boolean failed;
+ private boolean jmxConnectWorked;
+ private boolean rmiConnectWorked;
+
+ private JMXConnectorThread(String addr,
+ int jmxPort,
+ int rmiPort,
+ boolean useSSL,
+ CountDownLatch latch) {
+ this.addr = addr;
+ this.jmxPort = jmxPort;
+ this.rmiPort = rmiPort;
+ this.latch = latch;
+ this.useSSL = useSSL;
+ }
+
+ @Override
+ public void run() {
+ try {
+ connect();
+ } catch (IOException e) {
+ failed = true;
+ }
+ }
+
+ private void connect() throws IOException {
+ System.out.println(
+ "JMXConnectorThread: Attempting JMX connection on: "
+ + addr + " on port " + jmxPort);
+ JMXServiceURL url;
+ try {
+ url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"
+ + addr + ":" + jmxPort + "/jmxrmi");
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("Test failed.", e);
+ }
+ Map<String, Object> env = new HashMap<>();
+ if (useSSL) {
+ SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
+ env.put("com.sun.jndi.rmi.factory.socket", csf);
+ env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
+ }
+ // connect and immediately close
+ JMXConnector c = JMXConnectorFactory.connect(url, env);
+ c.close();
+ System.out.println("JMXConnectorThread: connection to JMX worked");
+ jmxConnectWorked = true;
+ checkRmiSocket();
+ latch.countDown(); // signal we are done.
+ }
+
+ private void checkRmiSocket() throws IOException {
+ Socket rmiConnection;
+ if (useSSL) {
+ rmiConnection = SSLSocketFactory.getDefault().createSocket();
+ } else {
+ rmiConnection = new Socket();
+ }
+ SocketAddress target = new InetSocketAddress(addr, rmiPort);
+ rmiConnection.connect(target);
+ if (useSSL) {
+ ((SSLSocket)rmiConnection).startHandshake();
+ }
+ System.out.println(
+ "JMXConnectorThread: connection to rmi socket worked host/port = "
+ + addr + "/" + rmiPort);
+ rmiConnectWorked = true;
+ // Closing the channel without sending any data will cause an
+ // java.io.EOFException on the server endpoint. We don't care about this
+ // though, since we only want to test if we can connect.
+ rmiConnection.close();
+ }
+
+ public boolean isFailed() {
+ return failed;
+ }
+
+ public boolean jmxConnectionWorked() {
+ return jmxConnectWorked;
+ }
+
+ public boolean rmiConnectionWorked() {
+ return rmiConnectWorked;
+ }
+ }
+
+ private static class MainThread extends Thread {
+
+ private static final int WAIT_FOR_JMX_AGENT_TIMEOUT_MS = 500;
+ private final String addr;
+ private final int jmxPort;
+ private final int rmiPort;
+ private final boolean useSSL;
+ private boolean terminated = false;
+ private boolean jmxAgentStarted = false;
+ private Exception excptn;
+
+ private MainThread(InetAddress bindAddress, int jmxPort, int rmiPort, boolean useSSL) {
+ this.addr = wrapAddress(bindAddress.getHostAddress());
+ this.jmxPort = jmxPort;
+ this.rmiPort = rmiPort;
+ this.useSSL = useSSL;
+ }
+
+ @Override
+ public void run() {
+ try {
+ waitUntilReadyForConnections();
+ // Do nothing, but wait for termination.
+ try {
+ while (!terminated) {
+ Thread.sleep(100);
+ }
+ } catch (InterruptedException e) { // ignore
+ }
+ System.out.println("MainThread: Thread stopped.");
+ } catch (Exception e) {
+ this.excptn = e;
+ }
+ }
+
+ private void waitUntilReadyForConnections() {
+ CountDownLatch latch = new CountDownLatch(1);
+ JMXConnectorThread connectionTester = new JMXConnectorThread(
+ addr, jmxPort, rmiPort, useSSL, latch);
+ connectionTester.start();
+ boolean expired = false;
+ try {
+ expired = !latch.await(WAIT_FOR_JMX_AGENT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ System.out.println(
+ "MainThread: Finished waiting for JMX agent to become available: expired == "
+ + expired);
+ jmxAgentStarted = !expired;
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Test failed", e);
+ }
+ if (!jmxAgentStarted) {
+ throw new RuntimeException(
+ "Test failed. JMX server agents not becoming available.");
+ }
+ if (connectionTester.isFailed()
+ || !connectionTester.jmxConnectionWorked()
+ || !connectionTester.rmiConnectionWorked()) {
+ throw new RuntimeException(
+ "Test failed. JMX agent does not seem ready. See log output for details.");
+ }
+ // The main test expects this exact message being printed
+ System.out.println("MainThread: Ready for connections");
+ }
+
+ private boolean isFailed() {
+ return excptn != null;
+ }
+
+ private void rethrowException() throws RuntimeException {
+ throw new RuntimeException(excptn);
+ }
+ }
+
+ /**
+ * Will wrap IPv6 address in '[]'
+ */
+ static String wrapAddress(String address) {
+ if (address.contains(":")) {
+ return "[" + address + "]";
+ }
+ return address;
+ }
+}
diff --git a/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java b/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java
new file mode 100644
index 0000000..4a48278
--- /dev/null
+++ b/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2015, Red Hat Inc
+ * 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.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
+import jdk.testlibrary.ProcessTools;
+
+/**
+ * NOTE:
+ * This test requires at least a setup similar to the following in
+ * /etc/hosts file (or the windows equivalent). I.e. it expects it to
+ * be multi-homed and not both being the loop-back interface.
+ * For example:
+ * ----->8-------- /etc/hosts ----------->8---
+ * 127.0.0.1 localhost
+ * 192.168.0.1 localhost
+ * ----->8-------- /etc/hosts ----------->8---
+ *
+ * @test
+ * @bug 6425769
+ * @summary Test JMX agent host address binding. Same ports but different
+ * interfaces to bind to (using plain sockets and SSL sockets).
+ *
+ * @modules java.management/sun.management
+ * java.management/sun.management.jmxremote
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* JMXAgentInterfaceBinding
+ * @run main/timeout=5 JMXInterfaceBindingTest
+ */
+public class JMXInterfaceBindingTest {
+
+ public static final int COMMUNICATION_ERROR_EXIT_VAL = 1;
+ public static final int STOP_PROCESS_EXIT_VAL = 137;
+ public static final int JMX_PORT = 9111;
+ public static final int RMI_PORT = 9112;
+ public static final String READY_MSG = "MainThread: Ready for connections";
+ public static final String TEST_CLASS = JMXAgentInterfaceBinding.class.getSimpleName();
+ public static final String KEYSTORE_LOC = System.getProperty("test.src", ".") +
+ File.separator +
+ "ssl" +
+ File.separator +
+ "keystore";
+ public static final String TRUSTSTORE_LOC = System.getProperty("test.src", ".") +
+ File.separator +
+ "ssl" +
+ File.separator +
+ "truststore";
+ public static final String TEST_CLASSPATH = System.getProperty("test.classes", ".");
+
+ public void run(List<InetAddress> addrs) {
+ System.out.println("DEBUG: Running tests with plain sockets.");
+ runTests(addrs, false);
+ System.out.println("DEBUG: Running tests with SSL sockets.");
+ runTests(addrs, true);
+ }
+
+ private void runTests(List<InetAddress> addrs, boolean useSSL) {
+ TestProcessThread[] jvms = new TestProcessThread[addrs.size()];
+ for (int i = 0; i < addrs.size(); i++) {
+ String addr = JMXAgentInterfaceBinding.wrapAddress(addrs.get(i).getHostAddress());
+ System.out.println();
+ String msg = String.format("DEBUG: Launching java tester for triplet (HOSTNAME,JMX_PORT,RMI_PORT) == (%s,%d,%d)",
+ addr,
+ JMX_PORT,
+ RMI_PORT);
+ System.out.println(msg);
+ jvms[i] = runJMXBindingTest(addr, useSSL);
+ jvms[i].start();
+ System.out.println("DEBUG: Started " + (i + 1) + " Process(es).");
+ }
+ int failedProcesses = 0;
+ for (TestProcessThread pt: jvms) {
+ try {
+ pt.stopProcess();
+ pt.join();
+ } catch (InterruptedException e) {
+ System.err.println("Failed to stop process: " + pt.getName());
+ throw new RuntimeException("Test failed", e);
+ }
+ int exitValue = pt.getExitValue();
+ // If there is a communication error (the case we care about)
+ // we get a exit code of 1
+ if (exitValue == COMMUNICATION_ERROR_EXIT_VAL) {
+ // Failure case since the java processes should still be
+ // running.
+ System.err.println("Test FAILURE on " + pt.getName());
+ failedProcesses++;
+ } else if (exitValue == STOP_PROCESS_EXIT_VAL) {
+ System.out.println("DEBUG: OK. Spawned java process terminated with expected exit code of " + STOP_PROCESS_EXIT_VAL);
+ } else {
+ System.err.println("Test FAILURE on " + pt.getName() + " reason: Unexpected exit code => " + exitValue);
+ failedProcesses++;
+ }
+ }
+ if (failedProcesses > 0) {
+ throw new RuntimeException("Test FAILED. " + failedProcesses + " out of " + addrs.size() + " process(es) failed to start the JMX agent.");
+ }
+ }
+
+ private TestProcessThread runJMXBindingTest(String address, boolean useSSL) {
+ List<String> args = new ArrayList<>();
+ args.add("-classpath");
+ args.add(TEST_CLASSPATH);
+ args.add("-Dcom.sun.management.jmxremote.host=" + address);
+ args.add("-Dcom.sun.management.jmxremote.port=" + JMX_PORT);
+ args.add("-Dcom.sun.management.jmxremote.rmi.port=" + RMI_PORT);
+ args.add("-Dcom.sun.management.jmxremote.authenticate=false");
+ args.add("-Dcom.sun.management.jmxremote.ssl=" + Boolean.toString(useSSL));
+ if (useSSL) {
+ args.add("-Dcom.sun.management.jmxremote.registry.ssl=true");
+ args.add("-Djavax.net.ssl.keyStore=" + KEYSTORE_LOC);
+ args.add("-Djavax.net.ssl.trustStore=" + TRUSTSTORE_LOC);
+ args.add("-Djavax.net.ssl.keyStorePassword=password");
+ args.add("-Djavax.net.ssl.trustStorePassword=trustword");
+ }
+ args.add(TEST_CLASS);
+ args.add(address);
+ args.add(Integer.toString(JMX_PORT));
+ args.add(Integer.toString(RMI_PORT));
+ args.add(Boolean.toString(useSSL));
+ try {
+ ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(args.toArray(new String[] {}));
+ System.out.println(ProcessTools.getCommandLine(builder));
+ TestProcessThread jvm = new TestProcessThread("JMX-Tester-" + address, JMXInterfaceBindingTest::isJMXAgentResponseAvailable, builder);
+ return jvm;
+ } catch (Exception e) {
+ throw new RuntimeException("Test failed", e);
+ }
+
+ }
+
+ private static boolean isJMXAgentResponseAvailable(String line) {
+ if (line.equals(READY_MSG)) {
+ System.out.println("DEBUG: Found expected READY_MSG.");
+ return true;
+ } else if (line.startsWith("Error:")) {
+ // Allow for a JVM process that exits with
+ // "Error: JMX connector server communication error: ..."
+ // to continue as well since we handle that case elsewhere.
+ // This has the effect that the test does not timeout and
+ // fails with an exception in the test.
+ System.err.println("PROBLEM: JMX agent of target JVM did not start as it should.");
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static void main(String[] args) {
+ List<InetAddress> addrs = getAddressesForLocalHost();
+ if (addrs.size() < 2) {
+ System.out.println("Ignoring manual test since no more than one IPs are configured for 'localhost'");
+ return;
+ }
+ JMXInterfaceBindingTest test = new JMXInterfaceBindingTest();
+ test.run(addrs);
+ System.out.println("All tests PASSED.");
+ }
+
+ private static List<InetAddress> getAddressesForLocalHost() {
+ try {
+ List<InetAddress> filtered = new ArrayList<>();
+ for (NetworkInterface iface: Collections.list(NetworkInterface.getNetworkInterfaces())) {
+ for (InetAddress addr: Collections.list(iface.getInetAddresses())) {
+ if (isNonloopbackLocalhost(addr)) {
+ filtered.add(addr);
+ }
+ }
+ }
+ return filtered;
+ } catch (SocketException e) {
+ throw new RuntimeException("Test failed", e);
+ }
+ }
+
+ // we need 'real' localhost addresses only (eg. not loopback ones)
+ // so we can bind the remote JMX connector to them
+ private static boolean isNonloopbackLocalhost(InetAddress i) {
+ if (!i.isLoopbackAddress()) {
+ return i.getHostName().toLowerCase().equals("localhost");
+ }
+ return false;
+ }
+
+ private static class TestProcessThread extends Thread {
+
+ private final Predicate<String> predicate;
+ private final ProcessBuilder pb;
+ private final CountDownLatch latch;
+ private Process process;
+
+ public TestProcessThread(String threadName, Predicate<String> predicate, ProcessBuilder pb) {
+ super(threadName);
+ this.predicate = predicate;
+ this.pb = pb;
+ this.latch = new CountDownLatch(1);
+ }
+
+ @Override
+ public void run() {
+ try {
+ process = ProcessTools.startProcess(getName(), pb, predicate, 10, TimeUnit.SECONDS);
+ latch.countDown();
+ process.waitFor();
+ } catch (Exception e) {
+ throw new RuntimeException("Test failed", e);
+ }
+ }
+
+ public void stopProcess() {
+ try {
+ latch.await();
+ } catch (InterruptedException e1) {
+ throw new RuntimeException("Test failed", e1);
+ }
+ if (process != null) {
+ process.destroyForcibly();
+ try {
+ process.waitFor();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Test failed", e);
+ }
+ }
+ }
+
+ public int getExitValue() {
+ return process.exitValue();
+ }
+ }
+}
diff --git a/test/sun/security/TestSignatureOidHelper.java b/test/sun/security/TestSignatureOidHelper.java
new file mode 100644
index 0000000..be13599
--- /dev/null
+++ b/test/sun/security/TestSignatureOidHelper.java
@@ -0,0 +1,124 @@
+/*
+ * 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 + "]";
+ }
+}
diff --git a/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java b/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java
new file mode 100644
index 0000000..58a8106
--- /dev/null
+++ b/test/sun/security/ec/NSASuiteB/TestSHAwithECDSASignatureOids.java
@@ -0,0 +1,50 @@
+/*
+ * 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();
+ }
+}
diff --git a/test/sun/security/pkcs12/P12SecretKey.java b/test/sun/security/pkcs12/P12SecretKey.java
new file mode 100644
index 0000000..39f95d5
--- /dev/null
+++ b/test/sun/security/pkcs12/P12SecretKey.java
@@ -0,0 +1,87 @@
+/*
+ * 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 8149411
+ * @summary Get AES key from keystore (uses SecretKeySpec not SecretKeyFactory)
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+public class P12SecretKey {
+
+ private static final String ALIAS = "alias";
+
+ public static void main(String[] args) throws Exception {
+ P12SecretKey testp12 = new P12SecretKey();
+ String keystoreType = "pkcs12";
+ if (args != null && args.length > 0) {
+ keystoreType = args[0];
+ }
+ testp12.run(keystoreType);
+ }
+
+ private void run(String keystoreType) throws Exception {
+ char[] pw = "password".toCharArray();
+ KeyStore ks = KeyStore.getInstance(keystoreType);
+ ks.load(null, pw);
+
+ KeyGenerator kg = KeyGenerator.getInstance("AES");
+ kg.init(128);
+ SecretKey key = kg.generateKey();
+
+ KeyStore.SecretKeyEntry ske = new KeyStore.SecretKeyEntry(key);
+ KeyStore.ProtectionParameter kspp = new KeyStore.PasswordProtection(pw);
+ ks.setEntry(ALIAS, ske, kspp);
+
+ File ksFile = File.createTempFile("test", ".test");
+ try (FileOutputStream fos = new FileOutputStream(ksFile)) {
+ ks.store(fos, pw);
+ fos.flush();
+ }
+
+ // now see if we can get it back
+ try (FileInputStream fis = new FileInputStream(ksFile)) {
+ KeyStore ks2 = KeyStore.getInstance(keystoreType);
+ ks2.load(fis, pw);
+ KeyStore.Entry entry = ks2.getEntry(ALIAS, kspp);
+ SecretKey keyIn = ((KeyStore.SecretKeyEntry)entry).getSecretKey();
+ if (Arrays.equals(key.getEncoded(), keyIn.getEncoded())) {
+ System.err.println("OK: worked just fine with " + keystoreType +
+ " keystore");
+ } else {
+ System.err.println("ERROR: keys are NOT equal after storing in "
+ + keystoreType + " keystore");
+ }
+ }
+ }
+}
diff --git a/test/sun/security/pkcs12/StoreSecretKeyTest.java b/test/sun/security/pkcs12/StoreSecretKeyTest.java
index 97bc375..1588933 100644
--- a/test/sun/security/pkcs12/StoreSecretKeyTest.java
+++ b/test/sun/security/pkcs12/StoreSecretKeyTest.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,9 @@
/*
* @test
- * @bug 8005408 8079129
+ * @bug 8005408 8079129 8048830
* @summary KeyStore API enhancements
+ * @run main StoreSecretKeyTest
*/
import java.io.*;
@@ -44,9 +45,20 @@
private static final String CERT = DIR + "/trusted.pem";
private static final String ALIAS = "my trusted cert";
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 {
-
+ boolean isSecretkeyAlgSupported = false;
// Skip test if AES is unavailable
try {
SecretKeyFactory.getInstance("AES");
@@ -55,57 +67,69 @@
return;
}
+ for (ALGORITHM alg : ALGORITHM.values()) {
+ isSecretkeyAlgSupported |= testSecretKeyAlgorithm(alg);
+ }
+ if (!isSecretkeyAlgSupported) {
+ throw new Exception("None of the SecretKey algorithms is "
+ + "supported");
+ }
+ }
+
+ private static boolean testSecretKeyAlgorithm(ALGORITHM algorithm) throws
+ Exception {
+
+ System.out.println("Testing algorithm : " + algorithm.name());
new File(KEYSTORE).delete();
+ try {
+ KeyStore keystore = KeyStore.getInstance("PKCS12");
+ keystore.load(null, null);
- KeyStore keystore = KeyStore.getInstance("PKCS12");
- keystore.load(null, null);
-
- // Set trusted certificate entry
- Certificate cert = loadCertificate(CERT);
- keystore.setEntry(ALIAS,
+ // Set trusted certificate entry
+ Certificate cert = loadCertificate(CERT);
+ keystore.setEntry(ALIAS,
new KeyStore.TrustedCertificateEntry(cert), null);
-
- // Set secret key entry
- keystore.setEntry(ALIAS2,
- new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)),
+ // 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));
- try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
- System.out.println("Storing keystore to: " + KEYSTORE);
- keystore.store(outStream, PASSWORD);
- }
+ try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
+ System.out.println("Storing keystore to: " + KEYSTORE);
+ 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");
- }
+ 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,
- new KeyStore.PasswordProtection(PASSWORD));
- System.out.println("Retrieved entry: " + entry);
+ KeyStore.Entry entry = keystore.getEntry(ALIAS2,
+ new KeyStore.PasswordProtection(PASSWORD));
+ System.out.println("Retrieved entry: " + entry);
- if (entry instanceof KeyStore.SecretKeyEntry) {
- System.out.println("Retrieved secret key entry: " + entry);
- } else {
- 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)
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);
generator.init(size);
return generator.generateKey();
diff --git a/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java b/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java
new file mode 100644
index 0000000..43a857f
--- /dev/null
+++ b/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java
@@ -0,0 +1,185 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/test/sun/security/provider/NSASuiteB/TestSHAOids.java b/test/sun/security/provider/NSASuiteB/TestSHAOids.java
new file mode 100644
index 0000000..66d72b6
--- /dev/null
+++ b/test/sun/security/provider/NSASuiteB/TestSHAOids.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java b/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java
new file mode 100644
index 0000000..dad84cc
--- /dev/null
+++ b/test/sun/security/provider/NSASuiteB/TestSHAwithDSASignatureOids.java
@@ -0,0 +1,47 @@
+/*
+ * 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();
+ }
+}
diff --git a/test/sun/security/tools/jarsigner/TimestampCheck.java b/test/sun/security/tools/jarsigner/TimestampCheck.java
index 65b1cca..113bb26 100644
--- a/test/sun/security/tools/jarsigner/TimestampCheck.java
+++ b/test/sun/security/tools/jarsigner/TimestampCheck.java
@@ -24,10 +24,9 @@
import com.sun.net.httpserver.*;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
-import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
@@ -38,9 +37,15 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Calendar;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import sun.misc.IOUtils;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.PKCS9Attribute;
import sun.security.pkcs.SignerInfo;
+import sun.security.timestamp.TimestampToken;
import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
@@ -51,6 +56,8 @@
static final String TSKS = "tsks";
static final String JAR = "old.jar";
+ static final String defaultPolicyId = "2.3.4.5";
+
static class Handler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
int len = 0;
@@ -94,6 +101,11 @@
* 6: extension is missing
* 7: extension is non-critical
* 8: extension does not have timestamping
+ * 9: no cert in response
+ * 10: normal
+ * 11: always return default policy id
+ * 12: normal
+ * otherwise: normal
* @returns the signed
*/
byte[] sign(byte[] input, int path) throws Exception {
@@ -106,6 +118,7 @@
messageImprint.data.getDerValue());
System.err.println("AlgorithmId: " + aid);
+ ObjectIdentifier policyId = new ObjectIdentifier(defaultPolicyId);
BigInteger nonce = null;
while (value.data.available() > 0) {
DerValue v = value.data.getDerValue();
@@ -114,6 +127,9 @@
System.err.println("nonce: " + nonce);
} else if (v.tag == DerValue.tag_Boolean) {
System.err.println("certReq: " + v.getBoolean());
+ } else if (v.tag == DerValue.tag_ObjectId) {
+ policyId = v.getOID();
+ System.err.println("PolicyID: " + policyId);
}
}
@@ -127,6 +143,10 @@
if (path == 7) alias = "tsbad2";
if (path == 8) alias = "tsbad3";
+ if (path == 11) {
+ policyId = new ObjectIdentifier(defaultPolicyId);
+ }
+
DerOutputStream statusInfo = new DerOutputStream();
statusInfo.putInteger(0);
@@ -150,7 +170,7 @@
DerOutputStream tst = new DerOutputStream();
tst.putInteger(1);
- tst.putOID(new ObjectIdentifier("1.2.3.4")); // policy
+ tst.putOID(policyId);
if (path != 3 && path != 4) {
tst.putDerValue(messageImprint);
@@ -260,15 +280,43 @@
jarsigner(cmd, 7, false); // tsbad2
jarsigner(cmd, 8, false); // tsbad3
jarsigner(cmd, 9, false); // no cert in timestamp
- jarsigner(cmd + " -tsapolicyid 1.2.3.4", 0, true);
- jarsigner(cmd + " -tsapolicyid 1.2.3.5", 0, false);
+ jarsigner(cmd + " -tsapolicyid 1.2.3.4", 10, true);
+ checkTimestamp("new_10.jar", "1.2.3.4", "SHA-256");
+ jarsigner(cmd + " -tsapolicyid 1.2.3.5", 11, false);
+ jarsigner(cmd + " -tsadigestalg SHA", 12, true);
+ checkTimestamp("new_12.jar", defaultPolicyId, "SHA-1");
} else { // Run as a standalone server
System.err.println("Press Enter to quit server");
System.in.read();
}
} finally {
server.stop(0);
- new File("x.jar").delete();
+ }
+ }
+
+ static void checkTimestamp(String file, String policyId, String digestAlg)
+ throws Exception {
+ try (JarFile jf = new JarFile(file)) {
+ JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
+ try (InputStream is = jf.getInputStream(je)) {
+ byte[] content = IOUtils.readFully(is, -1, true);
+ PKCS7 p7 = new PKCS7(content);
+ SignerInfo[] si = p7.getSignerInfos();
+ if (si == null || si.length == 0) {
+ throw new Exception("Not signed");
+ }
+ PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
+ .getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
+ PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
+ TimestampToken tt =
+ new TimestampToken(tsToken.getContentInfo().getData());
+ if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
+ throw new Exception("Digest alg different");
+ }
+ if (!tt.getPolicyID().equals(policyId)) {
+ throw new Exception("policyId different");
+ }
+ }
}
}
diff --git a/test/sun/security/tools/jarsigner/ts.sh b/test/sun/security/tools/jarsigner/ts.sh
index 928b22e..6cee680 100644
--- a/test/sun/security/tools/jarsigner/ts.sh
+++ b/test/sun/security/tools/jarsigner/ts.sh
@@ -86,6 +86,6 @@
$KT -alias ca -gencert -ext eku:critical=cs | \
$KT -alias tsbad3 -importcert
-$JAVAC -d . ${TESTSRC}/TimestampCheck.java
+$JAVAC -XDignore.symbol.file -d . ${TESTSRC}/TimestampCheck.java
$JAVA ${TESTVMOPTS} TimestampCheck
diff --git a/test/sun/tools/jcmd/TestJcmdDefaults.java b/test/sun/tools/jcmd/TestJcmdDefaults.java
new file mode 100644
index 0000000..a531086
--- /dev/null
+++ b/test/sun/tools/jcmd/TestJcmdDefaults.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011, 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 jdk.testlibrary.Asserts.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import jdk.testlibrary.JcmdBase;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.Utils;
+
+/**
+ * Unit test for jcmd utility. Tests jcmd options which do not send
+ * requests to a specific JVM process.
+ */
+/*
+ * @test
+ * @bug 7104647
+ * @library /lib/testlibrary
+ * @run main TestJcmdDefaults
+ */
+public class TestJcmdDefaults {
+
+ private static final String TEST_SRC = System.getProperty("test.src").trim();
+ private static final String[] VM_ARGS = new String[] { "-XX:+UsePerfData" };
+ private static final String JCMD_LIST_REGEX = "^\\d+\\s*.*";
+
+ public static void main(String[] args) throws Exception {
+ testJcmdUsage("-h");
+ testJcmdUsage("-help");
+ testJcmdDefaults();
+ testJcmdDefaults("-l");
+ }
+
+ /**
+ * jcmd -J-XX:+UsePerfData -h
+ * jcmd -J-XX:+UsePerfData -help
+ */
+ private static void testJcmdUsage(String... jcmdArgs) throws Exception {
+ OutputAnalyzer output = JcmdBase.jcmdNoPid(VM_ARGS, jcmdArgs);
+
+ assertNotEquals(output.getExitValue(), 0);
+ verifyOutputAgainstFile(output);
+ }
+
+ /**
+ * jcmd -J-XX:+UsePerfData
+ * jcmd -J-XX:+UsePerfData -l
+ */
+ private static void testJcmdDefaults(String... jcmdArgs) throws Exception {
+ OutputAnalyzer output = JcmdBase.jcmdNoPid(VM_ARGS, jcmdArgs);
+
+ output.shouldHaveExitValue(0);
+ output.shouldContain("sun.tools.jcmd.JCmd");
+ matchListedProcesses(output);
+ }
+
+ /**
+ * Verifies the listed processes match a certain pattern.
+ *
+ * The output should look like:
+ * 12246 sun.tools.jcmd.JCmd
+ * 24428 com.sun.javatest.regtest.MainWrapper /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/TestJcmdDefaults.jta
+ *
+ * @param output The generated output from the jcmd.
+ * @throws Exception
+ */
+ private static void matchListedProcesses(OutputAnalyzer output) throws Exception {
+ int matchedCount = output.shouldMatchByLine(JCMD_LIST_REGEX);
+ assertGreaterThan(matchedCount , 0,
+ "Found no lines matching pattern: " + JCMD_LIST_REGEX);
+ }
+
+ private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
+ File file = new File(TEST_SRC, "usage.out");
+ List<String> fileOutput = Utils.fileAsList(file);
+ List<String> outputAsLines = output.asLines();
+ assertTrue(outputAsLines.containsAll(fileOutput),
+ "The ouput should contain all content of " + file.getAbsolutePath());
+ }
+
+}
diff --git a/test/sun/tools/jcmd/TestJcmdSanity.java b/test/sun/tools/jcmd/TestJcmdSanity.java
new file mode 100644
index 0000000..b25c4c5
--- /dev/null
+++ b/test/sun/tools/jcmd/TestJcmdSanity.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2011, 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 jdk.testlibrary.Asserts.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import jdk.testlibrary.JcmdBase;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.Utils;
+
+/**
+ * Unit test for jcmd utility. The test will send different diagnostic command
+ * requests to the current java process.
+ */
+/*
+ * @test
+ * @bug 7104647 7154822
+ * @library /lib/testlibrary
+ * @run main TestJcmdSanity
+ */
+public class TestJcmdSanity {
+
+ private static final String TEST_SRC = System.getProperty("test.src").trim();
+ private static final String[] VM_ARGS = new String[] { "-XX:+UsePerfData" };
+ private static final String JCMD_COMMAND_REGEX = "(\\w|\\.)*";
+ private static final String PERF_COUNTER_REGEX = "(\\w|\\.)*\\=.*";
+
+ public static void main(String[] args) throws Exception {
+ testJcmdPidHelp();
+ testJcmdPidHelpHelp();
+ testJcmdPid_f();
+ testJcmdPidPerfCounterPrint();
+ testJcmdPidBigScript();
+ }
+
+ /**
+ * jcmd -J-XX:+UsePerfData pid help
+ */
+ private static void testJcmdPidHelp() throws Exception {
+ OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+ new String[] {"help"});
+ output.shouldHaveExitValue(0);
+ output.shouldNotContain("Exception");
+ output.shouldContain(Integer.toString(ProcessTools.getProcessId()) + ":");
+ matchJcmdCommands(output);
+ output.shouldContain("For more information about a specific command use 'help <command>'.");
+ }
+
+ /**
+ * jcmd -J-XX:+UsePerfData pid help help
+ */
+ private static void testJcmdPidHelpHelp() throws Exception {
+ OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+ new String[] {"help", "help"});
+
+ output.shouldHaveExitValue(0);
+ verifyOutputAgainstFile(output);
+ }
+
+ /**
+ * jcmd -J-XX:+UsePerfData pid PerfCounter.print
+ */
+ private static void testJcmdPidPerfCounterPrint() throws Exception {
+ OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+ new String[] {"PerfCounter.print"});
+
+ output.shouldHaveExitValue(0);
+ matchPerfCounters(output);
+ }
+
+ /**
+ * jcmd -J-XX:+UsePerfData pid -f dcmd-script.txt
+ */
+ private static void testJcmdPid_f() throws Exception {
+ File scrpitFile = new File(TEST_SRC, "dcmd-script.txt");
+ OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+ new String[] {"-f", scrpitFile.getAbsolutePath()});
+
+ output.shouldHaveExitValue(0);
+ verifyOutputAgainstFile(output);
+ }
+
+ /**
+ * Tests that it possible send a file over 1024 bytes large via jcmd -f.
+ *
+ * jcmd -J-XX:+UsePerfData pid -f dcmd-big-script.txt
+ */
+ private static void testJcmdPidBigScript() throws Exception {
+ File scrpitFile = new File(TEST_SRC, "dcmd-big-script.txt");
+ OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+ new String[] {"-f", scrpitFile.getAbsolutePath()});
+
+ output.shouldHaveExitValue(0);
+ output.shouldNotContain("Exception");
+ output.shouldContain(System.getProperty("java.vm.name").trim());
+ }
+
+ /**
+ * Verifies the listed jcmd commands match a certain pattern.
+ *
+ * The output of the jcmd commands should look like:
+ * VM.uptime
+ * VM.flags
+ * VM.system_properties
+ *
+ * @param output The generated output from the jcmd.
+ * @throws Exception
+ */
+ private static void matchJcmdCommands(OutputAnalyzer output) throws Exception {
+ int matchedCount = output.shouldMatchByLine(JCMD_COMMAND_REGEX,
+ "help",
+ JCMD_COMMAND_REGEX);
+ assertGreaterThan(matchedCount , 0,
+ "Found no lines matching pattern: " + JCMD_COMMAND_REGEX);
+ }
+
+ /**
+ * Verifies the generated output from the PerfCounter.print command
+ * matches a certain pattern.
+ *
+ * The output of perf counters should look like:
+ * java.property.java.vm.name="Java HotSpot(TM) 64-Bit Server VM"
+ * java.threads.daemon=7
+ * sun.rt.javaCommand="com.sun.javatest.regtest.MainWrapper /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/TestJcmdSanity.jta"
+ *
+ * @param output The generated output from the PerfCounter.print command.
+ * @throws Exception
+ */
+ private static void matchPerfCounters(OutputAnalyzer output) throws Exception {
+ int matchedCount = output.shouldMatchByLineFrom(PERF_COUNTER_REGEX,
+ PERF_COUNTER_REGEX);
+ assertGreaterThan(matchedCount , 0,
+ "Found no lines matching pattern: " + PERF_COUNTER_REGEX);
+ }
+
+ private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
+ File file = new File(TEST_SRC, "help_help.out");
+ List<String> fileOutput = Utils.fileAsList(file);
+ List<String> outputAsLines = output.asLines();
+ assertTrue(outputAsLines.containsAll(fileOutput),
+ "The ouput should contain all content of " + file.getAbsolutePath());
+ }
+
+}
diff --git a/test/sun/tools/jcmd/help_help.out b/test/sun/tools/jcmd/help_help.out
index beaf0f3..3f151b9 100644
--- a/test/sun/tools/jcmd/help_help.out
+++ b/test/sun/tools/jcmd/help_help.out
@@ -1,7 +1,7 @@
help
For more information about a specific command use 'help <command>'. With no argument this will show a list of available commands. 'help all' will show help for all commands.
-Impact: Low
+Impact: Low
Syntax : help [options] [<command name>]
diff --git a/test/sun/tools/jcmd/jcmd-Defaults.sh b/test/sun/tools/jcmd/jcmd-Defaults.sh
deleted file mode 100644
index 2d6aa2e..0000000
--- a/test/sun/tools/jcmd/jcmd-Defaults.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2011, 2012, 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 7104647
-# @run shell jcmd-Defaults.sh
-# @summary Test that output of 'jcmd' and 'jcmd -l' match a specific pattern
-
-JCMD="${TESTJAVA}/bin/jcmd"
-
-${JCMD} -J-XX:+UsePerfData 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
-
-${JCMD} -J-XX:+UsePerfData -l 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
diff --git a/test/sun/tools/jcmd/jcmd-big-script.sh b/test/sun/tools/jcmd/jcmd-big-script.sh
deleted file mode 100644
index a101c8c..0000000
--- a/test/sun/tools/jcmd/jcmd-big-script.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2012, 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 7154822
-# @summary test if we can send a file over 1024 bytes large via jcmd -f
-# @author David Buck
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-big-script.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-failed=0;
-
-# -f <script>
-rm -f jcmd.out 2>/dev/null
-set +e # even if jcmd fails, we do not want abort the script yet.
-${JCMD} -J-XX:+UsePerfData $appJavaPid -f ${TESTSRC}/dcmd-big-script.txt > jcmd.out 2>&1
-status="$?"
-set -e
-if [ "$status" != 0 ]; then
- echo "jcmd command returned non-zero exit code (status=$status). Failed."
- failed=1;
-fi
-cat jcmd.out
-set +e # if the test passes, grep will "fail" with an exit code of 1
-grep Exception jcmd.out > /dev/null 2>&1
-status="$?"
-set -e
-if [ "$status" = 0 ]; then
- echo "Output of \"jcmd [pid] -f dcmd-big-script.txt\" contains string \"Exception\". Failed."
- failed=1;
-fi
-
-# clean up
-rm -f jcmd.out 2>/dev/null
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd-f.sh b/test/sun/tools/jcmd/jcmd-f.sh
deleted file mode 100644
index ad73bc7..0000000
--- a/test/sun/tools/jcmd/jcmd-f.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 2012, 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 7104647
-# @summary Unit test for jcmd utility
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-f.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-# all return statuses are checked in this test
-set +e
-
-failed=0
-
-# -f <script>
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData $appJavaPid -f ${TESTSRC}/dcmd-script.txt | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
-echo jcmd.out
-diff -w jcmd.out ${TESTSRC}/help_help.out
-if [ $? != 0 ]; then
- echo "Output of jcmd [pid] -f dcmd-script.txt differ from expected output. Failed."
- rm -f jcmd.out 2>/dev/null
- failed=1;
-fi
-
-set -e
-
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd-help-help.sh b/test/sun/tools/jcmd/jcmd-help-help.sh
deleted file mode 100644
index 2f99b6f..0000000
--- a/test/sun/tools/jcmd/jcmd-help-help.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 2012, 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 7104647
-# @summary Unit test for jcmd utility
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-help-help.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-# all return statuses are checked in this test
-set +e
-
-failed=0
-
-# help help
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData $appJavaPid help help | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
-echo jcmd.out
-diff -w jcmd.out ${TESTSRC}/help_help.out
-if [ $? != 0 ]; then
- echo "Output of jcmd [pid] help help differ from expected output. Failed."
- rm -f jcmd.out 2>/dev/null
- failed=1;
-fi
-
-set -e
-
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd-help.sh b/test/sun/tools/jcmd/jcmd-help.sh
deleted file mode 100644
index b640776..0000000
--- a/test/sun/tools/jcmd/jcmd-help.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2011, 2012, 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 7104647
-# @run shell jcmd-help.sh
-# @summary Test that output of 'jcmd -h' matches the usage.out file
-
-JCMD="${TESTJAVA}/bin/jcmd"
-
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData -h > jcmd.out 2>&1
-
-diff -w jcmd.out ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
- echo "Output of jcmd -h differ from expected output. Failed."
- rm -f jcmd.out 2>/dev/null
- exit 1
-fi
-
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData -help > jcmd.out 2>&1
-
-diff -w jcmd.out ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
- echo "Output of jcmd -help differ from expected output. Failed."
- rm -f jcmd.out 2>/dev/null
- exit 1
-fi
-
-rm -f jcmd.out 2>/dev/null
-exit 0
diff --git a/test/sun/tools/jcmd/jcmd-pid.sh b/test/sun/tools/jcmd/jcmd-pid.sh
deleted file mode 100644
index df39733..0000000
--- a/test/sun/tools/jcmd/jcmd-pid.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 2012, 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 7104647
-# @summary Unit test for jcmd utility
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-pid.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-# all return statuses are checked in this test
-set +e
-
-failed=0
-
-# help command
-${JCMD} -J-XX:+UsePerfData $appJavaPid help 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output1.awk
-if [ $? != 0 ]; then failed=1; fi
-
-# PerfCounter.list option
-${JCMD} -J-XX:+UsePerfData $appJavaPid PerfCounter.print 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output2.awk
-if [ $? != 0 ]; then failed=1; fi
-
-set -e
-
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd_Output1.awk b/test/sun/tools/jcmd/jcmd_Output1.awk
deleted file mode 100644
index 5bf0403..0000000
--- a/test/sun/tools/jcmd/jcmd_Output1.awk
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0; current=0
- }
-
-# match on a main class name followed by arbitrary arguments
-/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\.]*($| .*$)/ {
- current=1;
- }
-
-# or match on a path name to a jar or war file followed by arbitraty arguments
-# - note, jar files ending with ".jar" is only a convention, not a requirement.
-#Theoretically, any valid file name could occur here.
-/^[0-9]+ .*\.(jar|war)($| .*$)/ {
- current=1;
-}
-
-# or match on the condition that the class name is not available
-/^[0-9]+ -- .*$/ {
- current=1;
- }
-
-# or match an empty class name
-/^[0-9]+ $/ {
- current=1;
- }
-
- { totallines++; matched+=current; current=0; print $0 }
-
-END {
- if ((totallines > 0) && (matched == totallines)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jcmd/jcmd_pid_Output1.awk b/test/sun/tools/jcmd/jcmd_pid_Output1.awk
deleted file mode 100644
index 8ee49f0..0000000
--- a/test/sun/tools/jcmd/jcmd_pid_Output1.awk
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-
-# section 0 = [PID]:
-# section 1 = "The following commands are available:"
-# section 2 = <list of commands, one command per line>
-# section 3 = blank line
-# section 4 = "For more information about a specific command use 'help <command>'."
-
-BEGIN {
- totallines=0; matched=0; section=0;
-}
-
-# match the first line (PID of the JVM followed by ':')
-/^[0-9]+:/{
- if(section==0) {
- matched++;
- section=1;
- }
-}
-
-/^The following commands are available:$/{
- if(section==1) {
- matched++;
- section=2;
- }
-}
-
-# match a command name
-/^[a-z|A-Z][a-z|A-Z|0-9|\.|_]*$/{
- if(section==2) {
- matched++;
- }
-}
-
-/^$/{
- if(section==2) {
- matched++;
- section=4;
- }
-}
-
-/^For more information about a specific command use 'help <command>'\.$/{
- if(section==4) {
- matched++;
- section=5;
- }
-}
-
-{ totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched == totallines)) {
- exit 0
- }
- else {
- exit 1
- }
-}
diff --git a/test/sun/tools/jcmd/jcmd_pid_Output2.awk b/test/sun/tools/jcmd/jcmd_pid_Output2.awk
deleted file mode 100644
index 49f0632..0000000
--- a/test/sun/tools/jcmd/jcmd_pid_Output2.awk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-# match on counter name followed '=' and an arbitrary value
-/^[a-z|A-Z][a-z|A-Z|0-9|\.|_]*=.*$/ {
- matched++;
- }
-
-# or match the first line (PID of the JVM followed by ':')
-/^[0-9]+:/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched == totallines)) {
- exit 0
- }
- else {
- exit 1
- }
-}
diff --git a/test/sun/tools/jcmd/usage.out b/test/sun/tools/jcmd/usage.out
index 78ac0f3..48efa40 100644
--- a/test/sun/tools/jcmd/usage.out
+++ b/test/sun/tools/jcmd/usage.out
@@ -1,15 +1,15 @@
Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
- or: jcmd -l
- or: jcmd -h
+ or: jcmd -l
+ or: jcmd -h
- command must be a valid jcmd command for the selected jvm.
+ command must be a valid jcmd command for the selected jvm.
Use the command "help" to see which commands are available.
If the pid is 0, commands will be sent to all Java processes.
The main class argument will be used to match (either partially
or fully) the class used to start Java.
If no options are given, lists Java processes (same as -p).
- PerfCounter.print display the counters exposed by this process
+ PerfCounter.print display the counters exposed by this process
-f read and execute commands from the file
-l list JVM processes on the local machine
-h this help
diff --git a/test/sun/tools/jps/JpsBase.java b/test/sun/tools/jps/JpsBase.java
new file mode 100644
index 0000000..59b293b
--- /dev/null
+++ b/test/sun/tools/jps/JpsBase.java
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+/**
+ * The base class for testing the jps utility.
+ * The test sequence is to start jps with different combinations of arguments
+ * and verify the output contains proper values.
+ */
+public final class JpsBase {
+
+ private static final String shortProcessName;
+ private static final String fullProcessName;
+
+ /**
+ * The jps output should contain processes' names
+ * (except when jps is started in quite mode).
+ * The expected name of the test process is prepared here.
+ */
+ static {
+ URL url = JpsBase.class.getResource("JpsBase.class");
+ boolean isJar = url.getProtocol().equals("jar");
+
+ if (isJar) {
+ shortProcessName = JpsBase.class.getSimpleName() + ".jar";
+ String urlPath = url.getPath();
+ File jar = new File(urlPath.substring(urlPath.indexOf("file:") + 5, urlPath.indexOf("jar!") + 3));
+ fullProcessName = jar.getAbsolutePath();
+ } else {
+ shortProcessName = JpsBase.class.getSimpleName();
+ fullProcessName = JpsBase.class.getName();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ int pid = ProcessTools.getProcessId();
+
+ List<List<JpsHelper.JpsArg>> combinations = JpsHelper.JpsArg.generateCombinations();
+ for (List<JpsHelper.JpsArg> combination : combinations) {
+ OutputAnalyzer output = JpsHelper.jps(JpsHelper.JpsArg.asCmdArray(combination));
+ output.shouldHaveExitValue(0);
+
+ boolean isQuiet = false;
+ boolean isFull = false;
+ String pattern;
+ for (JpsHelper.JpsArg jpsArg : combination) {
+ switch (jpsArg) {
+ case q:
+ // If '-q' is specified output should contain only a list of local VM identifiers:
+ // 30673
+ isQuiet = true;
+ JpsHelper.verifyJpsOutput(output, "^\\d+$");
+ output.shouldContain(Integer.toString(pid));
+ break;
+ case l:
+ // If '-l' is specified output should contain the full package name for the application's main class
+ // or the full path name to the application's JAR file:
+ // 30673 /tmp/jtreg/jtreg-workdir/scratch/JpsBase.jar ...
+ isFull = true;
+ pattern = "^" + pid + "\\s+" + replaceSpecialChars(fullProcessName) + ".*";
+ output.shouldMatch(pattern);
+ break;
+ case m:
+ // If '-m' is specified output should contain the arguments passed to the main method:
+ // 30673 JpsBase monkey ...
+ for (String arg : args) {
+ pattern = "^" + pid + ".*" + replaceSpecialChars(arg) + ".*";
+ output.shouldMatch(pattern);
+ }
+ break;
+ case v:
+ // If '-v' is specified output should contain VM arguments:
+ // 30673 JpsBase -Xmx512m -XX:+UseParallelGC -XX:Flags=/tmp/jtreg/jtreg-workdir/scratch/vmflags ...
+ for (String vmArg : JpsHelper.getVmArgs()) {
+ pattern = "^" + pid + ".*" + replaceSpecialChars(vmArg) + ".*";
+ output.shouldMatch(pattern);
+ }
+ break;
+ case V:
+ // If '-V' is specified output should contain VM flags:
+ // 30673 JpsBase +DisableExplicitGC ...
+ pattern = "^" + pid + ".*" + replaceSpecialChars(JpsHelper.VM_FLAG) + ".*";
+ output.shouldMatch(pattern);
+ break;
+ }
+
+ if (isQuiet) {
+ break;
+ }
+ }
+
+ if (!isQuiet) {
+ // Verify output line by line.
+ // Output should only contain lines with pids after the first line with pid.
+ JpsHelper.verifyJpsOutput(output, "^\\d+\\s+.*");
+ if (!isFull) {
+ pattern = "^" + pid + "\\s+" + replaceSpecialChars(shortProcessName);
+ if (combination.isEmpty()) {
+ // If no arguments are specified output should only contain
+ // pid and process name
+ pattern += "$";
+ } else {
+ pattern += ".*";
+ }
+ output.shouldMatch(pattern);
+ }
+ }
+ }
+ }
+
+ private static String replaceSpecialChars(String str) {
+ String tmp = str.replace("\\", "\\\\");
+ tmp = tmp.replace("+", "\\+");
+ tmp = tmp.replace(".", "\\.");
+ return tmp;
+ }
+
+}
diff --git a/test/sun/tools/jps/JpsHelper.java b/test/sun/tools/jps/JpsHelper.java
new file mode 100644
index 0000000..eaa965d
--- /dev/null
+++ b/test/sun/tools/jps/JpsHelper.java
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+import static jdk.testlibrary.Asserts.assertGreaterThan;
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import jdk.testlibrary.Asserts;
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.Utils;
+
+/**
+ * The helper class for running jps utility and verifying output from it
+ */
+public final class JpsHelper {
+
+ /**
+ * Helper class for handling jps arguments
+ */
+ public enum JpsArg {
+ q,
+ l,
+ m,
+ v,
+ V;
+
+ /**
+ * Generate all possible combinations of {@link JpsArg}
+ * (31 argument combinations and no arguments case)
+ */
+ public static List<List<JpsArg>> generateCombinations() {
+ final int argCount = JpsArg.values().length;
+ // If there are more than 30 args this algorithm will overflow.
+ Asserts.assertLessThan(argCount, 31, "Too many args");
+
+ List<List<JpsArg>> combinations = new ArrayList<>();
+ int combinationCount = (int) Math.pow(2, argCount);
+ for (int currCombo = 0; currCombo < combinationCount; ++currCombo) {
+ List<JpsArg> combination = new ArrayList<>();
+ for (int position = 0; position < argCount; ++position) {
+ int bit = 1 << position;
+ if ((bit & currCombo) != 0) {
+ combination.add(JpsArg.values()[position]);
+ }
+ }
+ combinations.add(combination);
+ }
+ return combinations;
+ }
+
+ /**
+ * Return combination of {@link JpsArg} as a String array
+ */
+ public static String[] asCmdArray(List<JpsArg> jpsArgs) {
+ List<String> list = new ArrayList<>();
+ for (JpsArg jpsArg : jpsArgs) {
+ list.add("-" + jpsArg.toString());
+ }
+ return list.toArray(new String[list.size()]);
+ }
+
+ }
+
+ /**
+ * VM arguments to start test application with
+ */
+ public static final String[] VM_ARGS = {"-Xmx512m", "-XX:+PrintGCDetails"};
+ /**
+ * VM flag to start test application with
+ */
+ public static final String VM_FLAG = "+DisableExplicitGC";
+
+ private static File vmFlagsFile = null;
+ private static List<String> testVmArgs = null;
+ private static File manifestFile = null;
+
+ /**
+ * Create a file containing VM_FLAG in the working directory
+ */
+ public static File getVmFlagsFile() throws IOException {
+ if (vmFlagsFile == null) {
+ vmFlagsFile = new File("vmflags");
+ try (BufferedWriter output = new BufferedWriter(new FileWriter(vmFlagsFile))) {
+ output.write(VM_FLAG);
+ }
+ vmFlagsFile.deleteOnExit();
+ }
+ return vmFlagsFile;
+ }
+
+ /**
+ * Return a list of VM arguments
+ */
+ public static List<String> getVmArgs() throws IOException {
+ if (testVmArgs == null) {
+ testVmArgs = new ArrayList<>();
+ testVmArgs.addAll(Arrays.asList(VM_ARGS));
+ testVmArgs.add("-XX:Flags=" + getVmFlagsFile().getAbsolutePath());
+ }
+ return testVmArgs;
+ }
+
+ /**
+ * Start jps utility without any arguments
+ */
+ public static OutputAnalyzer jps() throws Exception {
+ return jps(null, null);
+ }
+
+ /**
+ * Start jps utility with tool arguments
+ */
+ public static OutputAnalyzer jps(String... toolArgs) throws Exception {
+ return jps(null, Arrays.asList(toolArgs));
+ }
+
+ /**
+ * Start jps utility with VM args and tool arguments
+ */
+ public static OutputAnalyzer jps(List<String> vmArgs, List<String> toolArgs) throws Exception {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
+ if (vmArgs != null) {
+ for (String vmArg : vmArgs) {
+ launcher.addVMArg(vmArg);
+ }
+ }
+ if (toolArgs != null) {
+ for (String toolArg : toolArgs) {
+ launcher.addToolArg(toolArg);
+ }
+ }
+
+ ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+ System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
+ OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+ System.out.println(output.getOutput());
+
+ return output;
+ }
+
+ /**
+ * Verify jps output contains pids and programs' name information.
+ * The function will discard any lines that come before the first line with pid.
+ * This can happen if the JVM outputs a warning message for some reason
+ * before running jps.
+ *
+ * The output can look like:
+ * 35536 Jps
+ * 35417 Main
+ * 31103 org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
+ */
+ public static void verifyJpsOutput(OutputAnalyzer output, String regex) throws Exception {
+ output.shouldHaveExitValue(0);
+ int matchedCount = output.shouldMatchByLineFrom(regex, regex);
+ assertGreaterThan(matchedCount , 0, "Found no lines matching pattern: " + regex);
+ }
+
+ /**
+ * Compare jps output with a content in a file line by line
+ */
+ public static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
+ String testSrc = System.getProperty("test.src", "?");
+ File file = new File(testSrc, "usage.out");
+ List<String> fileOutput = Utils.fileAsList(file);
+ List<String> outputAsLines = output.asLines();
+ assertTrue(outputAsLines.containsAll(fileOutput),
+ "The ouput should contain all content of " + file.getAbsolutePath());
+ }
+
+ private static File getManifest(String className) throws IOException {
+ if (manifestFile == null) {
+ manifestFile = new File(className + ".mf");
+ try (BufferedWriter output = new BufferedWriter(new FileWriter(manifestFile))) {
+ output.write("Main-Class: " + className + Utils.NEW_LINE);
+ }
+ }
+ return manifestFile;
+ }
+
+ /**
+ * Build a jar of test classes in runtime
+ */
+ public static File buildJar(String className) throws Exception {
+ File jar = new File(className + ".jar");
+
+ List<String> jarArgs = new ArrayList<>();
+ jarArgs.add("-cfm");
+ jarArgs.add(jar.getAbsolutePath());
+ File manifestFile = getManifest(className);
+ jarArgs.add(manifestFile.getAbsolutePath());
+ String testClassPath = System.getProperty("test.class.path", "?");
+ for (String path : testClassPath.split(File.pathSeparator)) {
+ jarArgs.add("-C");
+ jarArgs.add(path);
+ jarArgs.add(".");
+ }
+
+ System.out.println("Running jar " + jarArgs.toString());
+ sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
+ if (!jarTool.run(jarArgs.toArray(new String[jarArgs.size()]))) {
+ throw new Exception("jar failed: args=" + jarArgs.toString());
+ }
+
+ manifestFile.delete();
+ jar.deleteOnExit();
+
+ return jar;
+ }
+
+}
diff --git a/test/sun/tools/jps/TestJpsClass.java b/test/sun/tools/jps/TestJpsClass.java
new file mode 100644
index 0000000..0133e9c
--- /dev/null
+++ b/test/sun/tools/jps/TestJpsClass.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+/*
+ * @test
+ * @summary The test application will be started with java class:
+ * java JpsBase
+ * For all possible combinations of jps arguments a jps process
+ * will be started from within the test application.
+ * The output should contain proper values.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* JpsHelper JpsBase
+ * @run driver TestJpsClass
+ */
+public class TestJpsClass {
+
+ public static void main(String[] args) throws Throwable {
+ String testJdk = System.getProperty("test.jdk", "?");
+ String testSrc = System.getProperty("test.src", "?");
+ String testClassPath = System.getProperty("test.class.path", "?");
+
+ List<String> cmd = new ArrayList<>();
+ cmd.addAll(JpsHelper.getVmArgs());
+ cmd.add("-Dtest.jdk=" + testJdk);
+ cmd.add("-Dtest.src=" + testSrc);
+ cmd.add("-cp");
+ cmd.add(testClassPath);
+ cmd.add("JpsBase");
+ cmd.add("monkey");
+
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(cmd.toArray(new String[cmd.size()]));
+ OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+ System.out.println(output.getOutput());
+ output.shouldHaveExitValue(0);
+ }
+
+}
diff --git a/test/sun/tools/jps/TestJpsJar.java b/test/sun/tools/jps/TestJpsJar.java
new file mode 100644
index 0000000..37230ae
--- /dev/null
+++ b/test/sun/tools/jps/TestJpsJar.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+/*
+ * @test
+ * @summary The test application will be started with absolute jar:
+ * java -jar /tmp/jtreg/jtreg-workdir/scratch/JpsBase.jar
+ * For all possible combinations of jps arguments a jps process
+ * will be started from within the test application.
+ * The output should contain proper values.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* JpsHelper JpsBase
+ * @run driver TestJpsJar
+ */
+public class TestJpsJar {
+
+ public static void main(String[] args) throws Throwable {
+ String testJdk = System.getProperty("test.jdk", "?");
+ String testSrc = System.getProperty("test.src", "?");
+ File jar = JpsHelper.buildJar("JpsBase");
+
+ List<String> cmd = new ArrayList<>();
+ cmd.addAll(JpsHelper.getVmArgs());
+ cmd.add("-Dtest.jdk=" + testJdk);
+ cmd.add("-Dtest.src=" + testSrc);
+ cmd.add("-jar");
+ cmd.add(jar.getAbsolutePath());
+ cmd.add("monkey");
+
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(cmd.toArray(new String[cmd.size()]));
+ OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+ System.out.println(output.getOutput());
+ output.shouldHaveExitValue(0);
+ }
+
+}
diff --git a/test/sun/tools/jps/TestJpsJarRelative.java b/test/sun/tools/jps/TestJpsJarRelative.java
new file mode 100644
index 0000000..8b7def5
--- /dev/null
+++ b/test/sun/tools/jps/TestJpsJarRelative.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+/*
+ * @test
+ * @summary The test application will be started with relative jar:
+ * java -jar ./JpsBase.jar
+ * For all possible combinations of jps arguments a jps process
+ * will be started from within the test application.
+ * The output should contain proper values.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* JpsHelper JpsBase
+ * @run driver TestJpsJarRelative
+ */
+public class TestJpsJarRelative {
+
+ public static void main(String[] args) throws Throwable {
+ String testJdk = System.getProperty("test.jdk", "?");
+ String testSrc = System.getProperty("test.src", "?");
+ File jar = JpsHelper.buildJar("JpsBase");
+
+ List<String> cmd = new ArrayList<>();
+ cmd.addAll(JpsHelper.getVmArgs());
+ cmd.add("-Dtest.jdk=" + testJdk);
+ cmd.add("-Dtest.src=" + testSrc);
+ cmd.add("-jar");
+ cmd.add("." + File.separator + jar.getName());
+ cmd.add("monkey");
+
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(cmd.toArray(new String[cmd.size()]));
+ OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+ System.out.println(output.getOutput());
+ output.shouldHaveExitValue(0);
+ }
+
+}
diff --git a/test/sun/tools/jps/TestJpsSanity.java b/test/sun/tools/jps/TestJpsSanity.java
new file mode 100644
index 0000000..5a0868a
--- /dev/null
+++ b/test/sun/tools/jps/TestJpsSanity.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+import jdk.testlibrary.Asserts;
+import jdk.testlibrary.OutputAnalyzer;
+
+/*
+ * @test
+ * @summary This test verifies jps usage and checks that appropriate error message is shown
+ * when running jps with illegal arguments.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* JpsHelper
+ * @run driver TestJpsSanity
+ */
+public class TestJpsSanity {
+
+ public static void main(String[] args) throws Throwable {
+ testJpsUsage();
+ testJpsVersion();
+ testJpsUnknownHost();
+ }
+
+ private static void testJpsUsage() throws Exception {
+ OutputAnalyzer output = JpsHelper.jps("-?");
+ JpsHelper.verifyOutputAgainstFile(output);
+
+ output = JpsHelper.jps("-help");
+ JpsHelper.verifyOutputAgainstFile(output);
+ }
+
+ private static void testJpsVersion() throws Exception {
+ OutputAnalyzer output = JpsHelper.jps("-version");
+ Asserts.assertNotEquals(output.getExitValue(), 0, "Exit code shouldn't be 0");
+ Asserts.assertFalse(output.getStderr().isEmpty(), "Error output should not be empty");
+ output.shouldContain("illegal argument: -version");
+ }
+
+ private static void testJpsUnknownHost() throws Exception {
+ String invalidHostName = "Oja781nh2ev7vcvbajdg-Sda1-C";
+ OutputAnalyzer output = JpsHelper.jps(invalidHostName);
+ Asserts.assertNotEquals(output.getExitValue(), 0, "Exit code shouldn't be 0");
+ Asserts.assertFalse(output.getStderr().isEmpty(), "Error output should not be empty");
+ output.shouldContain("Unknown host: " + invalidHostName);
+ }
+
+}
diff --git a/test/sun/tools/jps/jps-Defaults.sh b/test/sun/tools/jps/jps-Defaults.sh
deleted file mode 100644
index a8cd1ad..0000000
--- a/test/sun/tools/jps/jps-Defaults.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-Defaults.sh
-# @summary Test that output of 'jps' matches a specific pattern
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData 2>&1 | awk -f ${TESTSRC}/jps_Output1.awk
diff --git a/test/sun/tools/jps/jps-V_2.sh b/test/sun/tools/jps/jps-V_2.sh
deleted file mode 100644
index 2ab10ee..0000000
--- a/test/sun/tools/jps/jps-V_2.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 4990825
-# @run shell jps-V_2.sh
-# @summary Test that output of 'jps -V' shows JVM flags
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -J-XX:Flags=${TESTSRC}/vmflags -V | awk -f ${TESTSRC}/jps-V_Output2.awk
diff --git a/test/sun/tools/jps/jps-V_Output2.awk b/test/sun/tools/jps/jps-V_Output2.awk
deleted file mode 100644
index 3f1be04..0000000
--- a/test/sun/tools/jps/jps-V_Output2.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Jps.* \+DisableExplicitGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-Vm_2.sh b/test/sun/tools/jps/jps-Vm_2.sh
deleted file mode 100644
index ba9fa0f..0000000
--- a/test/sun/tools/jps/jps-Vm_2.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-Vm_2.sh
-# @summary Test that output of 'jps -Vm' shows JVM flags and main args
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -J-XX:Flags=${TESTSRC}/vmflags -Vm | awk -f ${TESTSRC}/jps-Vm_Output2.awk
diff --git a/test/sun/tools/jps/jps-Vm_Output2.awk b/test/sun/tools/jps/jps-Vm_Output2.awk
deleted file mode 100644
index 65f358b..0000000
--- a/test/sun/tools/jps/jps-Vm_Output2.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Jps -Vm.* \+DisableExplicitGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-Vvm.sh b/test/sun/tools/jps/jps-Vvm.sh
deleted file mode 100644
index d60896a..0000000
--- a/test/sun/tools/jps/jps-Vvm.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-Vvm.sh
-# @summary Test that output of 'jps -Vvm' shows JVM flags, arguments and main args
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -J-XX:Flags=${TESTSRC}/vmflags -Vvm | awk -f ${TESTSRC}/jps-Vvm_Output1.awk
diff --git a/test/sun/tools/jps/jps-Vvm_Output1.awk b/test/sun/tools/jps/jps-Vvm_Output1.awk
deleted file mode 100644
index 99187dc..0000000
--- a/test/sun/tools/jps/jps-Vvm_Output1.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Jps -Vvm.*-XX:Flags=.*vmflags.* \+DisableExplicitGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-Vvml.sh b/test/sun/tools/jps/jps-Vvml.sh
deleted file mode 100644
index f8d5fa3..0000000
--- a/test/sun/tools/jps/jps-Vvml.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-Vvml.sh
-# @summary Test that output of 'jps -Vvml' shows JVM arguments, flags, and main args with long class names
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -J-XX:Flags=${TESTSRC}/vmflags -Vvml | awk -f ${TESTSRC}/jps-Vvml_Output1.awk
diff --git a/test/sun/tools/jps/jps-Vvml_2.sh b/test/sun/tools/jps/jps-Vvml_2.sh
deleted file mode 100644
index 6fc88a3..0000000
--- a/test/sun/tools/jps/jps-Vvml_2.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 5009652
-# @library ../../jvmstat/testlibrary
-# @build Sleeper
-# @run shell jps-Vvml_2.sh
-# @summary Test that output of 'jps -Vvml' shows proper output when no JVM arguments, flags, or main args are present
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-cleanup() {
- kill_proc ${SLEEPER_PID}
-}
-
-trap 'cleanup' 0 HUP INT QUIT TERM
-
-JPS="${TESTJAVA}/bin/jps"
-
-JAVA="${TESTJAVA}/bin/java"
-
-# fire up a Sleeper that block indefinitely - but don't pass
-# any args to Sleeper.main() or any jvm flags or options, as we
-# need to inspect jps output for the no args condition.
-#
-# Note: this test can not pass on a VM with UsePerfData disabled by default,
-# and we can not set -XX:+UsePerfData as that invalidates the test premise of
-# there being no jvm flags
-
-${JAVA} -cp ${TESTCLASSPATH:-${TESTCLASSES}} Sleeper &
-SLEEPER_PID=$!
-
-${JPS} -J-XX:Flags=${TESTSRC}/vmflags -Vvml | awk -f ${TESTSRC}/jps-Vvml_Output2.awk
-RC=$?
-
-cleanup
-
-exit ${RC}
-
diff --git a/test/sun/tools/jps/jps-Vvml_Output1.awk b/test/sun/tools/jps/jps-Vvml_Output1.awk
deleted file mode 100644
index b4d4191..0000000
--- a/test/sun/tools/jps/jps-Vvml_Output1.awk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ sun.tools.jps.Jps -Vvml.*-XX:Flags=.*vmflags.* \+DisableExplicitGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-Vvml_Output2.awk b/test/sun/tools/jps/jps-Vvml_Output2.awk
deleted file mode 100644
index e7cad75..0000000
--- a/test/sun/tools/jps/jps-Vvml_Output2.awk
+++ /dev/null
@@ -1,24 +0,0 @@
-# 1.1 04/03/08
-
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Sleeper$/ {
- matched++;
- }
-
-/^[0-9]+ sun.tools.jps.Jps -Vvml.*-XX:Flags=.*vmflags.* \+DisableExplicitGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 2)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-help.sh b/test/sun/tools/jps/jps-help.sh
deleted file mode 100644
index c6c1cbd..0000000
--- a/test/sun/tools/jps/jps-help.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-help.sh
-# @summary Test that output of 'jps -?' matches the usage.out file
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-
-JPS="${TESTJAVA}/bin/jps"
-
-rm -f jps.out 2>/dev/null
-${JPS} -J-XX:+UsePerfData -? > jps.out 2>&1
-
-diff -w jps.out ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
- echo "Output of jps -? differ from expected output. Failed."
- rm -f jps.out 2>/dev/null
- exit 1
-fi
-
-rm -f jps.out 2>/dev/null
-${JPS} -J-XX:+UsePerfData -help > jps.out 2>&1
-
-diff -w jps.out ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
- echo "Output of jps -help differ from expected output. Failed."
- rm -f jps.out 2>/dev/null
- exit 1
-fi
-
-exit 0
diff --git a/test/sun/tools/jps/jps-l_1.sh b/test/sun/tools/jps/jps-l_1.sh
deleted file mode 100644
index 4cb65ea..0000000
--- a/test/sun/tools/jps/jps-l_1.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-l_1.sh
-# @summary Test that output of 'jps -l' matches a specific pattern
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -l 2>&1 | awk -f ${TESTSRC}/jps-l_Output1.awk
diff --git a/test/sun/tools/jps/jps-l_2.sh b/test/sun/tools/jps/jps-l_2.sh
deleted file mode 100644
index 95784db..0000000
--- a/test/sun/tools/jps/jps-l_2.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-l_2.sh
-# @summary Test that output of 'jps -l' shows the long class name
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -l | awk -f ${TESTSRC}/jps-l_Output2.awk
diff --git a/test/sun/tools/jps/jps-l_Output1.awk b/test/sun/tools/jps/jps-l_Output1.awk
deleted file mode 100644
index 08a48c1..0000000
--- a/test/sun/tools/jps/jps-l_Output1.awk
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-# match on a fully qualified class name
-/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\.|\$|\+]*$/ {
- matched++;
- }
-
-# or match on a jar or war file name - note, jar files ending with
-# ".jar" is only a convention , not a requirement. Theoretically,
-# any valid file name could occur here.
-/^[0-9]+ .*\.(jar|war)$/ {
- matched++;
-}
-
-# or match on the condition that the class name is not available
-/^[0-9]+ -- .*$/ {
- matched++;
- }
-
-# or match an empty class name
-/^[0-9]+ $/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched == totallines)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-l_Output2.awk b/test/sun/tools/jps/jps-l_Output2.awk
deleted file mode 100644
index 4df71f0..0000000
--- a/test/sun/tools/jps/jps-l_Output2.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ sun.tools.jps.Jps$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-lm.sh b/test/sun/tools/jps/jps-lm.sh
deleted file mode 100644
index 4a45512..0000000
--- a/test/sun/tools/jps/jps-lm.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-lm.sh
-# @summary Test that output of 'jps -lm' shows the long class name and main args
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -lm | awk -f ${TESTSRC}/jps-lm_Output1.awk
diff --git a/test/sun/tools/jps/jps-lm_Output1.awk b/test/sun/tools/jps/jps-lm_Output1.awk
deleted file mode 100644
index e3fcbee..0000000
--- a/test/sun/tools/jps/jps-lm_Output1.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ sun.tools.jps.Jps -lm$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-m.sh b/test/sun/tools/jps/jps-m.sh
deleted file mode 100644
index f900b9f..0000000
--- a/test/sun/tools/jps/jps-m.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-m.sh
-# @summary Test that output of 'jps -m' shows args to main
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -m | awk -f ${TESTSRC}/jps-m_Output1.awk
diff --git a/test/sun/tools/jps/jps-m_2.sh b/test/sun/tools/jps/jps-m_2.sh
deleted file mode 100644
index b881c35..0000000
--- a/test/sun/tools/jps/jps-m_2.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 5009652
-# @library ../../jvmstat/testlibrary
-# @build Sleeper
-# @run shell jps-m_2.sh
-# @summary Test that output of 'jps -m' shows proper output for main with no args.
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-cleanup() {
- kill_proc ${SLEEPER_PID}
-}
-
-trap 'cleanup' 0 HUP INT QUIT TERM
-
-JPS="${TESTJAVA}/bin/jps"
-JAVA="${TESTJAVA}/bin/java"
-
-# fire up a Sleeper that blocks indefinitely - but don't pass
-# any args to Sleeper.main(), as we need to inspect jps output
-# for the no args condition.
-#
-${JAVA} -XX:+UsePerfData -cp ${TESTCLASSPATH:-${TESTCLASSES}} Sleeper &
-SLEEPER_PID=$!
-
-${JPS} -J-XX:+UsePerfData -m | awk -f ${TESTSRC}/jps-m_Output2.awk
-RC=$?
-
-cleanup
-
-exit ${RC}
-
diff --git a/test/sun/tools/jps/jps-m_Output1.awk b/test/sun/tools/jps/jps-m_Output1.awk
deleted file mode 100644
index 560f6e8..0000000
--- a/test/sun/tools/jps/jps-m_Output1.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Jps -m$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-m_Output2.awk b/test/sun/tools/jps/jps-m_Output2.awk
deleted file mode 100644
index 0ba09ad..0000000
--- a/test/sun/tools/jps/jps-m_Output2.awk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Sleeper$/ {
- matched++;
- }
-
-/^[0-9]+ Jps -m$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 2)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-q.sh b/test/sun/tools/jps/jps-q.sh
deleted file mode 100644
index cd6a4ac..0000000
--- a/test/sun/tools/jps/jps-q.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-q.sh
-# @summary Test that output of 'jps -q' shows only the process ids
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -q | awk -f ${TESTSRC}/jps-q_Output1.awk
diff --git a/test/sun/tools/jps/jps-q_Output1.awk b/test/sun/tools/jps/jps-q_Output1.awk
deleted file mode 100644
index 53ae3a8..0000000
--- a/test/sun/tools/jps/jps-q_Output1.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-v_1.sh b/test/sun/tools/jps/jps-v_1.sh
deleted file mode 100644
index 21d0852..0000000
--- a/test/sun/tools/jps/jps-v_1.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-v_1.sh
-# @summary Test that output of 'jps -v' shows JVM arguments
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -J-XX:+UseParallelGC -v | awk -f ${TESTSRC}/jps-v_Output1.awk
diff --git a/test/sun/tools/jps/jps-v_Output1.awk b/test/sun/tools/jps/jps-v_Output1.awk
deleted file mode 100644
index 02ad298..0000000
--- a/test/sun/tools/jps/jps-v_Output1.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Jps.* -XX:\+UseParallelGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps-vm_1.sh b/test/sun/tools/jps/jps-vm_1.sh
deleted file mode 100644
index 80bb62e..0000000
--- a/test/sun/tools/jps/jps-vm_1.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (c) 2004, 2011, 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 4990825
-# @run shell jps-vm_1.sh
-# @summary Test that output of 'jps -vm' shows JVM arguments and main args
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-JPS="${TESTJAVA}/bin/jps"
-
-${JPS} -J-XX:+UsePerfData -J-XX:+UseParallelGC -vm | awk -f ${TESTSRC}/jps-vm_Output1.awk
diff --git a/test/sun/tools/jps/jps-vm_Output1.awk b/test/sun/tools/jps/jps-vm_Output1.awk
deleted file mode 100644
index 0cda3ca..0000000
--- a/test/sun/tools/jps/jps-vm_Output1.awk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-/^[0-9]+ Jps -vm.* -XX:\+UseParallelGC$/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched >= 1)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/jps_Output1.awk b/test/sun/tools/jps/jps_Output1.awk
deleted file mode 100644
index c64b0f1..0000000
--- a/test/sun/tools/jps/jps_Output1.awk
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-BEGIN {
- totallines=0; matched=0
- }
-
-# match on a main class name
-/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\$|\+]*$/ {
- matched++;
- }
-
-# or match on a path name to a jar or war file - note, jar files ending with
-# ".jar" is only a convention, not a requirement. Theoretically,
-# any valid file name could occur here.
-/^[0-9]+ .*\.(jar|war)$/ {
- matched++;
-}
-
-# or match on the condition that the class name is not available
-/^[0-9]+ -- .*$/ {
- matched++;
- }
-
-# or match an empty class name
-/^[0-9]+ $/ {
- matched++;
- }
-
- { totallines++; print $0 }
-
-END {
- if ((totallines > 0) && (matched == totallines)) {
- exit 0
- }
- else {
- exit 1
- }
- }
diff --git a/test/sun/tools/jps/vmflags b/test/sun/tools/jps/vmflags
deleted file mode 100644
index be0e23c..0000000
--- a/test/sun/tools/jps/vmflags
+++ /dev/null
@@ -1 +0,0 @@
-+DisableExplicitGC
diff --git a/test/sun/tools/native2ascii/NativeErrors.java b/test/sun/tools/native2ascii/NativeErrors.java
index 00493b8..02ca853 100644
--- a/test/sun/tools/native2ascii/NativeErrors.java
+++ b/test/sun/tools/native2ascii/NativeErrors.java
@@ -75,7 +75,14 @@
throw new Error("Output file cannot be made read only: " + path2);
}
f2.deleteOnExit();
- checkResult(executeCmd(path1, path2), "err.cannot.write");
+ if ( f2.canWrite() ) {
+ String msg = "Output file is still writable. " +
+ "Probably because test is run as root. Read-only test skipped.";
+ System.out.println(msg);
+ } else {
+ // Test write to a read-only file.
+ checkResult(executeCmd(path1, path2), "err.cannot.write");
+ }
}
private static String executeCmd(String... toolArgs) throws Throwable {