summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--JavaLibrary.mk10
-rw-r--r--dalvik/src/main/java/dalvik/system/Zygote.java57
-rw-r--r--expectations/brokentests.txt7
-rw-r--r--luni/src/main/java/java/lang/Object.java2
-rw-r--r--luni/src/main/java/java/util/Locale.java11
-rw-r--r--luni/src/main/java/libcore/io/DropBox.java72
-rw-r--r--luni/src/main/java/libcore/io/EventLogger.java69
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CertPinManager.java184
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java24
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java6
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherRSA.java24
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java44
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateCrtKey.java43
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateKey.java9
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java62
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinEntryException.java29
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinFailureLogger.java70
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinListEntry.java155
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinManagerException.java32
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketFactoryImpl.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketImpl.java37
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketWrapper.java5
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java138
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStore.java8
-rw-r--r--luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp109
-rw-r--r--luni/src/main/native/zip.h2
-rwxr-xr-xluni/src/test/java/libcore/java/io/InterruptedStreamTest.java50
-rw-r--r--luni/src/test/java/libcore/java/lang/OldObjectTest.java31
-rw-r--r--luni/src/test/java/libcore/java/net/OldSocketTest.java437
-rw-r--r--luni/src/test/java/libcore/java/security/KeyStoreTest.java467
-rw-r--r--luni/src/test/java/libcore/java/util/LocaleTest.java10
-rw-r--r--luni/src/test/java/libcore/javax/crypto/CipherTest.java769
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java49
-rw-r--r--luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java6
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyRepTest.java135
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreLoadStoreParameterTest.java15
-rw-r--r--luni/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java108
-rw-r--r--luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java175
-rw-r--r--luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java168
-rw-r--r--luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImplTest.java133
-rw-r--r--luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStoreTest.java20
-rw-r--r--luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java56
-rw-r--r--support/src/test/java/libcore/java/security/StandardNames.java14
43 files changed, 2777 insertions, 1077 deletions
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 59ac2e1..26a586a 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -55,9 +55,11 @@ core_resource_dirs := $(call all-core-resource-dirs,main)
test_resource_dirs := $(call all-core-resource-dirs,test)
ifeq ($(EMMA_INSTRUMENT),true)
+ifneq ($(EMMA_INSTRUMENT_STATIC),true)
core_src_files += $(call all-java-files-under, ../external/emma/core ../external/emma/pregenerated)
core_resource_dirs += ../external/emma/core/res ../external/emma/pregenerated/res
endif
+endif
local_javac_flags=-encoding UTF-8
#local_javac_flags+=-Xlint:all -Xlint:-serial,-deprecation,-unchecked
@@ -78,8 +80,6 @@ LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_DX_FLAGS := --core-library
-LOCAL_NO_EMMA_INSTRUMENT := true
-LOCAL_NO_EMMA_COMPILE := true
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := core
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -100,8 +100,6 @@ LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE_TAGS := tests
LOCAL_MODULE := core-tests
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
-LOCAL_NO_EMMA_INSTRUMENT := true
-LOCAL_NO_EMMA_COMPILE := true
include $(BUILD_STATIC_JAVA_LIBRARY)
# This one's tricky. One of our tests needs to have a
@@ -136,8 +134,6 @@ ifeq ($(WITH_HOST_DALVIK),true)
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_DX_FLAGS := --core-library
- LOCAL_NO_EMMA_INSTRUMENT := true
- LOCAL_NO_EMMA_COMPILE := true
LOCAL_BUILD_HOST_DEX := true
LOCAL_MODULE_TAGS := optional
@@ -157,8 +153,6 @@ ifeq ($(WITH_HOST_DALVIK),true)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := core-tests-hostdex
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
- LOCAL_NO_EMMA_INSTRUMENT := true
- LOCAL_NO_EMMA_COMPILE := true
LOCAL_BUILD_HOST_DEX := true
include $(BUILD_HOST_JAVA_LIBRARY)
endif
diff --git a/dalvik/src/main/java/dalvik/system/Zygote.java b/dalvik/src/main/java/dalvik/system/Zygote.java
index ec114ed..c06314e 100644
--- a/dalvik/src/main/java/dalvik/system/Zygote.java
+++ b/dalvik/src/main/java/dalvik/system/Zygote.java
@@ -41,6 +41,15 @@ public class Zygote {
/** Enable logging of third-party JNI activity. */
public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
+ /** No external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_NONE = 0;
+ /** Single-user external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_SINGLEUSER = 1;
+ /** Multi-user external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_MULTIUSER = 2;
+ /** All multi-user external storage should be mounted. */
+ public static final int MOUNT_EXTERNAL_MULTIUSER_ALL = 3;
+
/**
* When set by the system server, all subsequent apps will be launched in
* VM safe mode.
@@ -114,27 +123,17 @@ public class Zygote {
* @return 0 if this is the child, pid of the child
* if this is the parent, or -1 on error.
*/
- public static int forkAndSpecialize(int uid, int gid, int[] gids,
- int debugFlags, int[][] rlimits, String seInfo, String niceName) {
+ public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
+ int[][] rlimits, int mountExternal, String seInfo, String niceName) {
preFork();
- int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits, seInfo, niceName);
+ int pid = nativeForkAndSpecialize(
+ uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName);
postFork();
return pid;
}
- native public static int nativeForkAndSpecialize(int uid, int gid,
- int[] gids, int debugFlags, int[][] rlimits, String seInfo, String niceName);
-
- /**
- * Forks a new VM instance.
- * @deprecated use {@link Zygote#forkAndSpecialize(int, int, int[], int, int[][])}
- */
- @Deprecated
- public static int forkAndSpecialize(int uid, int gid, int[] gids,
- boolean enableDebugger, int[][] rlimits) {
- int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
- return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits, null, null);
- }
+ native public static int nativeForkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
+ int[][] rlimits, int mountExternal, String seInfo, String niceName);
/**
* Special method to start the system server process. In addition to the
@@ -159,31 +158,17 @@ public class Zygote {
* @return 0 if this is the child, pid of the child
* if this is the parent, or -1 on error.
*/
- public static int forkSystemServer(int uid, int gid, int[] gids,
- int debugFlags, int[][] rlimits,
- long permittedCapabilities, long effectiveCapabilities) {
+ public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
+ int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
preFork();
- int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits,
- permittedCapabilities,
- effectiveCapabilities);
+ int pid = nativeForkSystemServer(
+ uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
postFork();
return pid;
}
- /**
- * Special method to start the system server process.
- * @deprecated use {@link Zygote#forkSystemServer(int, int, int[], int, int[][])}
- */
- @Deprecated
- public static int forkSystemServer(int uid, int gid, int[] gids,
- boolean enableDebugger, int[][] rlimits) {
- int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
- return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits, null, null);
- }
-
- native public static int nativeForkSystemServer(int uid, int gid,
- int[] gids, int debugFlags, int[][] rlimits,
- long permittedCapabilities, long effectiveCapabilities);
+ native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
+ int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
/**
* Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
diff --git a/expectations/brokentests.txt b/expectations/brokentests.txt
index 6fc48cd..e1d81e0 100644
--- a/expectations/brokentests.txt
+++ b/expectations/brokentests.txt
@@ -8,7 +8,12 @@
bug: 5834665
},
{
- description: "libcore.java.net.URLConnectionTest#testServerShutdownInput fails on ICL27 mysid-userdebug",
+ description: "FIONREAD/SIOCINQ returns the wrong result on sockets (5731252 is the root cause of 5534202)",
+ name: "libcore.java.net.SocketTest#testAvailable",
+ bug: 5731252
+},
+{
+ description: "libcore.java.net.URLConnectionTest#testServerShutdownInput fails on ICL27 mysid-userdebug (5534202 is caused by 5731252)",
name: "libcore.java.net.URLConnectionTest#testServerShutdownInput",
bug: 5534202
},
diff --git a/luni/src/main/java/java/lang/Object.java b/luni/src/main/java/java/lang/Object.java
index 7f4b490..4bca034 100644
--- a/luni/src/main/java/java/lang/Object.java
+++ b/luni/src/main/java/java/lang/Object.java
@@ -361,7 +361,7 @@ public class Object {
* @see java.lang.Thread
*/
public final void wait() throws InterruptedException {
- wait(0 ,0);
+ wait(0, 0);
}
/**
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index 6b20a1c..0fbe2f5 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -396,6 +396,17 @@ public final class Locale implements Cloneable, Serializable {
if (languageCode.isEmpty()) {
return "";
}
+
+ // Last-minute workaround for http://b/7291355 in jb-mr1.
+ // This isn't right for all languages, but it's right for en and tl.
+ // We should have more CLDR data in a future release, but we'll still
+ // probably want to have frameworks/base translate the obsolete tl and
+ // tl-rPH locales to fil and fil-rPH at runtime, at which point
+ // libcore and icu4c will just do the right thing.
+ if (languageCode.equals("tl")) {
+ return "Filipino";
+ }
+
String result = ICU.getDisplayLanguageNative(toString(), locale.toString());
if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
result = ICU.getDisplayLanguageNative(toString(), Locale.getDefault().toString());
diff --git a/luni/src/main/java/libcore/io/DropBox.java b/luni/src/main/java/libcore/io/DropBox.java
new file mode 100644
index 0000000..cf88106
--- /dev/null
+++ b/luni/src/main/java/libcore/io/DropBox.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+public final class DropBox {
+
+ /**
+ * Hook for customizing how events are reported.
+ */
+ private static volatile Reporter REPORTER = new DefaultReporter();
+
+ /**
+ * Used to replace default Reporter for logging events. Must be non-null.
+ */
+ public static void setReporter(Reporter reporter) {
+ if (reporter == null) {
+ throw new NullPointerException("reporter == null");
+ }
+ REPORTER = reporter;
+ }
+
+ /**
+ * Returns non-null Reporter.
+ */
+ public static Reporter getReporter() {
+ return REPORTER;
+ }
+
+ /**
+ * Interface to allow customization of reporting behavior.
+ */
+ public static interface Reporter {
+ public void addData(String tag, byte[] data, int flags);
+ public void addText(String tag, String data);
+ }
+
+ /**
+ * Default Reporter which reports events to the log.
+ */
+ private static final class DefaultReporter implements Reporter {
+
+ public void addData(String tag, byte[] data, int flags) {
+ System.out.println(tag + ": " + Base64.encode(data));
+ }
+
+ public void addText(String tag, String data) {
+ System.out.println(tag + ": " + data);
+ }
+ }
+
+ public static void addData(String tag, byte[] data, int flags) {
+ getReporter().addData(tag, data, flags);
+ }
+
+ public static void addText(String tag, String data) {
+ getReporter().addText(tag, data);
+ }
+}
diff --git a/luni/src/main/java/libcore/io/EventLogger.java b/luni/src/main/java/libcore/io/EventLogger.java
new file mode 100644
index 0000000..9709cc9
--- /dev/null
+++ b/luni/src/main/java/libcore/io/EventLogger.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+public final class EventLogger {
+
+ /**
+ * Hook for customizing how events are reported.
+ */
+ private static volatile Reporter REPORTER = new DefaultReporter();
+
+ /**
+ * Used to replace default Reporter for logging events. Must be non-null.
+ */
+ public static void setReporter(Reporter reporter) {
+ if (reporter == null) {
+ throw new NullPointerException("reporter == null");
+ }
+ REPORTER = reporter;
+ }
+
+ /**
+ * Returns non-null Reporter.
+ */
+ public static Reporter getReporter() {
+ return REPORTER;
+ }
+
+ /**
+ * Interface to allow customization of reporting behavior.
+ */
+ public static interface Reporter {
+ public void report (int code, Object... list);
+ }
+
+ /**
+ * Default Reporter which reports events to the log.
+ */
+ private static final class DefaultReporter implements Reporter {
+ @Override
+ public void report (int code, Object... list) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(code);
+ for (Object o : list) {
+ sb.append(",");
+ sb.append(o.toString());
+ }
+ System.out.println(sb);
+ }
+ }
+
+ public static void writeEvent(int code, Object... list) {
+ getReporter().report(code, list);
+ }
+}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CertPinManager.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CertPinManager.java
new file mode 100644
index 0000000..4cdd8d2
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CertPinManager.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.DefaultHostnameVerifier;
+import libcore.io.IoUtils;
+import libcore.util.BasicLruCache;
+
+/**
+ * This class provides a simple interface for cert pinning.
+ */
+public class CertPinManager {
+
+ private long lastModified;
+
+ private final Map<String, PinListEntry> entries = new HashMap<String, PinListEntry>();
+ private final BasicLruCache<String, String> hostnameCache = new BasicLruCache<String, String>(10);
+ private final DefaultHostnameVerifier verifier = new DefaultHostnameVerifier();
+
+ private boolean initialized = false;
+ private static final boolean DEBUG = false;
+
+ private final File pinFile;
+ private final TrustedCertificateStore certStore;
+
+ public CertPinManager(TrustedCertificateStore store) throws PinManagerException {
+ pinFile = new File("/data/misc/keychain/pins");
+ certStore = store;
+ rebuild();
+ }
+
+ /** Test only */
+ public CertPinManager(String path, TrustedCertificateStore store) throws PinManagerException {
+ if (path == null) {
+ throw new NullPointerException("path == null");
+ }
+ pinFile = new File(path);
+ certStore = store;
+ rebuild();
+ }
+
+ /**
+ * This is the public interface for cert pinning.
+ *
+ * Given a hostname and a certificate chain this verifies that the chain includes
+ * certs from the pinned list provided.
+ *
+ * If the chain doesn't include those certs and is in enforcing mode, then this method
+ * returns true and the certificate check should fail.
+ */
+ public boolean chainIsNotPinned(String hostname, List<X509Certificate> chain)
+ throws PinManagerException {
+ // lookup the entry
+ PinListEntry entry = lookup(hostname);
+
+ // return its result or false if there's no pin
+ if (entry != null) {
+ return entry.chainIsNotPinned(chain);
+ }
+ return false;
+ }
+
+ private synchronized void rebuild() throws PinManagerException {
+ // reread the pin file
+ String pinFileContents = readPinFile();
+
+ if (pinFileContents != null) {
+ // rebuild the pinned certs
+ for (String entry : getPinFileEntries(pinFileContents)) {
+ try {
+ PinListEntry pin = new PinListEntry(entry, certStore);
+ entries.put(pin.getCommonName(), pin);
+ } catch (PinEntryException e) {
+ log("Pinlist contains a malformed pin: " + entry, e);
+ }
+ }
+
+ // clear the cache
+ hostnameCache.evictAll();
+
+ // set the last modified time
+ lastModified = pinFile.lastModified();
+
+ // we've been fully initialized and are ready to go
+ initialized = true;
+ }
+ }
+
+ private String readPinFile() throws PinManagerException {
+ try {
+ return IoUtils.readFileAsString(pinFile.getPath());
+ } catch (FileNotFoundException e) {
+ // there's no pin list, all certs are unpinned
+ return null;
+ } catch (IOException e) {
+ // this is unexpected, fail
+ throw new PinManagerException("Unexpected error reading pin list; failing.", e);
+ }
+ }
+
+ private static String[] getPinFileEntries(String pinFileContents) {
+ return pinFileContents.split("\n");
+ }
+
+ private synchronized PinListEntry lookup(String hostname) throws PinManagerException {
+
+ // if we don't have any data, don't bother
+ if (!initialized) {
+ return null;
+ }
+
+ // check to see if our cache is valid
+ if (cacheIsNotValid()) {
+ rebuild();
+ }
+
+ // if so, check the hostname cache
+ String cn = hostnameCache.get(hostname);
+ if (cn != null) {
+ // if we hit, return the corresponding entry
+ return entries.get(cn);
+ }
+
+ // otherwise, get the matching cn
+ cn = getMatchingCN(hostname);
+ if (cn != null) {
+ hostnameCache.put(hostname, cn);
+ // we have a matching CN, return that entry
+ return entries.get(cn);
+ }
+
+ // if we got here, we don't have a matching CN for this hostname
+ return null;
+ }
+
+ private boolean cacheIsNotValid() {
+ return pinFile.lastModified() != lastModified;
+ }
+
+ private String getMatchingCN(String hostname) {
+ String bestMatch = "";
+ for (String cn : entries.keySet()) {
+ // skip shorter CNs since they can't be better matches
+ if (cn.length() < bestMatch.length()) {
+ continue;
+ }
+ // now verify that the CN matches at all
+ if (verifier.verifyHostName(hostname, cn)) {
+ bestMatch = cn;
+ }
+ }
+ return bestMatch;
+ }
+
+ private static void log(String s, Exception e) {
+ if (DEBUG) {
+ System.out.println("PINFILE: " + s);
+ if (e != null) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
index 83f86ae..c855c0c 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
@@ -37,6 +37,7 @@ import javax.crypto.spec.DHPublicKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
import javax.security.auth.x500.X500Principal;
/**
@@ -88,7 +89,7 @@ public class ClientHandshakeImpl extends HandshakeProtocol {
if (engineOwner != null) {
session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
} else {
- session.setPeer(socketOwner.getInetAddress().getHostName(), socketOwner.getPort());
+ session.setPeer(socketOwner.getPeerHostName(), socketOwner.getPeerPort());
}
session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
recordProtocol.setVersion(session.protocol.version);
@@ -109,7 +110,7 @@ public class ClientHandshakeImpl extends HandshakeProtocol {
if (engineOwner != null) {
session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
} else {
- session.setPeer(socketOwner.getInetAddress().getHostName(), socketOwner.getPort());
+ session.setPeer(socketOwner.getPeerHostName(), socketOwner.getPeerPort());
}
session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
recordProtocol.setVersion(session.protocol.version);
@@ -527,8 +528,21 @@ public class ClientHandshakeImpl extends HandshakeProtocol {
if (authType == null) {
return;
}
+ String hostname = null;
+ if (engineOwner != null) {
+ hostname = engineOwner.getPeerHost();
+ } else {
+ // we don't want to do an inet address lookup here in case we're talking to a proxy
+ hostname = socketOwner.getWrappedHostName();
+ }
try {
- parameters.getTrustManager().checkServerTrusted(serverCert.certs, authType);
+ X509TrustManager x509tm = parameters.getTrustManager();
+ if (x509tm instanceof TrustManagerImpl) {
+ TrustManagerImpl tm = (TrustManagerImpl) x509tm;
+ tm.checkServerTrusted(serverCert.certs, authType, hostname);
+ } else {
+ x509tm.checkServerTrusted(serverCert.certs, authType);
+ }
} catch (CertificateException e) {
fatalAlert(AlertProtocol.BAD_CERTIFICATE, "Not trusted server certificate", e);
return;
@@ -559,8 +573,8 @@ public class ClientHandshakeImpl extends HandshakeProtocol {
host = engineOwner.getPeerHost();
port = engineOwner.getPeerPort();
} else {
- host = socketOwner.getInetAddress().getHostName();
- port = socketOwner.getPort();
+ host = socketOwner.getPeerHostName();
+ port = socketOwner.getPeerPort();
}
if (host == null || port == -1) {
return null; // starts new session
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
index c78e534..b46432d 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
@@ -85,6 +85,8 @@ public final class NativeCrypto {
public static native void EVP_PKEY_free(int pkey);
+ public static native int EVP_PKEY_cmp(int pkey1, int pkey2);
+
public static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int pkey);
public static native int d2i_PKCS8_PRIV_KEY_INFO(byte[] data);
@@ -732,7 +734,7 @@ public final class NativeCrypto {
public static native int SSL_read(int sslNativePointer,
FileDescriptor fd,
SSLHandshakeCallbacks shc,
- byte[] b, int off, int len, int timeoutMillis)
+ byte[] b, int off, int len, int readTimeoutMillis)
throws IOException;
/**
@@ -741,7 +743,7 @@ public final class NativeCrypto {
public static native void SSL_write(int sslNativePointer,
FileDescriptor fd,
SSLHandshakeCallbacks shc,
- byte[] b, int off, int len)
+ byte[] b, int off, int len, int writeTimeoutMillis)
throws IOException;
public static native void SSL_interrupt(int sslNativePointer);
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherRSA.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherRSA.java
index a11ffa9..ddf2e0d 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherRSA.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherRSA.java
@@ -110,16 +110,34 @@ public abstract class OpenSSLCipherRSA extends CipherSpi {
@Override
protected int engineGetBlockSize() {
- return 0;
+ if (encrypting) {
+ return paddedBlockSizeBytes();
+ }
+ return keySizeBytes();
}
@Override
protected int engineGetOutputSize(int inputLen) {
+ if (encrypting) {
+ return keySizeBytes();
+ }
+ return paddedBlockSizeBytes();
+ }
+
+ private int paddedBlockSizeBytes() {
+ int paddedBlockSizeBytes = keySizeBytes();
+ if (padding == NativeCrypto.RSA_PKCS1_PADDING) {
+ paddedBlockSizeBytes--; // for 0 prefix
+ paddedBlockSizeBytes -= 10; // PKCS1 padding header length
+ }
+ return paddedBlockSizeBytes;
+ }
+
+ private int keySizeBytes() {
if (key == null) {
throw new IllegalStateException("cipher is not initialized");
}
-
- return buffer.length;
+ return NativeCrypto.RSA_size(this.key.getPkeyContext());
}
@Override
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java
index 54253da..09b086c 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java
@@ -93,34 +93,34 @@ public final class OpenSSLProvider extends Provider {
put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1",
"MD5WithRSAEncryption");
- put("Signature.SHA1WithRSAEncryption", OpenSSLSignature.SHA1RSA.class.getName());
- put("Alg.Alias.Signature.SHA1WithRSA", "SHA1WithRSAEncryption");
- put("Alg.Alias.Signature.SHA1/RSA", "SHA1WithRSAEncryption");
- put("Alg.Alias.Signature.SHA-1/RSA", "SHA1WithRSAEncryption");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1WithRSAEncryption");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1WithRSAEncryption");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1WithRSAEncryption");
- put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1WithRSAEncryption");
-
- put("Signature.SHA256WithRSAEncryption", OpenSSLSignature.SHA256RSA.class.getName());
- put("Alg.Alias.Signature.SHA256WithRSA", "SHA256WithRSAEncryption");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256WithRSAEncryption");
+ put("Signature.SHA1WithRSA", OpenSSLSignature.SHA1RSA.class.getName());
+ put("Alg.Alias.Signature.SHA1WithRSAEncryption", "SHA1WithRSA");
+ put("Alg.Alias.Signature.SHA1/RSA", "SHA1WithRSA");
+ put("Alg.Alias.Signature.SHA-1/RSA", "SHA1WithRSA");
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1WithRSA");
+ put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1WithRSA");
+ put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1WithRSA");
+ put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1WithRSA");
+
+ put("Signature.SHA256WithRSA", OpenSSLSignature.SHA256RSA.class.getName());
+ put("Alg.Alias.Signature.SHA256WithRSAEncryption", "SHA256WithRSA");
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256WithRSA");
put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.1",
- "SHA256WithRSAEncryption");
+ "SHA256WithRSA");
put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11",
- "SHA256WithRSAEncryption");
+ "SHA256WithRSA");
- put("Signature.SHA384WithRSAEncryption", OpenSSLSignature.SHA384RSA.class.getName());
- put("Alg.Alias.Signature.SHA384WithRSA", "SHA384WithRSAEncryption");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384WithRSAEncryption");
+ put("Signature.SHA384WithRSA", OpenSSLSignature.SHA384RSA.class.getName());
+ put("Alg.Alias.Signature.SHA384WithRSAEncryption", "SHA384WithRSA");
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384WithRSA");
put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.113549.1.1.1",
- "SHA384WithRSAEncryption");
+ "SHA384WithRSA");
- put("Signature.SHA512WithRSAEncryption", OpenSSLSignature.SHA512RSA.class.getName());
- put("Alg.Alias.Signature.SHA512WithRSA", "SHA512WithRSAEncryption");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512WithRSAEncryption");
+ put("Signature.SHA512WithRSA", OpenSSLSignature.SHA512RSA.class.getName());
+ put("Alg.Alias.Signature.SHA512WithRSAEncryption", "SHA512WithRSA");
+ put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512WithRSA");
put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.113549.1.1.1",
- "SHA512WithRSAEncryption");
+ "SHA512WithRSA");
put("Signature.SHA1withDSA", OpenSSLSignature.SHA1DSA.class.getName());
put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateCrtKey.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateCrtKey.java
index f1e12c2..0f43bf9 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateCrtKey.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateCrtKey.java
@@ -197,8 +197,8 @@ public class OpenSSLRSAPrivateCrtKey extends OpenSSLRSAPrivateKey implements RSA
return true;
}
- if (o instanceof OpenSSLRSAPrivateCrtKey) {
- OpenSSLRSAPrivateCrtKey other = (OpenSSLRSAPrivateCrtKey) o;
+ if (o instanceof OpenSSLRSAPrivateKey) {
+ OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
/*
* We can shortcut the true case, but it still may be equivalent but
@@ -208,28 +208,35 @@ public class OpenSSLRSAPrivateCrtKey extends OpenSSLRSAPrivateKey implements RSA
return true;
}
- /*
- * If this key is ENGINE-based, it could be equivalent to another
- * ENGINE-based key. The modulus may be equal, but that occurrence
- * should be so improbably low as to never happen.
- */
- if (getOpenSSLKey().isEngineBased() || other.getOpenSSLKey().isEngineBased()) {
- return publicExponent.equals(other.getPublicExponent())
- && getModulus().equals(other.getModulus());
- }
+ return NativeCrypto.EVP_PKEY_cmp(getPkeyContext(), other.getPkeyContext()) == 1;
}
if (o instanceof RSAPrivateCrtKey) {
ensureReadParams();
RSAPrivateCrtKey other = (RSAPrivateCrtKey) o;
- return getModulus().equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent())
- && getPrivateExponent().equals(other.getPrivateExponent())
- && primeP.equals(other.getPrimeP()) && primeQ.equals(other.getPrimeQ())
- && primeExponentP.equals(other.getPrimeExponentP())
- && primeExponentQ.equals(other.getPrimeExponentQ())
- && crtCoefficient.equals(other.getCrtCoefficient());
+ if (getOpenSSLKey().isEngineBased()) {
+ return getModulus().equals(other.getModulus())
+ && publicExponent.equals(other.getPublicExponent());
+ } else {
+ return getModulus().equals(other.getModulus())
+ && publicExponent.equals(other.getPublicExponent())
+ && getPrivateExponent().equals(other.getPrivateExponent())
+ && primeP.equals(other.getPrimeP()) && primeQ.equals(other.getPrimeQ())
+ && primeExponentP.equals(other.getPrimeExponentP())
+ && primeExponentQ.equals(other.getPrimeExponentQ())
+ && crtCoefficient.equals(other.getCrtCoefficient());
+ }
+ } else if (o instanceof RSAPrivateKey) {
+ ensureReadParams();
+ RSAPrivateKey other = (RSAPrivateKey) o;
+
+ if (getOpenSSLKey().isEngineBased()) {
+ return getModulus().equals(other.getModulus());
+ } else {
+ return getModulus().equals(other.getModulus())
+ && getPrivateExponent().equals(other.getPrivateExponent());
+ }
}
return false;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateKey.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateKey.java
index fa455c7..6ad89b2 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateKey.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateKey.java
@@ -205,14 +205,7 @@ public class OpenSSLRSAPrivateKey implements RSAPrivateKey {
return true;
}
- /*
- * If this key is ENGINE-based, it could be equivalent to another
- * ENGINE-based key. The modulus may be equal, but that occurrence
- * should be so improbably low as to never happen.
- */
- if (key.isEngineBased() || other.getOpenSSLKey().isEngineBased()) {
- return modulus.equals(other.getModulus());
- }
+ return NativeCrypto.EVP_PKEY_cmp(getPkeyContext(), other.getPkeyContext()) == 1;
}
if (o instanceof RSAPrivateKey) {
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index 3720ba2..4cc16e6 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -42,7 +42,11 @@ import javax.net.ssl.SSLProtocolException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import javax.security.auth.x500.X500Principal;
+import static libcore.io.OsConstants.*;
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
import libcore.io.Streams;
+import libcore.io.StructTimeval;
import org.apache.harmony.security.provider.cert.X509CertImpl;
/**
@@ -93,7 +97,8 @@ public class OpenSSLSocketImpl
* OpenSSLSocketImplWrapper overrides setSoTimeout and
* getSoTimeout to delegate to the wrapped socket.
*/
- private int timeoutMilliseconds = 0;
+ private int readTimeoutMilliseconds = 0;
+ private int writeTimeoutMilliseconds = 0;
private int handshakeTimeoutMilliseconds = -1; // -1 = same as timeout; 0 = infinite
private String wrappedHost;
@@ -361,9 +366,11 @@ public class OpenSSLSocketImpl
}
// Temporarily use a different timeout for the handshake process
- int savedTimeoutMilliseconds = getSoTimeout();
+ int savedReadTimeoutMilliseconds = getSoTimeout();
+ int savedWriteTimeoutMilliseconds = getSoWriteTimeout();
if (handshakeTimeoutMilliseconds >= 0) {
setSoTimeout(handshakeTimeoutMilliseconds);
+ setSoWriteTimeout(handshakeTimeoutMilliseconds);
}
int sslSessionNativePointer;
@@ -399,7 +406,8 @@ public class OpenSSLSocketImpl
// Restore the original timeout now that the handshake is complete
if (handshakeTimeoutMilliseconds >= 0) {
- setSoTimeout(savedTimeoutMilliseconds);
+ setSoTimeout(savedReadTimeoutMilliseconds);
+ setSoWriteTimeout(savedWriteTimeoutMilliseconds);
}
// if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
@@ -418,7 +426,7 @@ public class OpenSSLSocketImpl
}
}
- private String getPeerHostName() {
+ String getPeerHostName() {
if (wrappedHost != null) {
return wrappedHost;
}
@@ -429,7 +437,7 @@ public class OpenSSLSocketImpl
return null;
}
- private int getPeerPort() {
+ int getPeerPort() {
return wrappedHost == null ? super.getPort() : wrappedPort;
}
@@ -570,8 +578,13 @@ public class OpenSSLSocketImpl
}
boolean client = sslParameters.getUseClientMode();
if (client) {
- sslParameters.getTrustManager().checkServerTrusted(peerCertificateChain,
- authMethod);
+ X509TrustManager x509tm = sslParameters.getTrustManager();
+ if (x509tm instanceof TrustManagerImpl) {
+ TrustManagerImpl tm = (TrustManagerImpl) x509tm;
+ tm.checkServerTrusted(peerCertificateChain, authMethod, wrappedHost);
+ } else {
+ x509tm.checkServerTrusted(peerCertificateChain, authMethod);
+ }
} else {
String authType = peerCertificateChain[0].getPublicKey().getAlgorithm();
sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain,
@@ -691,7 +704,7 @@ public class OpenSSLSocketImpl
return;
}
NativeCrypto.SSL_write(sslNativePointer, socket.getFileDescriptor$(),
- OpenSSLSocketImpl.this, buf, offset, byteCount);
+ OpenSSLSocketImpl.this, buf, offset, byteCount, writeTimeoutMilliseconds);
}
}
}
@@ -822,21 +835,42 @@ public class OpenSSLSocketImpl
throw new SocketException("Methods sendUrgentData, setOOBInline are not supported.");
}
- @Override public void setSoTimeout(int timeoutMilliseconds) throws SocketException {
- super.setSoTimeout(timeoutMilliseconds);
- this.timeoutMilliseconds = timeoutMilliseconds;
+ @Override public void setSoTimeout(int readTimeoutMilliseconds) throws SocketException {
+ super.setSoTimeout(readTimeoutMilliseconds);
+ this.readTimeoutMilliseconds = readTimeoutMilliseconds;
}
@Override public int getSoTimeout() throws SocketException {
- return timeoutMilliseconds;
+ return readTimeoutMilliseconds;
+ }
+
+ /**
+ * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+ */
+ public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+ this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
+
+ StructTimeval tv = StructTimeval.fromMillis(writeTimeoutMilliseconds);
+ try {
+ Libcore.os.setsockoptTimeval(getFileDescriptor$(), SOL_SOCKET, SO_SNDTIMEO, tv);
+ } catch (ErrnoException errnoException) {
+ throw errnoException.rethrowAsSocketException();
+ }
+ }
+
+ /**
+ * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+ */
+ public int getSoWriteTimeout() throws SocketException {
+ return writeTimeoutMilliseconds;
}
/**
* Set the handshake timeout on this socket. This timeout is specified in
* milliseconds and will be used only during the handshake process.
*/
- public void setHandshakeTimeout(int timeoutMilliseconds) throws SocketException {
- this.handshakeTimeoutMilliseconds = timeoutMilliseconds;
+ public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+ this.handshakeTimeoutMilliseconds = handshakeTimeoutMilliseconds;
}
@Override public void close() throws IOException {
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinEntryException.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinEntryException.java
new file mode 100644
index 0000000..8b74514
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinEntryException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+// public for testing by CertPinManagerTest
+public class PinEntryException extends Exception {
+
+ PinEntryException() {
+ }
+
+ PinEntryException(String msg) {
+ super(msg);
+ }
+}
+
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinFailureLogger.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinFailureLogger.java
new file mode 100644
index 0000000..40b1838
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinFailureLogger.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import libcore.io.Base64;
+import libcore.io.DropBox;
+
+public class PinFailureLogger {
+
+ private static final long LOG_INTERVAL_NANOS = 1000 * 1000 * 1000 * 60 * 60;
+
+ private static long lastLoggedNanos = 0;
+
+ public static synchronized void log(String cn, boolean chainContainsUserCert,
+ boolean pinIsEnforcing,
+ List<X509Certificate> chain) {
+ // if we've logged recently, don't do it again
+ if (!timeToLog()) {
+ return;
+ }
+ // otherwise, log the event
+ writeToLog(cn, chainContainsUserCert, pinIsEnforcing, chain);
+ // update the last logged time
+ lastLoggedNanos = System.nanoTime();
+ }
+
+ protected static synchronized void writeToLog(String cn, boolean chainContainsUserCert,
+ boolean pinIsEnforcing,
+ List<X509Certificate> chain) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(cn);
+ sb.append("|");
+ sb.append(chainContainsUserCert);
+ sb.append("|");
+ sb.append(pinIsEnforcing);
+ sb.append("|");
+ for (X509Certificate cert : chain) {
+ try {
+ sb.append(Base64.encode(cert.getEncoded()));
+ } catch (CertificateEncodingException e) {
+ sb.append("Error: could not encode certificate");
+ }
+ sb.append("|");
+ }
+ DropBox.addText("cert_pin_failure", sb.toString());
+ }
+
+ protected static boolean timeToLog() {
+ long currentTimeNanos = System.nanoTime();
+ return ((currentTimeNanos - lastLoggedNanos) > LOG_INTERVAL_NANOS);
+ }
+}
+
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinListEntry.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinListEntry.java
new file mode 100644
index 0000000..c05a391
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinListEntry.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import libcore.io.EventLogger;
+
+/**
+ * This class represents a single entry in the pin file.
+ */
+// public for testing by CertPinManagerTest
+public class PinListEntry {
+
+ /** The Common Name (CN) as used on the SSL certificate */
+ private final String cn;
+
+ /**
+ * Determines whether a failed match here will prevent the chain from being accepted. If true,
+ * an unpinned chain will log and cause a match failure. If false, it will merely log.
+ */
+ private final boolean enforcing;
+
+ private final Set<String> pinnedFingerprints = new HashSet<String>();
+
+ private static final boolean DEBUG = false;
+
+ private final TrustedCertificateStore certStore;
+
+ public String getCommonName() {
+ return cn;
+ }
+
+ public boolean getEnforcing() {
+ return enforcing;
+ }
+
+ public PinListEntry(String entry, TrustedCertificateStore store) throws PinEntryException {
+ if (entry == null) {
+ throw new NullPointerException("entry == null");
+ }
+ certStore = store;
+ // Examples:
+ // *.google.com=true|34c8a0d...9e04ca05f,9e04ca05f...34c8a0d
+ // *.android.com=true|ca05f...8a0d34c
+ // clients.google.com=false|9e04ca05f...34c8a0d,34c8a0d...9e04ca05f
+ String[] values = entry.split("[=,|]");
+ // entry must have a CN, an enforcement value, and at least one pin
+ if (values.length < 3) {
+ throw new PinEntryException("Received malformed pin entry");
+ }
+ // get the cn
+ cn = values[0]; // is there more validation we can do here?
+ enforcing = enforcementValueFromString(values[1]);
+ // the remainder should be pins
+ addPins(Arrays.copyOfRange(values, 2, values.length));
+ }
+
+ private static boolean enforcementValueFromString(String val) throws PinEntryException {
+ if (val.equals("true")) {
+ return true;
+ } else if (val.equals("false")) {
+ return false;
+ } else {
+ throw new PinEntryException("Enforcement status is not a valid value");
+ }
+ }
+
+ /**
+ * Checks the given chain against the pin list corresponding to this entry.
+ *
+ * If the pin list does not contain the required certs and the enforcing field is true then
+ * this returns true, indicating a verification error. Otherwise, it returns false and
+ * verification should proceed.
+ */
+ public boolean chainIsNotPinned(List<X509Certificate> chain) {
+ for (X509Certificate cert : chain) {
+ String fingerprint = getFingerprint(cert);
+ if (pinnedFingerprints.contains(fingerprint)) {
+ return false;
+ }
+ }
+ logPinFailure(chain);
+ return enforcing;
+ }
+
+ private static String getFingerprint(X509Certificate cert) {
+ try {
+ MessageDigest dgst = MessageDigest.getInstance("SHA512");
+ byte[] encoded = cert.getPublicKey().getEncoded();
+ byte[] fingerprint = dgst.digest(encoded);
+ return IntegralToString.bytesToHexString(fingerprint, false);
+ } catch (NoSuchAlgorithmException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private void addPins(String[] pins) {
+ for (String pin : pins) {
+ validatePin(pin);
+ }
+ Collections.addAll(pinnedFingerprints, pins);
+ }
+
+ private static void validatePin(String pin) {
+ // check to make sure the length is correct
+ if (pin.length() != 128) {
+ throw new IllegalArgumentException("Pin is not a valid length");
+ }
+ // check to make sure that it's a valid hex string
+ try {
+ new BigInteger(pin, 16);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Pin is not a valid hex string", e);
+ }
+ }
+
+ private boolean chainContainsUserCert(List<X509Certificate> chain) {
+ if (certStore == null) {
+ return false;
+ }
+ for (X509Certificate cert : chain) {
+ if (certStore.isUserAddedCertificate(cert)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void logPinFailure(List<X509Certificate> chain) {
+ PinFailureLogger.log(cn, chainContainsUserCert(chain), enforcing, chain);
+ }
+}
+
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinManagerException.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinManagerException.java
new file mode 100644
index 0000000..74b3c65
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/PinManagerException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+class PinManagerException extends Exception {
+
+ PinManagerException() {
+ }
+
+ PinManagerException(String msg) {
+ super(msg);
+ }
+
+ PinManagerException(String msg, Exception e) {
+ super(msg, e);
+ }
+}
+
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketFactoryImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketFactoryImpl.java
index be9a7fc..93496cf 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketFactoryImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketFactoryImpl.java
@@ -88,7 +88,7 @@ public class SSLSocketFactoryImpl extends SSLSocketFactory {
if (instantiationException != null) {
throw instantiationException;
}
- return new SSLSocketWrapper(s, autoClose, (SSLParametersImpl) sslParameters
+ return new SSLSocketWrapper(s, host, port, autoClose, (SSLParametersImpl) sslParameters
.clone());
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketImpl.java
index 6e5fddd..2cd2cf5 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketImpl.java
@@ -41,6 +41,10 @@ public class SSLSocketImpl extends SSLSocket {
// indicates if handshake has been started
private boolean handshake_started = false;
+ // used when we're wrapping a socket
+ private final String wrappedHost;
+ private final int wrappedPort;
+
// record protocol to be used
protected SSLRecordProtocol recordProtocol;
// handshake protocol to be used
@@ -83,6 +87,8 @@ public class SSLSocketImpl extends SSLSocket {
*/
protected SSLSocketImpl(SSLParametersImpl sslParameters) {
this.sslParameters = sslParameters;
+ this.wrappedHost = null;
+ this.wrappedPort = -1;
// init should be called after creation!
}
@@ -99,6 +105,8 @@ public class SSLSocketImpl extends SSLSocket {
protected SSLSocketImpl(String host, int port, SSLParametersImpl sslParameters)
throws IOException, UnknownHostException {
super(host, port);
+ this.wrappedHost = host;
+ this.wrappedPort = port;
this.sslParameters = sslParameters;
init();
}
@@ -120,6 +128,8 @@ public class SSLSocketImpl extends SSLSocket {
SSLParametersImpl sslParameters) throws IOException,
UnknownHostException {
super(host, port, localHost, localPort);
+ this.wrappedHost = host;
+ this.wrappedPort = port;
this.sslParameters = sslParameters;
init();
}
@@ -138,6 +148,8 @@ public class SSLSocketImpl extends SSLSocket {
SSLParametersImpl sslParameters) throws IOException {
super(host, port);
this.sslParameters = sslParameters;
+ this.wrappedHost = null;
+ this.wrappedPort = -1;
init();
}
@@ -158,6 +170,8 @@ public class SSLSocketImpl extends SSLSocket {
SSLParametersImpl sslParameters) throws IOException {
super(address, port, localAddress, localPort);
this.sslParameters = sslParameters;
+ this.wrappedHost = null;
+ this.wrappedPort = -1;
init();
}
@@ -193,6 +207,29 @@ public class SSLSocketImpl extends SSLSocket {
}
}
+ String getWrappedHostName() {
+ return wrappedHost;
+ }
+
+ int getWrappedPort() {
+ return wrappedPort;
+ }
+
+ String getPeerHostName() {
+ if (wrappedHost != null) {
+ return wrappedHost;
+ }
+ InetAddress inetAddress = super.getInetAddress();
+ if (inetAddress != null) {
+ return inetAddress.getHostName();
+ }
+ return null;
+ }
+
+ int getPeerPort() {
+ return (wrappedPort == -1) ? super.getPort() : wrappedPort;
+ }
+
// --------------- SSLParameters based methods ---------------------
/**
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketWrapper.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketWrapper.java
index 27bbead..a393e24 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketWrapper.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSocketWrapper.java
@@ -32,8 +32,9 @@ public class SSLSocketWrapper extends SSLSocketImpl {
private final Socket socket;
private final boolean autoClose;
- protected SSLSocketWrapper(Socket socket, boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
- super(sslParameters);
+ protected SSLSocketWrapper(Socket socket, String host, int port, boolean autoClose,
+ SSLParametersImpl sslParameters) throws IOException {
+ super(host, port, sslParameters);
if (!socket.isConnected()) {
throw new SocketException("Socket is not connected.");
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
index 8217fb5..1682df7 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java
@@ -35,6 +35,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.net.ssl.X509TrustManager;
+import libcore.io.EventLogger;
/**
*
@@ -52,6 +53,11 @@ public final class TrustManagerImpl implements X509TrustManager {
private final KeyStore rootKeyStore;
/**
+ * The CertPinManager, which validates the chain against a host-to-pin mapping
+ */
+ private CertPinManager pinManager;
+
+ /**
* The backing store for the AndroidCAStore if non-null. This will
* be null when the rootKeyStore is null, implying we are not
* using the AndroidCAStore.
@@ -83,6 +89,13 @@ public final class TrustManagerImpl implements X509TrustManager {
* @param ks
*/
public TrustManagerImpl(KeyStore keyStore) {
+ this(keyStore, null);
+ }
+
+ /**
+ * For testing only
+ */
+ public TrustManagerImpl(KeyStore keyStore, CertPinManager manager) {
CertPathValidator validatorLocal = null;
CertificateFactory factoryLocal = null;
KeyStore rootKeyStoreLocal = null;
@@ -111,6 +124,17 @@ public final class TrustManagerImpl implements X509TrustManager {
} catch (Exception e) {
errLocal = e;
}
+
+ if (manager != null) {
+ this.pinManager = manager;
+ } else {
+ try {
+ pinManager = new CertPinManager(trustedCertificateStoreLocal);
+ } catch (PinManagerException e) {
+ throw new SecurityException("Could not initialize CertPinManager", e);
+ }
+ }
+
this.rootKeyStore = rootKeyStoreLocal;
this.trustedCertificateStore = trustedCertificateStoreLocal;
this.validator = validatorLocal;
@@ -155,12 +179,22 @@ public final class TrustManagerImpl implements X509TrustManager {
@Override public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
- checkTrusted(chain, authType);
+ checkTrusted(chain, authType, null);
}
@Override public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
- checkTrusted(chain, authType);
+ checkTrusted(chain, authType, null);
+ }
+
+ /**
+ * Validates whether a server is trusted. If hostname is given and non-null it also checks if
+ * chain is pinned appropriately for that host. If null, it does not check for pinned certs.
+ * The return value is a list of the certificates used for making the trust decision.
+ */
+ public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
+ String host) throws CertificateException {
+ return checkTrusted(chain, authType, host);
}
public void handleTrustStorageUpdate() {
@@ -168,10 +202,10 @@ public final class TrustManagerImpl implements X509TrustManager {
trustedCertificateIndex.reset();
} else {
trustedCertificateIndex.reset(trustAnchors(acceptedIssuers));
- }
+ }
}
- private void checkTrusted(X509Certificate[] chain, String authType)
+ private List<X509Certificate> checkTrusted(X509Certificate[] chain, String authType, String host)
throws CertificateException {
if (chain == null || chain.length == 0 || authType == null || authType.length() == 0) {
throw new IllegalArgumentException("null or zero-length parameter");
@@ -180,15 +214,65 @@ public final class TrustManagerImpl implements X509TrustManager {
throw new CertificateException(err);
}
- Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>();
- X509Certificate[] newChain = cleanupCertChainAndFindTrustAnchors(chain, trustAnchors);
+ // get the cleaned up chain and trust anchor
+ Set<TrustAnchor> trustAnchor = new HashSet<TrustAnchor>(); // there can only be one!
+ X509Certificate[] newChain = cleanupCertChainAndFindTrustAnchors(chain, trustAnchor);
+
+ // add the first trust anchor to the chain, which may be an intermediate
+ List<X509Certificate> wholeChain = new ArrayList<X509Certificate>();
+ wholeChain.addAll(Arrays.asList(newChain));
+ // trustAnchor is actually just a single element
+ for (TrustAnchor trust : trustAnchor) {
+ wholeChain.add(trust.getTrustedCert());
+ }
+
+ // add all the cached certificates from the cert index, avoiding loops
+ // this gives us a full chain from leaf to root, which we use for cert pinning and pass
+ // back out to callers when we return.
+ X509Certificate last = wholeChain.get(wholeChain.size() - 1);
+ while (true) {
+ TrustAnchor cachedTrust = trustedCertificateIndex.findByIssuerAndSignature(last);
+ // the cachedTrust can be null if there isn't anything in the index or if a user has
+ // trusted a non-self-signed cert.
+ if (cachedTrust == null) {
+ break;
+ }
+
+ // at this point we have a cached trust anchor, but don't know if its one we got from
+ // the server. Extract the cert, compare it to the last element in the chain, and add it
+ // if we haven't seen it before.
+ X509Certificate next = cachedTrust.getTrustedCert();
+ if (next != last) {
+ wholeChain.add(next);
+ last = next;
+ } else {
+ // if next == last then we found a self-signed cert and the chain is done
+ break;
+ }
+ }
+
+ // build the cert path from the array of certs sans trust anchors
+ CertPath certPath = factory.generateCertPath(Arrays.asList(newChain));
+
+ if (host != null) {
+ boolean chainIsNotPinned = true;
+ try {
+ chainIsNotPinned = pinManager.chainIsNotPinned(host, wholeChain);
+ } catch (PinManagerException e) {
+ throw new CertificateException(e);
+ }
+ if (chainIsNotPinned) {
+ throw new CertificateException(new CertPathValidatorException(
+ "Certificate path is not properly pinned.", null, certPath, -1));
+ }
+ }
+
if (newChain.length == 0) {
// chain was entirely trusted, skip the validator
- return;
+ return wholeChain;
}
- CertPath certPath = factory.generateCertPath(Arrays.asList(newChain));
- if (trustAnchors.isEmpty()) {
+ if (trustAnchor.isEmpty()) {
throw new CertificateException(new CertPathValidatorException(
"Trust anchor for certification path not found.", null, certPath, -1));
}
@@ -198,7 +282,7 @@ public final class TrustManagerImpl implements X509TrustManager {
ChainStrengthAnalyzer.check(newChain);
try {
- PKIXParameters params = new PKIXParameters(trustAnchors);
+ PKIXParameters params = new PKIXParameters(trustAnchor);
params.setRevocationEnabled(false);
validator.validate(certPath, params);
// Add intermediate CAs to the index to tolerate sites
@@ -215,6 +299,8 @@ public final class TrustManagerImpl implements X509TrustManager {
} catch (CertPathValidatorException e) {
throw new CertificateException(e);
}
+
+ return wholeChain;
}
/**
@@ -236,17 +322,9 @@ public final class TrustManagerImpl implements X509TrustManager {
// Start with the first certificate in the chain, assuming it
// is the leaf certificate (server or client cert).
for (currIndex = 0; currIndex < chain.length; currIndex++) {
- // If the current cert is a TrustAnchor, we can ignore the rest of the chain.
- // This avoids including "bridge" CA certs that added for legacy compatability.
- TrustAnchor trustAnchor = findTrustAnchorBySubjectAndPublicKey(chain[currIndex]);
- if (trustAnchor != null) {
- trustAnchors.add(trustAnchor);
- currIndex--;
- break;
- }
- // Walk the rest of the chain to find a "subject" matching
+ // Walk the chain to find a "subject" matching
// the "issuer" of the current certificate. In a properly
- // order chain this should be the next cert and be fast.
+ // ordered chain this should be the next cert and be fast.
// If not, we reorder things to be as the validator will
// expect.
boolean foundNext = false;
@@ -275,15 +353,27 @@ public final class TrustManagerImpl implements X509TrustManager {
}
}
- // 2. If the chain is now shorter, copy to an appropriately sized array.
- int chainLength = currIndex + 1;
+ // 2. Find the trust anchor in the chain, if any
+ int anchorIndex;
+ for (anchorIndex = 0; anchorIndex < chain.length; anchorIndex++) {
+ // If the current cert is a TrustAnchor, we can ignore the rest of the chain.
+ // This avoids including "bridge" CA certs that added for legacy compatibility.
+ TrustAnchor trustAnchor = findTrustAnchorBySubjectAndPublicKey(chain[anchorIndex]);
+ if (trustAnchor != null) {
+ trustAnchors.add(trustAnchor);
+ break;
+ }
+ }
+
+ // 3. If the chain is now shorter, copy to an appropriately sized array.
+ int chainLength = anchorIndex;
X509Certificate[] newChain = ((chainLength == chain.length)
? chain
: Arrays.copyOf(chain, chainLength));
- // 3. If no TrustAnchor was found in cleanup, look for one now
+ // 4. If we didn't find a trust anchor earlier, look for one now
if (trustAnchors.isEmpty()) {
- TrustAnchor trustAnchor = findTrustAnchorByIssuerAndSignature(newChain[chainLength-1]);
+ TrustAnchor trustAnchor = findTrustAnchorByIssuerAndSignature(newChain[anchorIndex-1]);
if (trustAnchor != null) {
trustAnchors.add(trustAnchor);
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStore.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStore.java
index abb6e55..e7b1a7c 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStore.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStore.java
@@ -298,6 +298,14 @@ public final class TrustedCertificateStore {
}
/**
+ * Returns true to indicate that the certificate was added by the
+ * user, false otherwise.
+ */
+ public boolean isUserAddedCertificate(X509Certificate cert) {
+ return getCertificateFile(addedDir, cert).exists();
+ }
+
+ /**
* Returns a File for where the certificate is found if it exists
* or where it should be installed if it does not exist. The
* caller can disambiguate these cases by calling {@code
diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
index 12739a5..d7d8b22 100644
--- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
@@ -538,11 +538,11 @@ static bool arrayToBignum(JNIEnv* env, jbyteArray source, BIGNUM** dest) {
/**
* Converts an OpenSSL BIGNUM to a Java byte[] array.
*/
-static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source) {
- JNI_TRACE("bignumToArray(%p)", source);
+static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source, const char* sourceName) {
+ JNI_TRACE("bignumToArray(%p, %s)", source, sourceName);
if (source == NULL) {
- jniThrowNullPointerException(env, NULL);
+ jniThrowNullPointerException(env, sourceName);
return NULL;
}
@@ -550,7 +550,7 @@ static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source) {
jbyteArray javaBytes = env->NewByteArray(len);
ScopedByteArrayRW bytes(env, javaBytes);
if (bytes.get() == NULL) {
- JNI_TRACE("bignumToArray(%p) => NULL", source);
+ JNI_TRACE("bignumToArray(%p, %s) => NULL", source, sourceName);
return NULL;
}
@@ -568,7 +568,7 @@ static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source) {
return NULL;
}
- JNI_TRACE("bignumToArray(%p) => %p", source, javaBytes);
+ JNI_TRACE("bignumToArray(%p, %s) => %p", source, sourceName, javaBytes);
return javaBytes;
}
@@ -1111,6 +1111,26 @@ static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, jint pkeyRef) {
}
}
+static jint NativeCrypto_EVP_PKEY_cmp(JNIEnv* env, jclass, jint pkey1Ref, jint pkey2Ref) {
+ EVP_PKEY* pkey1 = reinterpret_cast<EVP_PKEY*>(pkey1Ref);
+ EVP_PKEY* pkey2 = reinterpret_cast<EVP_PKEY*>(pkey2Ref);
+ JNI_TRACE("EVP_PKEY_cmp(%p, %p)", pkey1, pkey2);
+
+ if (pkey1 == NULL) {
+ JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey1 == NULL", pkey1, pkey2);
+ jniThrowNullPointerException(env, "pkey1 == NULL");
+ return -1;
+ } else if (pkey2 == NULL) {
+ JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey2 == NULL", pkey1, pkey2);
+ jniThrowNullPointerException(env, "pkey2 == NULL");
+ return -1;
+ }
+
+ int result = EVP_PKEY_cmp(pkey1, pkey2);
+ JNI_TRACE("EVP_PKEY_cmp(%p, %p) => %d", pkey1, pkey2, result);
+ return result;
+}
+
/*
* static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int, byte[])
*/
@@ -1381,13 +1401,13 @@ static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jint
return NULL;
}
- jbyteArray n = bignumToArray(env, rsa->n);
+ jbyteArray n = bignumToArray(env, rsa->n, "n");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 0, n);
- jbyteArray e = bignumToArray(env, rsa->e);
+ jbyteArray e = bignumToArray(env, rsa->e, "e");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1419,14 +1439,14 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
return NULL;
}
- jbyteArray n = bignumToArray(env, rsa->n);
+ jbyteArray n = bignumToArray(env, rsa->n, "n");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 0, n);
if (rsa->e != NULL) {
- jbyteArray e = bignumToArray(env, rsa->e);
+ jbyteArray e = bignumToArray(env, rsa->e, "e");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1434,7 +1454,7 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
}
if (rsa->d != NULL) {
- jbyteArray d = bignumToArray(env, rsa->d);
+ jbyteArray d = bignumToArray(env, rsa->d, "d");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1442,7 +1462,7 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
}
if (rsa->p != NULL) {
- jbyteArray p = bignumToArray(env, rsa->p);
+ jbyteArray p = bignumToArray(env, rsa->p, "p");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1450,7 +1470,7 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
}
if (rsa->q != NULL) {
- jbyteArray q = bignumToArray(env, rsa->q);
+ jbyteArray q = bignumToArray(env, rsa->q, "q");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1458,7 +1478,7 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
}
if (rsa->dmp1 != NULL) {
- jbyteArray dmp1 = bignumToArray(env, rsa->dmp1);
+ jbyteArray dmp1 = bignumToArray(env, rsa->dmp1, "dmp1");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1466,7 +1486,7 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
}
if (rsa->dmq1 != NULL) {
- jbyteArray dmq1 = bignumToArray(env, rsa->dmq1);
+ jbyteArray dmq1 = bignumToArray(env, rsa->dmq1, "dmq1");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1474,7 +1494,7 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jin
}
if (rsa->iqmp != NULL) {
- jbyteArray iqmp = bignumToArray(env, rsa->iqmp);
+ jbyteArray iqmp = bignumToArray(env, rsa->iqmp, "iqmp");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1581,26 +1601,26 @@ static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jint pkeyRe
return NULL;
}
- jbyteArray g = bignumToArray(env, dsa->g);
+ jbyteArray g = bignumToArray(env, dsa->g, "g");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 0, g);
- jbyteArray p = bignumToArray(env, dsa->p);
+ jbyteArray p = bignumToArray(env, dsa->p, "p");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 1, p);
- jbyteArray q = bignumToArray(env, dsa->q);
+ jbyteArray q = bignumToArray(env, dsa->q, "q");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 2, q);
if (dsa->pub_key != NULL) {
- jbyteArray pub_key = bignumToArray(env, dsa->pub_key);
+ jbyteArray pub_key = bignumToArray(env, dsa->pub_key, "pub_key");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1608,7 +1628,7 @@ static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jint pkeyRe
}
if (dsa->priv_key != NULL) {
- jbyteArray priv_key = bignumToArray(env, dsa->priv_key);
+ jbyteArray priv_key = bignumToArray(env, dsa->priv_key, "priv_key");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1741,19 +1761,19 @@ static jobjectArray NativeCrypto_EC_GROUP_get_curve(JNIEnv* env, jclass, jint gr
return NULL;
}
- jbyteArray pArray = bignumToArray(env, p.get());
+ jbyteArray pArray = bignumToArray(env, p.get(), "p");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 0, pArray);
- jbyteArray aArray = bignumToArray(env, a.get());
+ jbyteArray aArray = bignumToArray(env, a.get(), "a");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 1, aArray);
- jbyteArray bArray = bignumToArray(env, b.get());
+ jbyteArray bArray = bignumToArray(env, b.get(), "b");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1781,7 +1801,7 @@ static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jint grou
return NULL;
}
- jbyteArray orderArray = bignumToArray(env, order.get());
+ jbyteArray orderArray = bignumToArray(env, order.get(), "order");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1808,7 +1828,7 @@ static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jint g
return NULL;
}
- jbyteArray cofactorArray = bignumToArray(env, cofactor.get());
+ jbyteArray cofactorArray = bignumToArray(env, cofactor.get(), "cofactor");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -2058,13 +2078,13 @@ static jobjectArray NativeCrypto_EC_POINT_get_affine_coordinates(JNIEnv* env, jc
return NULL;
}
- jbyteArray xBytes = bignumToArray(env, x.get());
+ jbyteArray xBytes = bignumToArray(env, x.get(), "x");
if (env->ExceptionCheck()) {
return NULL;
}
env->SetObjectArrayElement(joa, 0, xBytes);
- jbyteArray yBytes = bignumToArray(env, y.get());
+ jbyteArray yBytes = bignumToArray(env, y.get(), "y");
if (env->ExceptionCheck()) {
return NULL;
}
@@ -2127,7 +2147,7 @@ static jbyteArray NativeCrypto_EC_KEY_get_private_key(JNIEnv* env, jclass, jint
const BIGNUM *privkey = EC_KEY_get0_private_key(eckey.get());
- jbyteArray privBytes = bignumToArray(env, privkey);
+ jbyteArray privBytes = bignumToArray(env, privkey, "privkey");
if (env->ExceptionCheck()) {
JNI_TRACE("EC_KEY_get_private_key(%p) => threw error", pkey);
return NULL;
@@ -3265,12 +3285,15 @@ class AppData {
static AppData* create() {
UniquePtr<AppData> appData(new AppData());
if (pipe(appData.get()->fdsEmergency) == -1) {
+ ALOGE("AppData::create pipe(2) failed: %s", strerror(errno));
return NULL;
}
if (!setBlocking(appData.get()->fdsEmergency[0], false)) {
+ ALOGE("AppData::create fcntl(2) failed: %s", strerror(errno));
return NULL;
}
if (MUTEX_SETUP(appData.get()->mutex) == -1) {
+ ALOGE("pthread_mutex_init(3) failed: %s", strerror(errno));
return NULL;
}
return appData.release();
@@ -4756,7 +4779,7 @@ static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, ji
* cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
*/
static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
- int* sslReturnCode, int* sslErrorCode, int timeout_millis) {
+ int* sslReturnCode, int* sslErrorCode, int read_timeout_millis) {
JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
if (len == 0) {
@@ -4835,7 +4858,7 @@ static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* b
// Need to wait for availability of underlying layer, then retry.
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE: {
- int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
+ int selectResult = sslSelect(env, sslError, fdObject, appData, read_timeout_millis);
if (selectResult == THROWN_EXCEPTION) {
return THROWN_EXCEPTION;
}
@@ -4887,11 +4910,11 @@ static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* b
*/
static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
jobject shc, jbyteArray b, jint offset, jint len,
- jint timeout_millis)
+ jint read_timeout_millis)
{
SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d timeout_millis=%d",
- ssl, fdObject, shc, b, offset, len, timeout_millis);
+ JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d read_timeout_millis=%d",
+ ssl, fdObject, shc, b, offset, len, read_timeout_millis);
if (ssl == NULL) {
return 0;
}
@@ -4915,7 +4938,7 @@ static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject
int sslErrorCode = SSL_ERROR_NONE;;
int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
- &returnCode, &sslErrorCode, timeout_millis);
+ &returnCode, &sslErrorCode, read_timeout_millis);
int result;
switch (ret) {
@@ -4955,8 +4978,9 @@ static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject
* cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
*/
static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
- int* sslReturnCode, int* sslErrorCode) {
- JNI_TRACE("ssl=%p sslWrite buf=%p len=%d", ssl, buf, len);
+ int* sslReturnCode, int* sslErrorCode, int write_timeout_millis) {
+ JNI_TRACE("ssl=%p sslWrite buf=%p len=%d write_timeout_millis=%d",
+ ssl, buf, len, write_timeout_millis);
if (len == 0) {
// Don't bother doing anything in this case.
@@ -5041,7 +5065,7 @@ static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const
// it's also not standard Java behavior, so we wait forever here.
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE: {
- int selectResult = sslSelect(env, sslError, fdObject, appData, 0);
+ int selectResult = sslSelect(env, sslError, fdObject, appData, write_timeout_millis);
if (selectResult == THROWN_EXCEPTION) {
return THROWN_EXCEPTION;
}
@@ -5092,11 +5116,11 @@ static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const
* OpenSSL write function (2): write into buffer at offset n chunks.
*/
static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
- jobject shc, jbyteArray b, jint offset, jint len)
+ jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis)
{
SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d",
- ssl, fdObject, shc, b, offset, len);
+ JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d write_timeout_millis=%d",
+ ssl, fdObject, shc, b, offset, len, write_timeout_millis);
if (ssl == NULL) {
return;
}
@@ -5119,7 +5143,7 @@ static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobjec
int returnCode = 0;
int sslErrorCode = SSL_ERROR_NONE;
int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
- len, &returnCode, &sslErrorCode);
+ len, &returnCode, &sslErrorCode, write_timeout_millis);
switch (ret) {
case THROW_SSLEXCEPTION:
@@ -5435,6 +5459,7 @@ static JNINativeMethod sNativeCryptoMethods[] = {
NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(I)Ljava/lang/String;"),
NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(I)Ljava/lang/String;"),
NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"),
+ NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(II)I"),
NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(I)[B"),
NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)I"),
NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(I)[B"),
@@ -5527,7 +5552,7 @@ static JNINativeMethod sNativeCryptoMethods[] = {
NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(I)[[B"),
NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(I)[[B"),
NATIVE_METHOD(NativeCrypto, SSL_read, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
- NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BII)V"),
+ NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(I)V"),
NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(I" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
NATIVE_METHOD(NativeCrypto, SSL_free, "(I)V"),
diff --git a/luni/src/main/native/zip.h b/luni/src/main/native/zip.h
index 0f3c0c1..303c940 100644
--- a/luni/src/main/native/zip.h
+++ b/luni/src/main/native/zip.h
@@ -23,7 +23,7 @@
#include "UniquePtr.h"
#include "jni.h"
#include "zlib.h"
-#include "zutil.h"
+#include "zutil.h" // For DEF_WBITS and DEF_MEM_LEVEL.
static void throwExceptionForZlibError(JNIEnv* env, const char* exceptionClassName, int error) {
if (error == Z_MEM_ERROR) {
diff --git a/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java b/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java
index e1f51bd..e46df5d 100755
--- a/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java
@@ -46,10 +46,16 @@ public final class InterruptedStreamTest extends TestCase {
private Socket[] sockets;
+ @Override protected void setUp() throws Exception {
+ Thread.interrupted(); // clear interrupted bit
+ super.tearDown();
+ }
+
@Override protected void tearDown() throws Exception {
if (sockets != null) {
sockets[0].close();
sockets[1].close();
+ sockets = null;
}
Thread.interrupted(); // clear interrupted bit
super.tearDown();
@@ -111,56 +117,66 @@ public final class InterruptedStreamTest extends TestCase {
}
private void testInterruptInputStream(final InputStream in) throws Exception {
- interruptMeLater();
+ Thread thread = interruptMeLater();
try {
in.read();
fail();
} catch (InterruptedIOException expected) {
+ } finally {
+ waitForInterrupt(thread);
}
}
private void testInterruptReader(final PipedReader reader) throws Exception {
- interruptMeLater();
+ Thread thread = interruptMeLater();
try {
reader.read();
fail();
} catch (InterruptedIOException expected) {
+ } finally {
+ waitForInterrupt(thread);
}
}
private void testInterruptReadableChannel(final ReadableByteChannel channel) throws Exception {
- interruptMeLater();
+ Thread thread = interruptMeLater();
try {
channel.read(ByteBuffer.allocate(BUFFER_SIZE));
fail();
} catch (ClosedByInterruptException expected) {
+ } finally {
+ waitForInterrupt(thread);
}
}
private void testInterruptOutputStream(final OutputStream out) throws Exception {
- interruptMeLater();
+ Thread thread = interruptMeLater();
try {
// this will block when the receiving buffer fills up
while (true) {
out.write(new byte[BUFFER_SIZE]);
}
} catch (InterruptedIOException expected) {
+ } finally {
+ waitForInterrupt(thread);
}
}
private void testInterruptWriter(final PipedWriter writer) throws Exception {
- interruptMeLater();
+ Thread thread = interruptMeLater();
try {
// this will block when the receiving buffer fills up
while (true) {
writer.write(new char[BUFFER_SIZE]);
}
} catch (InterruptedIOException expected) {
+ } finally {
+ waitForInterrupt(thread);
}
}
private void testInterruptWritableChannel(final WritableByteChannel channel) throws Exception {
- interruptMeLater();
+ Thread thread = interruptMeLater();
try {
// this will block when the receiving buffer fills up
while (true) {
@@ -168,12 +184,14 @@ public final class InterruptedStreamTest extends TestCase {
}
} catch (ClosedByInterruptException expected) {
} catch (ClosedChannelException expected) {
+ } finally {
+ waitForInterrupt(thread);
}
}
- private void interruptMeLater() throws Exception {
+ private Thread interruptMeLater() throws Exception {
final Thread toInterrupt = Thread.currentThread();
- new Thread(new Runnable () {
+ Thread thread = new Thread(new Runnable () {
@Override public void run() {
try {
Thread.sleep(1000);
@@ -181,6 +199,20 @@ public final class InterruptedStreamTest extends TestCase {
}
toInterrupt.interrupt();
}
- }).start();
+ });
+ thread.start();
+ return thread;
+ }
+
+ private static void waitForInterrupt(Thread thread) throws Exception {
+ try {
+ thread.join();
+ } catch (InterruptedException ignore) {
+ // There is currently a race between Thread.interrupt in
+ // interruptMeLater and Thread.join here. Most of the time
+ // we won't get an InterruptedException, but occasionally
+ // we do, so for now ignore this exception.
+ // http://b/6951157
+ }
}
}
diff --git a/luni/src/test/java/libcore/java/lang/OldObjectTest.java b/luni/src/test/java/libcore/java/lang/OldObjectTest.java
index 08471b2..3ab0327 100644
--- a/luni/src/test/java/libcore/java/lang/OldObjectTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldObjectTest.java
@@ -16,8 +16,6 @@
*/
package libcore.java.lang;
-import dalvik.annotation.SideEffect;
-import java.util.Vector;
import junit.framework.TestCase;
public class OldObjectTest extends TestCase {
@@ -187,7 +185,36 @@ public class OldObjectTest extends TestCase {
fail("InterruptedException was thrown.");
}
assertEquals(3, status);
+ }
+
+ public void test_waitJI_invalid() throws Exception {
+ Object o = new Object();
+ synchronized (o) {
+ try {
+ o.wait(-1, 0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ o.wait(0, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ o.wait(-1, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ // The ms timeout must fit in 32 bits.
+ try {
+ o.wait(Integer.MAX_VALUE + 1, 0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
}
public void test_waitJ() {
diff --git a/luni/src/test/java/libcore/java/net/OldSocketTest.java b/luni/src/test/java/libcore/java/net/OldSocketTest.java
index fda9557..033a7bf 100644
--- a/luni/src/test/java/libcore/java/net/OldSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/OldSocketTest.java
@@ -38,7 +38,6 @@ import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.SocketChannel;
import java.security.Permission;
import tests.support.Support_Configuration;
-import tests.support.Support_PortManager;
public class OldSocketTest extends OldSocketTestCase {
@@ -115,17 +114,15 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_ConstructorLjava_lang_StringILjava_net_InetAddressI1() throws IOException {
int sport = startServer("Cons String,I,InetAddress,I");
- int portNumber = Support_PortManager.getNextPort();
s = new Socket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), portNumber);
+ InetAddress.getLocalHost(), 0);
assertTrue("Failed to create socket", s.getPort() == sport);
}
public void test_ConstructorLjava_lang_StringILjava_net_InetAddressI2() throws IOException {
- int testPort = Support_PortManager.getNextPort();
- Socket s1 = new Socket("www.google.com", 80, null, testPort);
+ Socket s1 = new Socket("www.google.com", 80, null, 0);
try {
- Socket s2 = new Socket("www.google.com", 80, null, testPort);
+ Socket s2 = new Socket("www.google.com", 80, null, s1.getLocalPort());
try {
s2.close();
} catch (IOException ignored) {
@@ -162,10 +159,8 @@ public class OldSocketTest extends OldSocketTestCase {
// Test for method java.net.Socket(java.net.InetAddress, int,
// java.net.InetAddress, int)
int sport = startServer("Cons InetAddress,I,InetAddress,I");
- int portNumber = Support_PortManager.getNextPort();
s = new Socket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), portNumber);
- assertTrue("Failed to create socket", s.getLocalPort() == portNumber);
+ InetAddress.getLocalHost(), 0);
}
public void test_ConstructorLjava_net_InetAddressIZ() throws IOException {
@@ -180,8 +175,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_close() throws IOException {
// Test for method void java.net.Socket.close()
int sport = startServer("SServer close");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
try {
s.setSoLinger(false, 100);
} catch (IOException e) {
@@ -199,8 +193,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getInetAddress() throws IOException {
// Test for method java.net.InetAddress java.net.Socket.getInetAddress()
int sport = startServer("SServer getInetAddress");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
assertTrue("Returned incorrect InetAddress", s.getInetAddress().equals(
InetAddress.getLocalHost()));
@@ -220,9 +213,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getKeepAlive() {
try {
int sport = startServer("SServer getKeepAlive");
- int portNumber = Support_PortManager.getNextPort();
- Socket theSocket = new Socket(InetAddress.getLocalHost(), sport,
- null, portNumber);
+ Socket theSocket = new Socket(InetAddress.getLocalHost(), sport, null, 0);
theSocket.setKeepAlive(true);
assertTrue("getKeepAlive false when it should be true", theSocket
.getKeepAlive());
@@ -254,8 +245,7 @@ public class OldSocketTest extends OldSocketTestCase {
// Test for method java.net.InetAddress
// java.net.Socket.getLocalAddress()
int sport = startServer("SServer getLocAddress");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
assertEquals("Returned incorrect InetAddress",
InetAddress.getLocalHost(), s.getLocalAddress());
@@ -271,10 +261,10 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getLocalPort() throws IOException {
// Test for method int java.net.Socket.getLocalPort()
int sport = startServer("SServer getLocalPort");
- int portNumber = Support_PortManager.getNextPort();
s = new Socket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), portNumber);
- assertTrue("Returned incorrect port", s.getLocalPort() == portNumber);
+ InetAddress.getLocalHost(), 0);
+ // There's nothing we can usefully assert about the kernel-assigned port.
+ s.getLocalPort();
}
@SuppressWarnings("deprecation")
@@ -282,15 +272,13 @@ public class OldSocketTest extends OldSocketTestCase {
// Test for method java.io.OutputStream
// java.net.Socket.getOutputStream()
int sport = startServer("SServer getOutputStream");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport);
java.io.OutputStream os = s.getOutputStream();
assertNotNull("Failed to get stream", os);
os.write(1);
s.close();
// Regression test for harmony-2934
- s = new Socket("127.0.0.1", Support_PortManager.getNextPort(),
- false);
+ s = new Socket("127.0.0.1", sport, false);
OutputStream o = s.getOutputStream();
o.write(1);
try {
@@ -301,8 +289,7 @@ public class OldSocketTest extends OldSocketTestCase {
s.close();
// Regression test for harmony-2942
- s = new Socket("0.0.0.0", Support_PortManager.getNextPort(),
- false);
+ s = new Socket("0.0.0.0", sport, false);
o = s.getOutputStream();
o.write(1);
try {
@@ -316,18 +303,15 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getPort() throws IOException {
// Test for method int java.net.Socket.getPort()
int sport = startServer("SServer getPort");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
- assertTrue("Returned incorrect port" + s.getPort(),
- s.getPort() == sport);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
+ assertTrue("Returned incorrect port" + s.getPort(), s.getPort() == sport);
}
public void test_getSoLinger() {
// Test for method int java.net.Socket.getSoLinger()
int sport = startServer("SServer getSoLinger");
try {
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.setSoLinger(true, 200);
assertEquals("Returned incorrect linger", 200, s.getSoLinger());
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_LINGER);
@@ -337,8 +321,7 @@ public class OldSocketTest extends OldSocketTestCase {
}
try {
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.close();
try {
s.getSoLinger();
@@ -354,9 +337,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getReceiveBufferSize() {
try {
int sport = startServer("SServer getReceiveBufferSize");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost().getHostName(), sport,
- null, portNumber);
+ s = new Socket(InetAddress.getLocalHost().getHostName(), sport, null, 0);
s.setReceiveBufferSize(130);
assertTrue("Incorrect buffer size", s.getReceiveBufferSize() >= 130);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_RCVBUF);
@@ -381,9 +362,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getSendBufferSize() {
int sport = startServer("SServer setSendBufferSize");
try {
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost().getHostName(), sport,
- null, portNumber);
+ s = new Socket(InetAddress.getLocalHost().getHostName(), sport, null, 0);
s.setSendBufferSize(134);
assertTrue("Incorrect buffer size", s.getSendBufferSize() >= 134);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_SNDBUF);
@@ -391,8 +370,7 @@ public class OldSocketTest extends OldSocketTestCase {
handleException(e, SO_SNDBUF);
}
try {
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.close();
try {
s.getSendBufferSize();
@@ -430,8 +408,7 @@ public class OldSocketTest extends OldSocketTestCase {
// Test for method boolean java.net.Socket.getTcpNoDelay()
int sport = startServer("SServer getTcpNoDelay");
try {
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
boolean bool = !s.getTcpNoDelay();
s.setTcpNoDelay(bool);
assertTrue("Failed to get no delay setting: " + s.getTcpNoDelay(),
@@ -442,8 +419,7 @@ public class OldSocketTest extends OldSocketTestCase {
}
try {
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.close();
try {
s.getTcpNoDelay();
@@ -461,9 +437,7 @@ public class OldSocketTest extends OldSocketTestCase {
// crashed machines. Just make sure we can set it
try {
int sport = startServer("SServer setKeepAlive");
- int portNumber = Support_PortManager.getNextPort();
- Socket theSocket = new Socket(InetAddress.getLocalHost(), sport,
- null, portNumber);
+ Socket theSocket = new Socket(InetAddress.getLocalHost(), sport, null, 0);
theSocket.setKeepAlive(true);
theSocket.setKeepAlive(false);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_KEEPALIVE);
@@ -509,8 +483,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_setSendBufferSizeI() {
try {
int sport = startServer("SServer setSendBufferSizeI");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.setSendBufferSize(134);
assertTrue("Incorrect buffer size", s.getSendBufferSize() >= 134);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_SNDBUF);
@@ -533,8 +506,7 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_setReceiveBufferSizeI() {
try {
int sport = startServer("SServer setReceiveBufferSizeI");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.setReceiveBufferSize(130);
assertTrue("Incorrect buffer size", s.getReceiveBufferSize() >= 130);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_RCVBUF);
@@ -558,8 +530,7 @@ public class OldSocketTest extends OldSocketTestCase {
// Test for method void java.net.Socket.setSoLinger(boolean, int)
try {
int sport = startServer("SServer setSoLingerZI");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
s.setSoLinger(true, 500);
assertEquals("Set incorrect linger", 500, s.getSoLinger());
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_LINGER);
@@ -584,8 +555,7 @@ public class OldSocketTest extends OldSocketTestCase {
// Test for method void java.net.Socket.setTcpNoDelay(boolean)
try {
int sport = startServer("SServer setTcpNoDelayZ");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
boolean bool;
s.setTcpNoDelay(bool = !s.getTcpNoDelay());
assertTrue("Failed to set no delay setting: " + s.getTcpNoDelay(),
@@ -610,9 +580,8 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_toString() throws IOException {
// Test for method java.lang.String java.net.Socket.toString()
int sport = startServer("SServer toString");
- int portNumber = Support_PortManager.getNextPort();
s = new Socket(InetAddress.getLocalHost().getHostName(), sport,
- InetAddress.getLocalHost(), portNumber);
+ InetAddress.getLocalHost(), 0);
assertEquals("Socket[address=" + InetAddress.getLocalHost() + ",port=" + s.getPort()
+ ",localPort=" + s.getLocalPort() + "]", s.toString());
}
@@ -620,9 +589,8 @@ public class OldSocketTest extends OldSocketTestCase {
// AndroidOnly: RI returns wrong value for EOF
public void test_shutdownInput() throws Exception {
InetAddress addr = InetAddress.getLocalHost();
- int port = Support_PortManager.getNextPort();
- ServerSocket serverSocket = new ServerSocket(port, 5, addr);
- Socket theSocket = new Socket(addr, port);
+ ServerSocket serverSocket = new ServerSocket(0, 5, addr);
+ Socket theSocket = new Socket(addr, serverSocket.getLocalPort());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
@@ -656,10 +624,8 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_shutdownOutput() throws IOException {
- InetAddress addr = InetAddress.getLocalHost();
- int port = Support_PortManager.getNextPort();
- ServerSocket serverSocket = new ServerSocket(port, 5, addr);
- Socket theSocket = new Socket(addr, port);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ Socket theSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
@@ -692,17 +658,9 @@ public class OldSocketTest extends OldSocketTestCase {
// set up server connect and then validate that we get the right
// response for the local address
int sport = startServer("SServer getLocSocketAddress");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
- assertTrue(
- "Returned incorrect InetSocketAddress(1):"
- + s.getLocalSocketAddress().toString()
- + "Expected: "
- + (new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber)).toString(), s
- .getLocalSocketAddress().equals(
- new InetSocketAddress(InetAddress
- .getLocalHost(), portNumber)));
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
+ assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), s.getLocalPort()),
+ s.getLocalSocketAddress());
s.close();
// now create a socket that is not bound and validate we get the
@@ -713,21 +671,12 @@ public class OldSocketTest extends OldSocketTestCase {
theSocket.getLocalSocketAddress());
// now bind the socket and make sure we get the right answer
- portNumber = Support_PortManager.getNextPort();
- theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber));
- assertTrue(
- "Returned incorrect InetSocketAddress(2):"
- + theSocket.getLocalSocketAddress().toString()
- + "Expected: "
- + (new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber)).toString(), theSocket
- .getLocalSocketAddress().equals(
- new InetSocketAddress(InetAddress
- .getLocalHost(), portNumber)));
+ theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), theSocket.getLocalPort()),
+ theSocket.getLocalSocketAddress());
theSocket.close();
- // now validate that behaviour when the any address is returned
+ // now validate that behavior when the any address is returned
s = new Socket();
s.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
@@ -747,8 +696,7 @@ public class OldSocketTest extends OldSocketTestCase {
// set up server connect and then validate that we get the right
// response for the remote address
int sport = startServer("SServer getLocRemoteAddress");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
+ s = new Socket(InetAddress.getLocalHost(), sport, null, 0);
assertTrue("Returned incorrect InetSocketAddress(1):"
+ s.getLocalSocketAddress().toString(),
s.getRemoteSocketAddress()
@@ -760,9 +708,7 @@ public class OldSocketTest extends OldSocketTestCase {
// now create one that is not connect and validate that we get the
// right answer
Socket theSocket = new Socket();
- portNumber = Support_PortManager.getNextPort();
- theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber));
+ theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
assertNull("Returned incorrect InetSocketAddress -unconnected socket:"
+ "Expected: NULL", theSocket.getRemoteSocketAddress());
@@ -781,10 +727,8 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_isBound() throws IOException {
- InetAddress addr = InetAddress.getLocalHost();
- int port = Support_PortManager.getNextPort();
- ServerSocket serverSocket = new ServerSocket(port, 5, addr);
- Socket theSocket = new Socket(addr, port);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ Socket theSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
Socket servSock = serverSocket.accept();
assertTrue("Socket indicated not bound when it should be (1)",
theSocket.isBound());
@@ -793,14 +737,11 @@ public class OldSocketTest extends OldSocketTestCase {
// now do it with the new constructors and revalidate. Connect causes
// the socket to be bound
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
theSocket = new Socket();
assertFalse("Socket indicated bound when it was not (2)", theSocket
.isBound());
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
servSock = serverSocket.accept();
assertTrue("Socket indicated not bound when it should be (2)",
theSocket.isBound());
@@ -808,12 +749,10 @@ public class OldSocketTest extends OldSocketTestCase {
serverSocket.close();
// now test when we bind explicitly
- InetSocketAddress theLocalAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
theSocket = new Socket();
assertFalse("Socket indicated bound when it was not (3)", theSocket
.isBound());
- theSocket.bind(theLocalAddress);
+ theSocket.bind(null);
assertTrue("Socket indicated not bound when it should be (3a)",
theSocket.isBound());
theSocket.close();
@@ -822,10 +761,8 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_isConnected() throws IOException {
- InetAddress addr = InetAddress.getLocalHost();
- int port = Support_PortManager.getNextPort();
- ServerSocket serverSocket = new ServerSocket(port, 5, addr);
- Socket theSocket = new Socket(addr, port);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ Socket theSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
Socket servSock = serverSocket.accept();
assertTrue("Socket indicated not connected when it should be",
theSocket.isConnected());
@@ -833,14 +770,11 @@ public class OldSocketTest extends OldSocketTestCase {
serverSocket.close();
// now do it with the new constructors and revalidate
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
theSocket = new Socket();
assertFalse("Socket indicated connected when it was not", theSocket
.isConnected());
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
servSock = serverSocket.accept();
assertTrue("Socket indicated not connected when it should be",
theSocket.isConnected());
@@ -849,10 +783,8 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_isClosed() throws IOException {
- InetAddress addr = InetAddress.getLocalHost();
- int port = Support_PortManager.getNextPort();
- ServerSocket serverSocket = new ServerSocket(port, 5, addr);
- Socket theSocket = new Socket(addr, port);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ Socket theSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
Socket servSock = serverSocket.accept();
// validate isClosed returns expected values
@@ -862,7 +794,7 @@ public class OldSocketTest extends OldSocketTestCase {
assertTrue("Socket should indicate it is closed(1):", theSocket
.isClosed());
- theSocket = new Socket(addr, port);
+ theSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
assertFalse("Socket should indicate it is not closed(2):", theSocket
.isClosed());
theSocket.close();
@@ -891,7 +823,7 @@ public class OldSocketTest extends OldSocketTestCase {
try {
theSocket.bind(new InetSocketAddress(InetAddress
.getByAddress(Support_Configuration.nonLocalAddressBytes),
- Support_PortManager.getNextPort()));
+ 80));
fail("No exception when binding to bad address:"
+ theSocket.getLocalSocketAddress().toString());
} catch (IOException ex) {
@@ -900,39 +832,21 @@ public class OldSocketTest extends OldSocketTestCase {
// now create a socket that is not bound and then bind it
theSocket = new Socket();
- int portNumber = Support_PortManager.getNextPort();
theSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber));
+ 0));
// validate that the localSocketAddress reflects the address we
// bound to
- assertTrue(
- "Local address not correct after bind:"
- + theSocket.getLocalSocketAddress().toString()
- + " Expected: "
- + (new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber)).toString(), theSocket
- .getLocalSocketAddress().equals(
- new InetSocketAddress(InetAddress
- .getLocalHost(), portNumber)));
+ assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), theSocket.getLocalPort()),
+ theSocket.getLocalSocketAddress());
// make sure we can now connect and that connections appear to come
// from the address we bound to.
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
- ServerSocket serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
Socket servSock = serverSocket.accept();
- assertTrue(
- "Returned Remote address from server connected to does not match expected local address:"
- + servSock.getRemoteSocketAddress().toString()
- + " Expected: "
- + (new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber)).toString(), servSock
- .getRemoteSocketAddress().equals(
- new InetSocketAddress(InetAddress
- .getLocalHost(), portNumber)));
+ assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), theSocket.getLocalPort()),
+ servSock.getRemoteSocketAddress());
theSocket.close();
servSock.close();
serverSocket.close();
@@ -951,10 +865,8 @@ public class OldSocketTest extends OldSocketTestCase {
theSocket = new Socket();
Socket theSocket2 = new Socket();
try {
- theAddress = new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
- theSocket.bind(theAddress);
- theSocket2.bind(theAddress);
+ theSocket.bind(null);
+ theSocket2.bind(theSocket.getLocalSocketAddress());
fail("No exception binding to address that is not available");
} catch (IOException ex) {
}
@@ -1020,7 +932,7 @@ public class OldSocketTest extends OldSocketTestCase {
}
// start by validating the error checks
- int portNumber = Support_PortManager.getNextPort();
+ int portNumber = 0;
Socket theSocket = null;
ServerSocket serverSocket = null;
SocketAddress theAddress = null;
@@ -1084,17 +996,8 @@ public class OldSocketTest extends OldSocketTestCase {
// now validate that we can actually connect when somebody is listening
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
- theSocket.close();
- serverSocket.close();
-
- // now validate that we can actually connect when somebody is listening
- theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
// validate that when a socket is connected that it answers
// correctly to related queries
@@ -1119,10 +1022,9 @@ public class OldSocketTest extends OldSocketTestCase {
// are already connected
try {
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
+ theSocket.connect(serverSocket.getLocalSocketAddress());
theSocket.close();
serverSocket.close();
fail("No exception when we try to connect on a connected socket: ");
@@ -1145,9 +1047,8 @@ public class OldSocketTest extends OldSocketTestCase {
// now validate that connected socket can be used to read/write
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
OutputStream theOutput = servSock.getOutputStream();
@@ -1197,10 +1098,8 @@ public class OldSocketTest extends OldSocketTestCase {
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
Socket socket = channel.socket();
- int port = Support_PortManager.getNextPort();
try {
- socket.connect( new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort()));
+ socket.connect(serverSocket.getLocalSocketAddress());
fail("IllegalBlockingModeException was not thrown.");
} catch (IllegalBlockingModeException expected) {
}
@@ -1263,28 +1162,14 @@ public class OldSocketTest extends OldSocketTestCase {
}
// start by validating the error checks
- int portNumber = Support_PortManager.getNextPort();
- Socket theSocket = null;
- ServerSocket serverSocket = null;
- SocketAddress theAddress = null;
- SocketAddress nonConnectableAddress = null;
- SocketAddress nonReachableAddress = null;
- SocketAddress nonListeningAddress = null;
- SocketAddress invalidType = null;
byte[] theBytes = { 0, 0, 0, 0 };
+ SocketAddress theAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
+ SocketAddress nonConnectableAddress = new InetSocketAddress(InetAddress.getByAddress(theBytes), 0);
+ SocketAddress nonReachableAddress = new InetSocketAddress(InetAddress.getByName(Support_Configuration.ResolvedNotExistingHost), 0);
+ SocketAddress invalidType = new mySocketAddress();
- theAddress = new InetSocketAddress(InetAddress.getLocalHost(),
- portNumber);
- nonConnectableAddress = new InetSocketAddress(InetAddress
- .getByAddress(theBytes), portNumber);
- nonReachableAddress = new InetSocketAddress(InetAddress
- .getByName(Support_Configuration.ResolvedNotExistingHost),
- portNumber);
- // make sure we get another port
- Thread.sleep(7000);
- nonListeningAddress = new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
- invalidType = new mySocketAddress();
+ Socket theSocket = null;
+ ServerSocket serverSocket = null;
try {
theSocket = new Socket();
@@ -1340,9 +1225,8 @@ public class OldSocketTest extends OldSocketTestCase {
// now validate that we can actually connect when somebody is listening
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress, 0);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
theSocket.close();
serverSocket.close();
@@ -1350,7 +1234,7 @@ public class OldSocketTest extends OldSocketTestCase {
// an address on which nobody is listening
try {
theSocket = new Socket();
- theSocket.connect(nonListeningAddress, 100000);
+ theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 80), 100000);
theSocket.close();
fail("No exception when connecting to address nobody listening on: ");
} catch (Exception e) {
@@ -1390,12 +1274,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
// now validate that we can actually connect when somebody is listening
- new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager
- .getNextPort());
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress, 100000);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
// validate that when a socket is connected that it answers
// correctly to related queries
@@ -1419,8 +1300,6 @@ public class OldSocketTest extends OldSocketTestCase {
// now validate that we get the right exception if we connect when we
// are already connected
try {
- new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
theSocket = new Socket();
serverSocket = new ServerSocket();
serverSocket.bind(theAddress);
@@ -1447,12 +1326,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
// now validate that connected socket can be used to read/write
- new InetSocketAddress(InetAddress.getLocalHost(), Support_PortManager
- .getNextPort());
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress, 100000);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
OutputStream theOutput = servSock.getOutputStream();
@@ -1515,10 +1391,8 @@ public class OldSocketTest extends OldSocketTestCase {
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
Socket socket = channel.socket();
- int port = Support_PortManager.getNextPort();
try {
- socket.connect( new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort()), port);
+ socket.connect(serverSocket.getLocalSocketAddress());
fail("IllegalBlockingModeException was not thrown.");
} catch (IllegalBlockingModeException expected) {
}
@@ -1526,12 +1400,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_isInputShutdown() throws IOException {
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
Socket theSocket = new Socket();
- ServerSocket serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
OutputStream theOutput = servSock.getOutputStream();
@@ -1559,12 +1430,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
public void test_isOutputShutdown() throws IOException {
- InetSocketAddress theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
Socket theSocket = new Socket();
- ServerSocket serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
OutputStream theOutput = servSock.getOutputStream();
@@ -1591,18 +1459,14 @@ public class OldSocketTest extends OldSocketTestCase {
}
- public void test_setReuseAddressZ() {
+ public void test_setReuseAddressZ() throws Exception {
try {
InetAddress allAddresses[] = InetAddress.getAllByName(InetAddress
.getLocalHost().getHostName());
if (allAddresses.length > 1) {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPort());
- ServerSocket serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
// try to bind to port address that is already in use with
// reuseAddress = false.
@@ -1612,17 +1476,15 @@ public class OldSocketTest extends OldSocketTestCase {
// what the expected result is. It seems that on linux
// platforms we also don't get an exception.
InetSocketAddress theLocalAddress = new InetSocketAddress(
- (InetAddress) allAddresses[1], Support_PortManager
- .getNextPort());
+ (InetAddress) allAddresses[1], 0);
InetSocketAddress theOtherLocalAddress = new InetSocketAddress(
- (InetAddress) allAddresses[0], theLocalAddress
- .getPort());
+ (InetAddress) allAddresses[0], theLocalAddress.getPort());
Socket theSocket = new Socket();
theSocket.setReuseAddress(false);
theSocket.bind(theLocalAddress);
Socket theSocket2 = null;
String platform = System.getProperty("os.name");
- try {
+
theSocket2 = new Socket();
theSocket2.setReuseAddress(false);
theSocket2.bind(theOtherLocalAddress);
@@ -1639,69 +1501,34 @@ public class OldSocketTest extends OldSocketTestCase {
+ ":"
+ theOtherLocalAddress.toString());
}
- } catch (IOException ex) {
- if ((platform.startsWith("Linux"))
- || ((platform.startsWith("Windows")) && ((((InetAddress) allAddresses[0]) instanceof Inet4Address) && (((InetAddress) allAddresses[1]) instanceof Inet4Address)))) {
- fail("Got unexpected exception when binding with setReuseAddress false on windows platform:"
- + theAddress.toString() + ":" + ex.toString());
- }
- }
theSocket.close();
theSocket2.close();
// try to bind to port that is already in use with reuseAddress
// = true
- theLocalAddress = new InetSocketAddress(
- (InetAddress) allAddresses[0], Support_PortManager
- .getNextPort());
- theOtherLocalAddress = new InetSocketAddress(
- (InetAddress) allAddresses[1], theLocalAddress
- .getPort());
+ theLocalAddress = new InetSocketAddress((InetAddress) allAddresses[0], 0);
theSocket = new Socket();
theSocket.setReuseAddress(true);
theSocket.bind(theLocalAddress);
- try {
- theSocket2 = new Socket();
- theSocket2.setReuseAddress(true);
- theSocket2.bind(theOtherLocalAddress);
- theSocket2.close();
- } catch (IOException ex) {
- fail("IOException when setReuseAddress is true and we bind :"
- + ex.toString());
- }
+ theSocket2 = new Socket();
+ theSocket2.setReuseAddress(true);
+ theOtherLocalAddress = new InetSocketAddress((InetAddress) allAddresses[1], theSocket.getLocalPort());
+ theSocket2.bind(theOtherLocalAddress);
+ theSocket2.close();
theSocket.close();
serverSocket.close();
// try with default behavior which should be the same on all
// platforms
- theLocalAddress = new InetSocketAddress(
- (InetAddress) allAddresses[0], Support_PortManager
- .getNextPort());
- theOtherLocalAddress = new InetSocketAddress(
- (InetAddress) allAddresses[1], theLocalAddress
- .getPort());
+ theLocalAddress = new InetSocketAddress((InetAddress) allAddresses[0], 0);
theSocket = new Socket();
theSocket.bind(theLocalAddress);
- try {
- theSocket2 = new Socket();
- theSocket2.bind(theOtherLocalAddress);
- theSocket2.close();
- if ((!platform.startsWith("Linux"))
- && ((!platform.startsWith("Windows")) || !((((InetAddress) allAddresses[0]) instanceof Inet4Address) && (((InetAddress) allAddresses[1]) instanceof Inet4Address)))) {
- fail("No exception when setReuseAddress is default and we bind:"
- + theLocalAddress.toString()
- + ":"
- + theOtherLocalAddress.toString());
- }
- } catch (IOException ex) {
- if ((platform.startsWith("Linux"))
- || ((platform.startsWith("Windows")) && ((((InetAddress) allAddresses[0]) instanceof Inet4Address) && (((InetAddress) allAddresses[1]) instanceof Inet4Address)))) {
- fail("Got unexpected exception when binding with setReuseAddress default on windows platform:"
- + theAddress.toString() + ":" + ex.toString());
- }
- }
+ theSocket2 = new Socket();
+ theOtherLocalAddress = new InetSocketAddress((InetAddress) allAddresses[1], theSocket.getLocalPort());
+ theSocket2.bind(theOtherLocalAddress);
+ theSocket2.close();
theSocket.close();
serverSocket.close();
@@ -1754,8 +1581,6 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_setOOBInlineZ() {
// mostly tested in getOOBInline. Just set to make sure call works ok
try {
- new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
Socket theSocket = new Socket();
theSocket.setOOBInline(true);
assertTrue("expected OOBIline to be true", theSocket.getOOBInline());
@@ -1779,8 +1604,6 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getOOBInline() {
try {
- new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
Socket theSocket = new Socket();
// validate that value reflects what we set it to true after true,
@@ -1812,8 +1635,6 @@ public class OldSocketTest extends OldSocketTestCase {
int IPTOS_LOWCOST = 0x2;
int IPTOS_THROUGHPUT = 0x8;
- new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
Socket theSocket = new Socket();
// validate that value set must be between 0 and 255
@@ -1851,8 +1672,6 @@ public class OldSocketTest extends OldSocketTestCase {
public void test_getTrafficClass() {
try {
- new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
Socket theSocket = new Socket();
/*
@@ -1888,13 +1707,9 @@ public class OldSocketTest extends OldSocketTestCase {
// is silently ignored
String urgentData = "U";
try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPort());
Socket theSocket = new Socket();
- ServerSocket serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ ServerSocket serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
Socket servSock = serverSocket.accept();
InputStream theInput = theSocket.getInputStream();
OutputStream theOutput = servSock.getOutputStream();
@@ -1931,12 +1746,9 @@ public class OldSocketTest extends OldSocketTestCase {
// now validate that urgent data is received as expected. Expect
// that it should be between the two writes.
- theAddress = new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
servSock = serverSocket.accept();
theInput = theSocket.getInputStream();
theOutput = servSock.getOutputStream();
@@ -1973,12 +1785,9 @@ public class OldSocketTest extends OldSocketTestCase {
serverSocket.close();
// now test case where we try to send two urgent bytes.
- theAddress = new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
servSock = serverSocket.accept();
theInput = theSocket.getInputStream();
theOutput = servSock.getOutputStream();
@@ -2022,12 +1831,9 @@ public class OldSocketTest extends OldSocketTestCase {
*/
if (!platform.startsWith("Windows")) {
// now test the case were we send turn the OOBInline on/off
- theAddress = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPort());
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
servSock = serverSocket.accept();
theInput = theSocket.getInputStream();
theOutput = servSock.getOutputStream();
@@ -2139,12 +1945,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
// now test the case where there is only urgent data
- theAddress = new InetSocketAddress(InetAddress.getLocalHost(),
- Support_PortManager.getNextPort());
theSocket = new Socket();
- serverSocket = new ServerSocket();
- serverSocket.bind(theAddress);
- theSocket.connect(theAddress);
+ serverSocket = new ServerSocket(0, 5);
+ theSocket.connect(serverSocket.getLocalSocketAddress());
servSock = serverSocket.accept();
theInput = theSocket.getInputStream();
theOutput = servSock.getOutputStream();
@@ -2370,13 +2173,9 @@ public class OldSocketTest extends OldSocketTestCase {
}
- /**
- *
- */
protected int startServer(String name) {
- int portNumber = Support_PortManager.getNextPort();
try {
- ss = new ServerSocket(portNumber, 5);
+ ss = new ServerSocket(0, 5);
} catch (IOException e) {
fail(name + ": " + e);
}
diff --git a/luni/src/test/java/libcore/java/security/KeyStoreTest.java b/luni/src/test/java/libcore/java/security/KeyStoreTest.java
index 15314c9..ddee6ce 100644
--- a/luni/src/test/java/libcore/java/security/KeyStoreTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyStoreTest.java
@@ -45,6 +45,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -65,10 +66,12 @@ public class KeyStoreTest extends TestCase {
private static final String ALIAS_SECRET = "secret";
private static final String ALIAS_ALT_CASE_PRIVATE = "pRiVaTe";
+ private static final String ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE = "PrIvAtE-no-password";
private static final String ALIAS_ALT_CASE_CERTIFICATE = "cErTiFiCaTe";
private static final String ALIAS_ALT_CASE_SECRET = "sEcRet";
private static final String ALIAS_UNICODE_PRIVATE = "\u6400\u7902\u3101\u8c02\u5002\u8702\udd01";
+ private static final String ALIAS_UNICODE_NO_PASSWORD_PRIVATE = "\u926c\u0967\uc65b\ubc78";
private static final String ALIAS_UNICODE_CERTIFICATE = "\u5402\udd01\u7902\u8702\u3101\u5f02\u3101\u5402\u5002\u8702\udd01";
private static final String ALIAS_UNICODE_SECRET = "\ue224\ud424\ud224\ue124\ud424\ue324";
@@ -146,7 +149,8 @@ public class KeyStoreTest extends TestCase {
// JKS key stores cannot store secret keys, neither can the RI's PKCS12
return (!(ks.getType().equals("JKS")
|| ks.getType().equals("CaseExactJKS")
- || (ks.getType().equals("PKCS12"))));
+ || (ks.getType().equals("PKCS12"))
+ || (ks.getType().equals("AndroidKeyStore"))));
}
private static boolean isCertificateEnabled(KeyStore ks) {
@@ -157,13 +161,16 @@ public class KeyStoreTest extends TestCase {
private static boolean isCaseSensitive(KeyStore ks) {
return (ks.getType().equals("CaseExactJKS")
|| ks.getType().equals("BKS")
- || ks.getType().equals("BouncyCastle"));
+ || ks.getType().equals("BouncyCastle")
+ || ks.getType().equals("AndroidKeyStore"));
}
private static boolean isUnsupported(KeyStore ks) {
// Don't bother testing BC on RI
- return (StandardNames.IS_RI && ks.getProvider().getName().equals("BC"));
+ // TODO enable AndroidKeyStore when CTS can set up the keystore
+ return (StandardNames.IS_RI && ks.getProvider().getName().equals("BC"))
+ || "AndroidKeyStore".equalsIgnoreCase(ks.getType());
}
private static boolean isNullPasswordAllowed(KeyStore ks) {
@@ -172,7 +179,9 @@ public class KeyStoreTest extends TestCase {
|| ks.getType().equals("JCEKS")
|| ks.getType().equals("PKCS12")));
}
-
+ private static boolean isKeyPasswordSupported(KeyStore ks) {
+ return !ks.getType().equals("AndroidKeyStore");
+ }
private static boolean isKeyPasswordIgnored(KeyStore ks) {
// BouncyCastle's PKCS12 ignores the key password unlike the RI which requires it
return (ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("BC"));
@@ -183,6 +192,14 @@ public class KeyStoreTest extends TestCase {
return (ks.getType().equals("PKCS12") && ks.getProvider().getName().equals("BC"));
}
+ private static boolean isPersistentStorage(KeyStore ks) {
+ return ks.getType().equalsIgnoreCase("AndroidKeyStore");
+ }
+
+ private static boolean isLoadStoreUnsupported(KeyStore ks) {
+ return ks.getType().equalsIgnoreCase("AndroidKeyStore");
+ }
+
private static boolean isSetKeyByteArrayUnimplemented(KeyStore ks) {
// All of BouncyCastle's
// KeyStore.setKeyEntry(String,byte[],char[]) implementations
@@ -203,16 +220,13 @@ public class KeyStoreTest extends TestCase {
}
public static void populate(KeyStore ks) throws Exception {
- ks.load(null, null);
- if (isReadOnly(ks)) {
- try {
- setPrivateKey(ks);
- fail(ks.toString());
- } catch (UnsupportedOperationException e) {
- }
+ boolean readOnly = clearKeyStore(ks);
+ if (readOnly) {
return;
}
- setPrivateKey(ks);
+ if (isKeyPasswordSupported(ks)) {
+ setPrivateKey(ks);
+ }
if (isNullPasswordAllowed(ks)) {
ks.setKeyEntry(ALIAS_NO_PASSWORD_PRIVATE,
getPrivateKey().getPrivateKey(),
@@ -234,6 +248,30 @@ public class KeyStoreTest extends TestCase {
}
}
+ private static boolean clearKeyStore(KeyStore ks) throws Exception {
+ ks.load(null, null);
+ if (isReadOnly(ks)) {
+ try {
+ setPrivateKey(ks);
+ fail(ks.toString());
+ } catch (UnsupportedOperationException e) {
+ }
+ return true;
+ }
+ if (isPersistentStorage(ks)) {
+ Enumeration<String> aliases = ks.aliases();
+ while (aliases.hasMoreElements()) {
+ String alias = aliases.nextElement();
+ ks.deleteEntry(alias);
+ }
+ }
+ return false;
+ }
+
+ public static void setPrivateKeyNoPassword(KeyStore ks, String alias, PrivateKeyEntry privateKey)
+ throws Exception {
+ ks.setKeyEntry(alias, privateKey.getPrivateKey(), null, privateKey.getCertificateChain());
+ }
public static void setPrivateKey(KeyStore ks) throws Exception {
setPrivateKey(ks, ALIAS_PRIVATE);
}
@@ -492,7 +530,12 @@ public class KeyStoreTest extends TestCase {
if (isReadOnly(keyStore)) {
assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
} else {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
} else {
@@ -503,21 +546,27 @@ public class KeyStoreTest extends TestCase {
// test case insensitive
if (isCaseSensitive(keyStore) || isReadOnly(keyStore)) {
assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, PASSWORD_KEY));
assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
} else {
- assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
}
}
// test with null passwords
- if (isKeyPasswordIgnored(keyStore)) {
+ if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
} else {
if (isReadOnly(keyStore)) {
assertNull(keyStore.getKey(ALIAS_PRIVATE, null));
- } else {
+ } else if (isKeyPasswordSupported(keyStore)) {
try {
keyStore.getKey(ALIAS_PRIVATE, null);
fail(keyStore.getType());
@@ -546,9 +595,9 @@ public class KeyStoreTest extends TestCase {
// test with bad passwords
if (isReadOnly(keyStore)) {
assertNull(keyStore.getKey(ALIAS_PRIVATE, null));
- } else if (isKeyPasswordIgnored(keyStore)) {
+ } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
- } else {
+ } else if (isKeyPasswordSupported(keyStore)) {
try {
keyStore.getKey(ALIAS_PRIVATE, PASSWORD_BAD);
fail(keyStore.getType());
@@ -593,8 +642,10 @@ public class KeyStoreTest extends TestCase {
// test case sensitive
if (isReadOnly(keyStore)) {
assertNull(keyStore.getCertificateChain(ALIAS_PRIVATE));
- } else {
+ } else if (isKeyPasswordSupported(keyStore)) {
assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ } else if (isNullPasswordAllowed(keyStore)) {
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
}
// test case insensitive
@@ -657,9 +708,10 @@ public class KeyStoreTest extends TestCase {
}
long before = System.currentTimeMillis();
for (KeyStore keyStore : keyStores()) {
+ populate(keyStore);
+
// add 1000 since some key stores round of time to nearest second
long after = System.currentTimeMillis() + 1000;
- populate(keyStore);
// test odd inputs
try {
@@ -673,8 +725,10 @@ public class KeyStoreTest extends TestCase {
if (!isReadOnly(keyStore) && isCertificateEnabled(keyStore)) {
Date date = keyStore.getCreationDate(ALIAS_CERTIFICATE);
assertNotNull(date);
- assertTrue(before <= date.getTime());
- assertTrue(date.getTime() <= after);
+ assertTrue("date should be after start time: " + date.getTime() + " >= " + before,
+ before <= date.getTime());
+ assertTrue("date should be before expiry time: " + date.getTime() + " <= " + after,
+ date.getTime() <= after);
} else {
assertNull(keyStore.getCreationDate(ALIAS_CERTIFICATE));
}
@@ -737,15 +791,24 @@ public class KeyStoreTest extends TestCase {
PASSWORD_KEY,
null);
fail(keyStore.getType());
- } catch (IllegalArgumentException expected) {
+ } catch (Exception e) {
+ if (e.getClass() != IllegalArgumentException.class
+ && e.getClass() != KeyStoreException.class) {
+ throw e;
+ }
}
}
for (KeyStore keyStore : keyStores()) {
- keyStore.load(null, null);
+ clearKeyStore(keyStore);
// test case sensitive
- assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ }
if (isReadOnly(keyStore)) {
try {
keyStore.setKeyEntry(ALIAS_SECRET, getSecretKey(), PASSWORD_KEY, null);
@@ -754,9 +817,16 @@ public class KeyStoreTest extends TestCase {
}
continue;
}
- setPrivateKey(keyStore);
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ setPrivateKey(keyStore);
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ setPrivateKeyNoPassword(keyStore, ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey());
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
setSecretKey(keyStore);
@@ -783,11 +853,22 @@ public class KeyStoreTest extends TestCase {
assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
} else if (isCaseSensitive(keyStore)) {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
- setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ }
+
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
+ getPrivateKey2());
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
@@ -797,11 +878,22 @@ public class KeyStoreTest extends TestCase {
assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
}
} else {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
- setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
- assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ setPrivateKey(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+ assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ }
+
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, null));
+ assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ setPrivateKey(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, getPrivateKey2());
+ assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, null));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ }
+
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
assertSecretKey(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
@@ -913,10 +1005,15 @@ public class KeyStoreTest extends TestCase {
continue;
}
- keyStore.load(null, null);
+ clearKeyStore(keyStore);
// test case sensitive
- assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ }
if (isReadOnly(keyStore)) {
try {
setPrivateKeyBytes(keyStore);
@@ -925,9 +1022,16 @@ public class KeyStoreTest extends TestCase {
}
continue;
}
- setPrivateKeyBytes(keyStore);
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ setPrivateKeyBytes(keyStore);
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ setPrivateKeyNoPassword(keyStore, ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey());
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
setSecretKeyBytes(keyStore);
@@ -959,11 +1063,21 @@ public class KeyStoreTest extends TestCase {
assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
} else if (isCaseSensitive(keyStore)) {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
- setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
+ getPrivateKey2());
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
@@ -973,11 +1087,21 @@ public class KeyStoreTest extends TestCase {
assertSecretKey2(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
}
} else {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
- setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
- assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ setPrivateKeyBytes(keyStore, ALIAS_ALT_CASE_PRIVATE, getPrivateKey2());
+ assertPrivateKey2(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertPrivateKey(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ setPrivateKeyNoPassword(keyStore, ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE,
+ getPrivateKey2());
+ assertPrivateKey2(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
@@ -1031,13 +1155,17 @@ public class KeyStoreTest extends TestCase {
try {
int size = keyStore.size();
keyStore.setCertificateEntry(ALIAS_CERTIFICATE, null);
- assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
- assertEquals(size, keyStore.size());
- assertTrue(keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
- assertTrue(Collections.list(keyStore.aliases()).contains(ALIAS_CERTIFICATE));
+ assertNull(keyStore.getType(), keyStore.getCertificate(ALIAS_CERTIFICATE));
+ assertEquals(keyStore.getType(), size, keyStore.size());
+ assertTrue(keyStore.getType(), keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
+ assertTrue(keyStore.getType(),
+ Collections.list(keyStore.aliases()).contains(ALIAS_CERTIFICATE));
} catch (NullPointerException expectedSometimes) {
- assertEquals("PKCS12", keyStore.getType());
- assertEquals("BC", keyStore.getProvider().getName());
+ if (!("PKCS12".equalsIgnoreCase(keyStore.getType()) &&
+ "BC".equalsIgnoreCase(keyStore.getProvider().getName()))
+ && !"AndroidKeyStore".equalsIgnoreCase(keyStore.getType())) {
+ throw expectedSometimes;
+ }
}
} else {
try {
@@ -1053,9 +1181,8 @@ public class KeyStoreTest extends TestCase {
continue;
}
- keyStore.load(null, null);
+ clearKeyStore(keyStore);
- // test case sensitive
assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
if (isReadOnly(keyStore)) {
try {
@@ -1077,10 +1204,8 @@ public class KeyStoreTest extends TestCase {
populate(keyStore);
if (isReadOnly(keyStore)) {
- assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
- assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
- assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
+ assertNull(keyStore.getCertificate(ALIAS_CERTIFICATE));
+ assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
} else if (isCaseSensitive(keyStore)) {
assertCertificate(keyStore.getCertificate(ALIAS_CERTIFICATE));
assertNull(keyStore.getCertificate(ALIAS_ALT_CASE_CERTIFICATE));
@@ -1146,10 +1271,18 @@ public class KeyStoreTest extends TestCase {
}
// test case sensitive
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
- keyStore.deleteEntry(ALIAS_PRIVATE);
- assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ keyStore.deleteEntry(ALIAS_PRIVATE);
+ assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+ keyStore.deleteEntry(ALIAS_NO_PASSWORD_PRIVATE);
+ assertNull(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
@@ -1174,9 +1307,16 @@ public class KeyStoreTest extends TestCase {
// test case insensitive
if (isCaseSensitive(keyStore)) {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- keyStore.deleteEntry(ALIAS_ALT_CASE_PRIVATE);
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ keyStore.deleteEntry(ALIAS_ALT_CASE_PRIVATE);
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ keyStore.deleteEntry(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE);
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
@@ -1208,10 +1348,14 @@ public class KeyStoreTest extends TestCase {
for (KeyStore keyStore : keyStores()) {
keyStore.load(null, null);
- if (hasDefaultContents(keyStore)) {
- assertTrue(keyStore.aliases().hasMoreElements());
+ if (isPersistentStorage(keyStore)) {
+ assertNotNull("Should be able to query size: " + keyStore.getType(),
+ keyStore.aliases());
+ } else if (hasDefaultContents(keyStore)) {
+ assertTrue("Should have more than one alias already: " + keyStore.getType(),
+ keyStore.aliases().hasMoreElements());
} else {
- assertEquals(Collections.EMPTY_SET,
+ assertEquals("Should have no aliases:" + keyStore.getType(), Collections.EMPTY_SET,
new HashSet(Collections.list(keyStore.aliases())));
}
}
@@ -1220,7 +1364,9 @@ public class KeyStoreTest extends TestCase {
populate(keyStore);
Set<String> expected = new HashSet<String>();
- expected.add(ALIAS_PRIVATE);
+ if (isKeyPasswordSupported(keyStore)) {
+ expected.add(ALIAS_PRIVATE);
+ }
if (isNullPasswordAllowed(keyStore)) {
expected.add(ALIAS_NO_PASSWORD_PRIVATE);
}
@@ -1233,7 +1379,10 @@ public class KeyStoreTest extends TestCase {
if (isCertificateEnabled(keyStore)) {
expected.add(ALIAS_CERTIFICATE);
}
- if (hasDefaultContents(keyStore)) {
+ if (isPersistentStorage(keyStore)) {
+ assertNotNull("Should be able to query size: " + keyStore.getType(),
+ keyStore.aliases());
+ } else if (hasDefaultContents(keyStore)) {
assertTrue(keyStore.aliases().hasMoreElements());
} else {
assertEquals(expected, new HashSet<String>(Collections.list(keyStore.aliases())));
@@ -1271,7 +1420,11 @@ public class KeyStoreTest extends TestCase {
assertFalse(keyStore.containsAlias(ALIAS_PRIVATE));
continue;
}
- assertTrue(keyStore.containsAlias(ALIAS_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertTrue(keyStore.containsAlias(ALIAS_PRIVATE));
+ } else if (isNullPasswordAllowed(keyStore)) {
+ assertTrue(keyStore.containsAlias(ALIAS_NO_PASSWORD_PRIVATE));
+ }
assertEquals(isSecretKeyEnabled(keyStore), keyStore.containsAlias(ALIAS_SECRET));
assertEquals(isCertificateEnabled(keyStore), keyStore.containsAlias(ALIAS_CERTIFICATE));
@@ -1295,21 +1448,29 @@ public class KeyStoreTest extends TestCase {
for (KeyStore keyStore : keyStores()) {
keyStore.load(null, null);
- if (hasDefaultContents(keyStore)) {
- assertTrue(keyStore.size() > 0);
+ if (isPersistentStorage(keyStore)) {
+ assertTrue("Should successfully query size: " + keyStore.getType(),
+ keyStore.size() >= 0);
+ } else if (hasDefaultContents(keyStore)) {
+ assertTrue("Should have non-empty store: " + keyStore.getType(),
+ keyStore.size() > 0);
} else {
- assertEquals(0, keyStore.size());
+ assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
}
}
for (KeyStore keyStore : keyStores()) {
populate(keyStore);
if (hasDefaultContents(keyStore)) {
- assertTrue(keyStore.size() > 0);
+ assertTrue("Should have non-empty store: " + keyStore.getType(),
+ keyStore.size() > 0);
continue;
}
- int expected = 1;
+ int expected = 0;
+ if (isKeyPasswordSupported(keyStore)) {
+ expected++;
+ }
if (isNullPasswordAllowed(keyStore)) {
expected++;
}
@@ -1355,7 +1516,12 @@ public class KeyStoreTest extends TestCase {
assertFalse(keyStore.isKeyEntry(ALIAS_PRIVATE));
continue;
}
- assertTrue(keyStore.isKeyEntry(ALIAS_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertTrue(keyStore.isKeyEntry(ALIAS_PRIVATE));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertTrue(keyStore.isKeyEntry(ALIAS_NO_PASSWORD_PRIVATE));
+ }
assertEquals(isSecretKeyEnabled(keyStore), keyStore.isKeyEntry(ALIAS_SECRET));
assertFalse(keyStore.isKeyEntry(ALIAS_CERTIFICATE));
@@ -1397,7 +1563,12 @@ public class KeyStoreTest extends TestCase {
assertFalse(keyStore.isCertificateEntry(""));
- assertFalse(keyStore.isCertificateEntry(ALIAS_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertFalse(keyStore.isCertificateEntry(ALIAS_PRIVATE));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ assertFalse(keyStore.isCertificateEntry(ALIAS_NO_PASSWORD_PRIVATE));
+ }
assertFalse(keyStore.isCertificateEntry(ALIAS_SECRET));
assertEquals(isCertificateEnabled(keyStore) && !isReadOnly(keyStore),
keyStore.isCertificateEntry(ALIAS_CERTIFICATE));
@@ -1429,7 +1600,9 @@ public class KeyStoreTest extends TestCase {
populate(keyStore);
Set<String> expected = new HashSet<String>();
- expected.add(ALIAS_PRIVATE);
+ if (isKeyPasswordSupported(keyStore)) {
+ expected.add(ALIAS_PRIVATE);
+ }
if (isNullPasswordAllowed(keyStore)) {
expected.add(ALIAS_NO_PASSWORD_PRIVATE);
}
@@ -1487,7 +1660,7 @@ public class KeyStoreTest extends TestCase {
for (KeyStore keyStore : keyStores()) {
keyStore.load(null, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
- if (isReadOnly(keyStore)) {
+ if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
try {
keyStore.store(out, null);
fail(keyStore.getType());
@@ -1517,11 +1690,11 @@ public class KeyStoreTest extends TestCase {
populate(keyStore);
ByteArrayOutputStream out = new ByteArrayOutputStream();
- if (isReadOnly(keyStore)) {
+ if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
try {
keyStore.store(out, null);
fail(keyStore.getType());
- } catch (UnsupportedOperationException e) {
+ } catch (UnsupportedOperationException expected) {
}
} else if (isNullPasswordAllowed(keyStore)) {
keyStore.store(out, null);
@@ -1542,7 +1715,7 @@ public class KeyStoreTest extends TestCase {
for (KeyStore keyStore : keyStores()) {
keyStore.load(null, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
- if (isReadOnly(keyStore)) {
+ if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
try {
keyStore.store(out, PASSWORD_STORE);
fail(keyStore.getType());
@@ -1557,7 +1730,7 @@ public class KeyStoreTest extends TestCase {
for (KeyStore keyStore : keyStores()) {
populate(keyStore);
ByteArrayOutputStream out = new ByteArrayOutputStream();
- if (isReadOnly(keyStore)) {
+ if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
try {
keyStore.store(out, PASSWORD_STORE);
fail(keyStore.getType());
@@ -1596,19 +1769,30 @@ public class KeyStoreTest extends TestCase {
public void test_KeyStore_load_InputStream() throws Exception {
for (KeyStore keyStore : keyStores()) {
keyStore.load(null, null);
- if (hasDefaultContents(keyStore)) {
- assertTrue(keyStore.size() > 0);
+ if (isPersistentStorage(keyStore)) {
+ assertTrue("Should be able to query size: " + keyStore.getType(),
+ keyStore.size() >= 0);
+ } else if (hasDefaultContents(keyStore)) {
+ assertTrue("Should have non-empty store: " + keyStore.getType(),
+ keyStore.size() > 0);
} else {
- assertEquals(0, keyStore.size());
+ assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
}
}
for (KeyStore keyStore : keyStores()) {
+ if (isLoadStoreUnsupported(keyStore)) {
+ continue;
+ }
keyStore.load(null, PASSWORD_STORE);
- if (hasDefaultContents(keyStore)) {
- assertTrue(keyStore.size() > 0);
+ if (isPersistentStorage(keyStore)) {
+ assertTrue("Should be able to query size: " + keyStore.getType(),
+ keyStore.size() >= 0);
+ } else if (hasDefaultContents(keyStore)) {
+ assertTrue("Should have non-empty store: " + keyStore.getType(),
+ keyStore.size() > 0);
} else {
- assertEquals(0, keyStore.size());
+ assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
}
}
@@ -1618,10 +1802,14 @@ public class KeyStoreTest extends TestCase {
public void test_KeyStore_load_LoadStoreParameter() throws Exception {
for (KeyStore keyStore : keyStores()) {
keyStore.load(null);
- if (hasDefaultContents(keyStore)) {
- assertTrue(keyStore.size() > 0);
+ if (isPersistentStorage(keyStore)) {
+ assertTrue("Should be able to query size: " + keyStore.getType(),
+ keyStore.size() >= 0);
+ } else if (hasDefaultContents(keyStore)) {
+ assertTrue("Should have non-empty store: " + keyStore.getType(),
+ keyStore.size() > 0);
} else {
- assertEquals(0, keyStore.size());
+ assertEquals("Should have empty store: " + keyStore.getType(), 0, keyStore.size());
}
}
@@ -1668,7 +1856,11 @@ public class KeyStoreTest extends TestCase {
if (isReadOnly(keyStore)) {
assertNull(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
} else {
- assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_KEY));
+ } else if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getEntry(ALIAS_SECRET, PARAM_KEY));
} else {
@@ -1704,9 +1896,9 @@ public class KeyStoreTest extends TestCase {
assertNull(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
} else if (isNullPasswordAllowed(keyStore)) {
assertPrivateKey(keyStore.getEntry(ALIAS_NO_PASSWORD_PRIVATE, null));
- } else if (isKeyPasswordIgnored(keyStore)) {
+ } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, null));
- } else {
+ } else if (isKeyPasswordIgnored(keyStore)) {
try {
keyStore.getEntry(ALIAS_PRIVATE, null);
fail(keyStore.getType());
@@ -1734,9 +1926,9 @@ public class KeyStoreTest extends TestCase {
// test with bad passwords
if (isReadOnly(keyStore)) {
assertNull(keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD));
- } else if (isKeyPasswordIgnored(keyStore)) {
+ } else if (isKeyPasswordSupported(keyStore) && isKeyPasswordIgnored(keyStore)) {
assertPrivateKey(keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD));
- } else {
+ } else if (isKeyPasswordSupported(keyStore)) {
try {
keyStore.getEntry(ALIAS_PRIVATE, PARAM_BAD);
fail(keyStore.getType());
@@ -1773,7 +1965,7 @@ public class KeyStoreTest extends TestCase {
try {
keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), new FakeProtectionParameter());
- fail("Should not accept unknown ProtectionParameter");
+ fail("Should not accept unknown ProtectionParameter: " + keyStore.getProvider());
} catch (KeyStoreException expected) {
}
}
@@ -1808,7 +2000,7 @@ public class KeyStoreTest extends TestCase {
}
for (KeyStore keyStore : keyStores()) {
- keyStore.load(null, null);
+ clearKeyStore(keyStore);
// test case sensitive
assertNull(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
@@ -1820,9 +2012,16 @@ public class KeyStoreTest extends TestCase {
}
continue;
}
- keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), PARAM_KEY);
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ keyStore.setEntry(ALIAS_PRIVATE, getPrivateKey(), PARAM_KEY);
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_PRIVATE));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ keyStore.setEntry(ALIAS_NO_PASSWORD_PRIVATE, getPrivateKey(), null);
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_NO_PASSWORD_PRIVATE));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
keyStore.setEntry(ALIAS_SECRET, new SecretKeyEntry(getSecretKey()), PARAM_KEY);
@@ -1849,9 +2048,17 @@ public class KeyStoreTest extends TestCase {
} catch (KeyStoreException expected) {
}
}
- keyStore.setEntry(ALIAS_UNICODE_PRIVATE, getPrivateKey(), PARAM_KEY);
- assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_PRIVATE, PASSWORD_KEY));
- assertCertificateChain(keyStore.getCertificateChain(ALIAS_UNICODE_PRIVATE));
+ if (isKeyPasswordSupported(keyStore)) {
+ keyStore.setEntry(ALIAS_UNICODE_PRIVATE, getPrivateKey(), PARAM_KEY);
+ assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_PRIVATE, PASSWORD_KEY));
+ assertCertificateChain(keyStore.getCertificateChain(ALIAS_UNICODE_PRIVATE));
+ }
+ if (isNullPasswordAllowed(keyStore)) {
+ keyStore.setEntry(ALIAS_UNICODE_NO_PASSWORD_PRIVATE, getPrivateKey(), null);
+ assertPrivateKey(keyStore.getKey(ALIAS_UNICODE_NO_PASSWORD_PRIVATE, null));
+ assertCertificateChain(keyStore
+ .getCertificateChain(ALIAS_UNICODE_NO_PASSWORD_PRIVATE));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertNull(keyStore.getKey(ALIAS_UNICODE_SECRET, PASSWORD_KEY));
keyStore.setEntry(ALIAS_UNICODE_SECRET, new SecretKeyEntry(getSecretKey()), PARAM_KEY);
@@ -1874,11 +2081,21 @@ public class KeyStoreTest extends TestCase {
assertNull(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
assertNull(keyStore.getKey(ALIAS_ALT_CASE_SECRET, PASSWORD_KEY));
} else if (isCaseSensitive(keyStore)) {
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
- keyStore.setEntry(ALIAS_ALT_CASE_PRIVATE, getPrivateKey2(), PARAM_KEY);
- assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
- assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ if (isKeyPasswordSupported(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ keyStore.setEntry(ALIAS_ALT_CASE_PRIVATE, getPrivateKey2(), PARAM_KEY);
+ assertPrivateKey(keyStore.getKey(ALIAS_PRIVATE, PASSWORD_KEY));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_PRIVATE, PASSWORD_KEY));
+ }
+
+ if (isNullPasswordAllowed(keyStore)) {
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertNull(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ keyStore.setEntry(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, getPrivateKey2(), null);
+ assertPrivateKey(keyStore.getKey(ALIAS_NO_PASSWORD_PRIVATE, null));
+ assertPrivateKey2(keyStore.getKey(ALIAS_ALT_CASE_NO_PASSWORD_PRIVATE, null));
+ }
if (isSecretKeyEnabled(keyStore)) {
assertSecretKey(keyStore.getKey(ALIAS_SECRET, PASSWORD_KEY));
@@ -2073,10 +2290,17 @@ public class KeyStoreTest extends TestCase {
}
// test case sensitive
- assertTrue(keyStore.entryInstanceOf(ALIAS_PRIVATE, PrivateKeyEntry.class));
+ assertEquals(isKeyPasswordSupported(keyStore),
+ keyStore.entryInstanceOf(ALIAS_PRIVATE, PrivateKeyEntry.class));
assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, SecretKeyEntry.class));
assertFalse(keyStore.entryInstanceOf(ALIAS_PRIVATE, TrustedCertificateEntry.class));
+ assertEquals(isNullPasswordAllowed(keyStore),
+ keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE, PrivateKeyEntry.class));
+ assertFalse(keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE, SecretKeyEntry.class));
+ assertFalse(keyStore.entryInstanceOf(ALIAS_NO_PASSWORD_PRIVATE,
+ TrustedCertificateEntry.class));
+
assertEquals(isSecretKeyEnabled(keyStore),
keyStore.entryInstanceOf(ALIAS_SECRET, SecretKeyEntry.class));
assertFalse(keyStore.entryInstanceOf(ALIAS_SECRET, PrivateKeyEntry.class));
@@ -2173,7 +2397,7 @@ public class KeyStoreTest extends TestCase {
OutputStream os = null;
try {
os = new FileOutputStream(file);
- if (isReadOnly(keyStore)) {
+ if (isLoadStoreUnsupported(keyStore) || isReadOnly(keyStore)) {
try {
keyStore.store(os, PASSWORD_STORE);
fail(keyStore.getType());
@@ -2204,6 +2428,9 @@ public class KeyStoreTest extends TestCase {
}
for (KeyStore keyStore : keyStores()) {
+ if (isLoadStoreUnsupported(keyStore)) {
+ continue;
+ }
Builder builder = Builder.newInstance(keyStore.getType(),
keyStore.getProvider(),
PARAM_STORE);
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 541dd66..b146b1a 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -46,6 +46,16 @@ public class LocaleTest extends junit.framework.TestCase {
assertEquals("Deutsch", Locale.GERMAN.getDisplayLanguage(Locale.GERMAN));
}
+ // http://b/7291355; Locale.getDisplayLanguage fails for tl in tl in ICU 4.9.
+ public void test_tl() throws Exception {
+ Locale tl = new Locale("tl");
+ Locale tl_PH = new Locale("tl", "PH");
+ assertEquals("Filipino", tl.getDisplayLanguage(Locale.ENGLISH));
+ assertEquals("Filipino", tl_PH.getDisplayLanguage(Locale.ENGLISH));
+ assertEquals("Filipino", tl.getDisplayLanguage(tl));
+ assertEquals("Filipino", tl_PH.getDisplayLanguage(tl_PH));
+ }
+
// http://b/3452611; Locale.getDisplayLanguage fails for the obsolete language codes.
public void test_getDisplayName_obsolete() throws Exception {
// he (new) -> iw (obsolete)
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index 764b63c..a98cdec 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -17,7 +17,6 @@
package libcore.javax.crypto;
import com.android.org.bouncycastle.asn1.x509.KeyUsage;
-
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
@@ -56,7 +55,6 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;
-
import junit.framework.TestCase;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
@@ -64,6 +62,35 @@ import libcore.util.EmptyArray;
public final class CipherTest extends TestCase {
+ private static final String[] RSA_PROVIDERS = ((StandardNames.IS_RI)
+ ? new String[] { "SunJCE" }
+ : new String[] { "BC" , "AndroidOpenSSL" });
+
+ private static final String[] AES_PROVIDERS = ((StandardNames.IS_RI)
+ ? new String[] { "SunJCE" }
+ : new String[] { "BC", "AndroidOpenSSL" });
+
+ private static final boolean IS_UNLIMITED;
+ static {
+ boolean is_unlimited;
+ if (StandardNames.IS_RI) {
+ try {
+ String algorithm = "PBEWITHMD5ANDTRIPLEDES";
+ Cipher.getInstance(algorithm).init(getEncryptMode(algorithm),
+ getEncryptKey(algorithm),
+ getAlgorithmParameterSpec(algorithm));
+ is_unlimited = true;
+ } catch (Exception e) {
+ is_unlimited = false;
+ System.out.println("WARNING: Some tests disabled due to lack of "
+ + "'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files'");
+ }
+ } else {
+ is_unlimited = true;
+ }
+ IS_UNLIMITED = is_unlimited;
+ }
+
private static boolean isUnsupported(String algorithm) {
if (algorithm.equals("RC2")) {
return true;
@@ -83,9 +110,28 @@ public final class CipherTest extends TestCase {
if (algorithm.equals("PBEWITHSHAANDTWOFISH-CBC")) {
return true;
}
+ if (!IS_UNLIMITED) {
+ if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
+ return true;
+ }
+ }
return false;
}
+ private synchronized static int getEncryptMode(String algorithm) throws Exception {
+ if (isOnlyWrappingAlgorithm(algorithm)) {
+ return Cipher.WRAP_MODE;
+ }
+ return Cipher.ENCRYPT_MODE;
+ }
+
+ private synchronized static int getDecryptMode(String algorithm) throws Exception {
+ if (isOnlyWrappingAlgorithm(algorithm)) {
+ return Cipher.UNWRAP_MODE;
+ }
+ return Cipher.DECRYPT_MODE;
+ }
+
private static String getBaseAlgorithm(String algorithm) {
if (algorithm.equals("AESWRAP")) {
return "AES";
@@ -164,6 +210,11 @@ public final class CipherTest extends TestCase {
return algorithm.endsWith("WRAP");
}
+ private static boolean isWrappingSupported(String algorithm, String provider) {
+ // All Cipher's should support wrapping but BouncyCastle PBE ciphers do not.
+ return !(provider.equals("BC") && isPBE(algorithm));
+ }
+
private static boolean isPBE(String algorithm) {
return algorithm.startsWith("PBE");
}
@@ -211,135 +262,213 @@ public final class CipherTest extends TestCase {
private static Map<String, Integer> EXPECTED_BLOCK_SIZE = new HashMap<String, Integer>();
static {
- EXPECTED_BLOCK_SIZE.put("AES", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND128BITAES-CBC-BC", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND192BITAES-CBC-BC", 16);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND256BITAES-CBC-BC", 16);
+ setExpectedBlockSize("AES", 16);
+ setExpectedBlockSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
+ setExpectedBlockSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
+ setExpectedBlockSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
+ setExpectedBlockSize("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
+ setExpectedBlockSize("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
+ setExpectedBlockSize("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
+ setExpectedBlockSize("PBEWITHSHAAND128BITAES-CBC-BC", 16);
+ setExpectedBlockSize("PBEWITHSHAAND192BITAES-CBC-BC", 16);
+ setExpectedBlockSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
if (StandardNames.IS_RI) {
- EXPECTED_BLOCK_SIZE.put("AESWRAP", 16);
+ setExpectedBlockSize("AESWRAP", 16);
} else {
- EXPECTED_BLOCK_SIZE.put("AESWRAP", 0);
+ setExpectedBlockSize("AESWRAP", 0);
}
- EXPECTED_BLOCK_SIZE.put("ARC4", 0);
- EXPECTED_BLOCK_SIZE.put("ARCFOUR", 0);
+ setExpectedBlockSize("ARC4", 0);
+ setExpectedBlockSize("ARCFOUR", 0);
+ setExpectedBlockSize("PBEWITHSHAAND40BITRC4", 0);
+ setExpectedBlockSize("PBEWITHSHAAND128BITRC4", 0);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND40BITRC4", 0);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND128BITRC4", 0);
+ setExpectedBlockSize("BLOWFISH", 8);
- EXPECTED_BLOCK_SIZE.put("BLOWFISH", 8);
+ setExpectedBlockSize("DES", 8);
+ setExpectedBlockSize("PBEWITHMD5ANDDES", 8);
+ setExpectedBlockSize("PBEWITHSHA1ANDDES", 8);
- EXPECTED_BLOCK_SIZE.put("DES", 8);
- EXPECTED_BLOCK_SIZE.put("PBEWITHMD5ANDDES", 8);
- EXPECTED_BLOCK_SIZE.put("PBEWITHMD5ANDTRIPLEDES", 8);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHA1ANDDES", 8);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHA1ANDDESEDE", 8);
+ setExpectedBlockSize("DESEDE", 8);
+ setExpectedBlockSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
+ setExpectedBlockSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
+ setExpectedBlockSize("PBEWITHMD5ANDTRIPLEDES", 8);
+ setExpectedBlockSize("PBEWITHSHA1ANDDESEDE", 8);
- EXPECTED_BLOCK_SIZE.put("DESEDE", 8);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
- EXPECTED_BLOCK_SIZE.put("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
if (StandardNames.IS_RI) {
- EXPECTED_BLOCK_SIZE.put("DESEDEWRAP", 8);
+ setExpectedBlockSize("DESEDEWRAP", 8);
} else {
- EXPECTED_BLOCK_SIZE.put("DESEDEWRAP", 0);
+ setExpectedBlockSize("DESEDEWRAP", 0);
}
- EXPECTED_BLOCK_SIZE.put("RSA", 0);
- }
+ if (StandardNames.IS_RI) {
+ setExpectedBlockSize("RSA", 0);
+ setExpectedBlockSize("RSA/ECB/NoPadding", 0);
+ setExpectedBlockSize("RSA/ECB/PKCS1Padding", 0);
+ } else {
+ setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, 256);
+ setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
+ setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 245);
- private static int getExpectedBlockSize(String algorithm, Key key) {
- final int firstSlash = algorithm.indexOf('/');
- if (firstSlash != -1) {
- algorithm = algorithm.substring(0, firstSlash);
- }
+ // BC strips the leading 0 for us even when NoPadding is specified
+ setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, "BC", 255);
+ setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, "BC", 255);
- if (!StandardNames.IS_RI && "RSA".equals(getBaseAlgorithm(algorithm))) {
- // Must be one less than the modulus size to make sure it fits.
- return getRSAModulusSize(key) - 1;
+ setExpectedBlockSize("RSA", Cipher.DECRYPT_MODE, 256);
+ setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
+ setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 256);
}
+ }
- Integer expected = EXPECTED_BLOCK_SIZE.get(algorithm);
- assertNotNull(algorithm, expected);
- return expected;
+ private static String modeKey(String algorithm, int mode) {
+ return algorithm + ":" + mode;
}
- private static int getRSAModulusSize(Key key) {
- if (key instanceof RSAPrivateKey) {
- RSAPrivateKey rsaKey = (RSAPrivateKey) key;
- return rsaKey.getModulus().bitLength() / 8;
- } else if (key instanceof RSAPublicKey) {
- RSAPublicKey rsaKey = (RSAPublicKey) key;
- return rsaKey.getModulus().bitLength() / 8;
- } else {
- throw new RuntimeException("Unknown RSA key type: " + key.getClass().getName());
+ private static String modeProviderKey(String algorithm, int mode, String provider) {
+ return algorithm + ":" + mode + ":" + provider;
+ }
+
+ private static void setExpectedSize(Map<String, Integer> map,
+ String algorithm, int value) {
+ algorithm = algorithm.toUpperCase(Locale.US);
+ map.put(algorithm, value);
+ }
+
+ private static void setExpectedSize(Map<String, Integer> map,
+ String algorithm, int mode, int value) {
+ setExpectedSize(map, modeKey(algorithm, mode), value);
+ }
+
+ private static void setExpectedSize(Map<String, Integer> map,
+ String algorithm, int mode, String provider, int value) {
+ setExpectedSize(map, modeProviderKey(algorithm, mode, provider), value);
+ }
+
+ private static int getExpectedSize(Map<String, Integer> map, String algorithm, int mode, String provider) {
+ Integer expected = map.get(modeProviderKey(algorithm, mode, provider));
+ if (expected != null) {
+ return expected;
+ }
+ expected = map.get(modeKey(algorithm, mode));
+ if (expected != null) {
+ return expected;
}
+ expected = map.get(algorithm);
+ assertNotNull("Algorithm " + algorithm + " not found in " + map, expected);
+ return expected;
+ }
+
+ private static void setExpectedBlockSize(String algorithm, int value) {
+ setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, value);
+ }
+
+ private static void setExpectedBlockSize(String algorithm, int mode, int value) {
+ setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, value);
+ }
+
+ private static void setExpectedBlockSize(String algorithm, int mode, String provider, int value) {
+ setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, provider, value);
+ }
+
+ private static int getExpectedBlockSize(String algorithm, int mode, String provider) {
+ return getExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, provider);
}
private static Map<String, Integer> EXPECTED_OUTPUT_SIZE = new HashMap<String, Integer>();
static {
- EXPECTED_OUTPUT_SIZE.put("AES", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND128BITAES-CBC-BC", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND192BITAES-CBC-BC", 16);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND256BITAES-CBC-BC", 16);
+ setExpectedOutputSize("AES", Cipher.ENCRYPT_MODE, 16);
+ setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
+ setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
+ setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
+ setExpectedOutputSize("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
+ setExpectedOutputSize("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
+ setExpectedOutputSize("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
+ setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", 16);
+ setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", 16);
+ setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
+
+ setExpectedOutputSize("AES", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHA256AND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHA256AND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHA256AND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
if (StandardNames.IS_RI) {
- EXPECTED_OUTPUT_SIZE.put("AESWRAP", 8);
+ setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
+ setExpectedOutputSize("AESWRAP", Cipher.UNWRAP_MODE, 0);
} else {
- EXPECTED_OUTPUT_SIZE.put("AESWRAP", -1);
+ setExpectedOutputSize("AESWRAP", -1);
}
- EXPECTED_OUTPUT_SIZE.put("ARC4", 0);
- EXPECTED_OUTPUT_SIZE.put("ARCFOUR", 0);
+ setExpectedOutputSize("ARC4", 0);
+ setExpectedOutputSize("ARCFOUR", 0);
+ setExpectedOutputSize("PBEWITHSHAAND40BITRC4", 0);
+ setExpectedOutputSize("PBEWITHSHAAND128BITRC4", 0);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND40BITRC4", 0);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND128BITRC4", 0);
+ setExpectedOutputSize("BLOWFISH", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("BLOWFISH", Cipher.DECRYPT_MODE, 0);
- EXPECTED_OUTPUT_SIZE.put("BLOWFISH", 8);
+ setExpectedOutputSize("DES", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.ENCRYPT_MODE, 8);
- EXPECTED_OUTPUT_SIZE.put("DES", 8);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHMD5ANDDES", 8);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHMD5ANDTRIPLEDES", 8);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHA1ANDDES", 8);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHA1ANDDESEDE", 8);
+ setExpectedOutputSize("DES", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.DECRYPT_MODE, 0);
- EXPECTED_OUTPUT_SIZE.put("DESEDE", 8);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
- EXPECTED_OUTPUT_SIZE.put("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
+ setExpectedOutputSize("DESEDE", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.ENCRYPT_MODE, 8);
+
+ setExpectedOutputSize("DESEDE", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.DECRYPT_MODE, 0);
if (StandardNames.IS_RI) {
- EXPECTED_OUTPUT_SIZE.put("DESEDEWRAP", 16);
+ setExpectedOutputSize("DESEDEWRAP", Cipher.WRAP_MODE, 16);
+ setExpectedOutputSize("DESEDEWRAP", Cipher.UNWRAP_MODE, 0);
} else {
- EXPECTED_OUTPUT_SIZE.put("DESEDEWRAP", -1);
+ setExpectedOutputSize("DESEDEWRAP", -1);
}
+
+ setExpectedOutputSize("RSA", Cipher.ENCRYPT_MODE, 256);
+ setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
+ setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 256);
+
+ setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, 256);
+ setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
+ setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 245);
+
+ // BC strips the leading 0 for us even when NoPadding is specified
+ setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, "BC", 255);
+ setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, "BC", 255);
}
- private static int getExpectedOutputSize(String algorithm, Key key) {
- final int firstSlash = algorithm.indexOf('/');
- if (firstSlash != -1) {
- algorithm = algorithm.substring(0, firstSlash);
- }
- // Output size for RSA depends on the key size being used.
- if ("RSA".equals(getBaseAlgorithm(algorithm))) {
- return getRSAModulusSize(key);
- }
+ private static void setExpectedOutputSize(String algorithm, int value) {
+ setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, value);
+ }
- Integer expected = EXPECTED_OUTPUT_SIZE.get(algorithm);
- assertNotNull(algorithm, expected);
- return expected;
+ private static void setExpectedOutputSize(String algorithm, int mode, int value) {
+ setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, value);
+ }
+
+ private static void setExpectedOutputSize(String algorithm, int mode, String provider, int value) {
+ setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, provider, value);
+ }
+
+ private static int getExpectedOutputSize(String algorithm, int mode, String provider) {
+ return getExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, provider);
}
private static byte[] ORIGINAL_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c };
@@ -437,6 +566,15 @@ public final class CipherTest extends TestCase {
return ORIGINAL_PLAIN_TEXT;
}
+ private static AlgorithmParameterSpec getAlgorithmParameterSpec(String algorithm) {
+ if (!isPBE(algorithm)) {
+ return null;
+ }
+ final byte[] salt = new byte[8];
+ new SecureRandom().nextBytes(salt);
+ return new PBEParameterSpec(salt, 1024);
+ }
+
public void test_getInstance() throws Exception {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
@@ -475,7 +613,8 @@ public final class CipherTest extends TestCase {
try {
test_Cipher_Algorithm(provider, algorithm);
} catch (Throwable e) {
- out.append("Error encountered checking " + algorithm + "\n");
+ out.append("Error encountered checking " + algorithm
+ + " with provider " + provider.getName() + "\n");
e.printStackTrace(out);
}
@@ -489,7 +628,8 @@ public final class CipherTest extends TestCase {
try {
test_Cipher_Algorithm(provider, algorithmName);
} catch (Throwable e) {
- out.append("Error encountered checking " + algorithmName + "\n");
+ out.append("Error encountered checking " + algorithmName
+ + " with provider " + provider.getName() + "\n");
e.printStackTrace(out);
}
}
@@ -533,6 +673,8 @@ public final class CipherTest extends TestCase {
if (isUnsupported(algorithm)) {
return;
}
+ String providerName = c.getProvider().getName();
+ String cipherID = algorithm + ":" + providerName;
try {
c.getOutputSize(0);
@@ -541,35 +683,30 @@ public final class CipherTest extends TestCase {
// TODO: test keys from different factories (e.g. OpenSSLRSAPrivateKey vs JCERSAPrivateKey)
Key encryptKey = getEncryptKey(algorithm);
- final AlgorithmParameterSpec spec;
- if (isPBE(algorithm)) {
- final byte[] salt = new byte[8];
- new SecureRandom().nextBytes(salt);
- spec = new PBEParameterSpec(salt, 1024);
- } else {
- spec = null;
- }
- if (!isOnlyWrappingAlgorithm(algorithm)) {
- c.init(Cipher.ENCRYPT_MODE, encryptKey, spec);
- } else {
- c.init(Cipher.WRAP_MODE, encryptKey, spec);
- }
-
- assertEquals("getBlockSize()", getExpectedBlockSize(algorithm, encryptKey),
- c.getBlockSize());
-
- assertEquals("getOutputSize(0)", getExpectedOutputSize(algorithm, encryptKey),
- c.getOutputSize(0));
+ final AlgorithmParameterSpec spec = getAlgorithmParameterSpec(algorithm);
+
+ int encryptMode = getEncryptMode(algorithm);
+ c.init(encryptMode, encryptKey, spec);
+ assertEquals(cipherID + " getBlockSize()",
+ getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize());
+ assertEquals(cipherID + " getOutputSize(0)",
+ getExpectedOutputSize(algorithm, encryptMode, providerName), c.getOutputSize(0));
+ int decryptMode = getDecryptMode(algorithm);
+ c.init(decryptMode, encryptKey, spec);
+ assertEquals(cipherID + " getBlockSize()",
+ getExpectedBlockSize(algorithm, decryptMode, providerName), c.getBlockSize());
+ assertEquals(cipherID + " getOutputSize(0)",
+ getExpectedOutputSize(algorithm, decryptMode, providerName), c.getOutputSize(0));
// TODO: test Cipher.getIV()
// TODO: test Cipher.getParameters()
- assertNull(c.getExemptionMechanism());
+ assertNull(cipherID, c.getExemptionMechanism());
- // Test wrapping a key. Every cipher should be able to wrap.
- {
+ // Test wrapping a key. Most every cipher should be able to wrap.
+ if (isWrappingSupported(algorithm, providerName)) {
// Generate a small SecretKey for AES.
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
@@ -583,7 +720,8 @@ public final class CipherTest extends TestCase {
c.init(Cipher.UNWRAP_MODE, getDecryptKey(algorithm), spec);
Key decryptedKey = c.unwrap(cipherText, sk.getAlgorithm(), Cipher.SECRET_KEY);
- assertEquals("sk.getAlgorithm()=" + sk.getAlgorithm()
+ assertEquals(cipherID
+ + " sk.getAlgorithm()=" + sk.getAlgorithm()
+ " decryptedKey.getAlgorithm()=" + decryptedKey.getAlgorithm()
+ " encryptKey.getEncoded()=" + Arrays.toString(sk.getEncoded())
+ " decryptedKey.getEncoded()=" + Arrays.toString(decryptedKey.getEncoded()),
@@ -595,31 +733,37 @@ public final class CipherTest extends TestCase {
byte[] cipherText = c.doFinal(ORIGINAL_PLAIN_TEXT);
c.init(Cipher.DECRYPT_MODE, getDecryptKey(algorithm), spec);
byte[] decryptedPlainText = c.doFinal(cipherText);
- assertEquals(Arrays.toString(getExpectedPlainText(algorithm)),
+ assertEquals(cipherID, Arrays.toString(getExpectedPlainText(algorithm)),
Arrays.toString(decryptedPlainText));
}
}
public void testInputPKCS1Padding() throws Exception {
- testInputPKCS1Padding(PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
+ for (String provider : RSA_PROVIDERS) {
+ testInputPKCS1Padding(provider);
+ }
+ }
+
+ private void testInputPKCS1Padding(String provider) throws Exception {
+ testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
try {
- testInputPKCS1Padding(PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
+ testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
fail();
} catch (BadPaddingException expected) {
}
try {
- testInputPKCS1Padding(PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
+ testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
fail();
} catch (BadPaddingException expected) {
}
- testInputPKCS1Padding(PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
+ testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
}
- private void testInputPKCS1Padding(byte[] prePaddedPlainText, Key encryptKey, Key decryptKey) throws Exception {
- Cipher encryptCipher = Cipher.getInstance("RSA/ECB/NoPadding");
+ private void testInputPKCS1Padding(String provider, byte[] prePaddedPlainText, Key encryptKey, Key decryptKey) throws Exception {
+ Cipher encryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
byte[] cipherText = encryptCipher.doFinal(prePaddedPlainText);
- Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
byte[] plainText = decryptCipher.doFinal(cipherText);
assertEquals(Arrays.toString(ORIGINAL_PLAIN_TEXT),
@@ -627,37 +771,51 @@ public final class CipherTest extends TestCase {
}
public void testOutputPKCS1Padding() throws Exception {
- testOutputPKCS1Padding((byte) 1, getEncryptKey("RSA"), getDecryptKey("RSA"));
- testOutputPKCS1Padding((byte) 2, getDecryptKey("RSA"), getEncryptKey("RSA"));
+ for (String provider : RSA_PROVIDERS) {
+ testOutputPKCS1Padding(provider);
+ }
+ }
+
+ private void testOutputPKCS1Padding(String provider) throws Exception {
+ testOutputPKCS1Padding(provider, (byte) 1, getEncryptKey("RSA"), getDecryptKey("RSA"));
+ testOutputPKCS1Padding(provider, (byte) 2, getDecryptKey("RSA"), getEncryptKey("RSA"));
}
- private void testOutputPKCS1Padding(byte expectedBlockType, Key encryptKey, Key decryptKey) throws Exception {
- Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ private void testOutputPKCS1Padding(String provider, byte expectedBlockType, Key encryptKey, Key decryptKey) throws Exception {
+ Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
byte[] cipherText = encryptCipher.doFinal(ORIGINAL_PLAIN_TEXT);
- Cipher decryptCipher = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher decryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
byte[] plainText = decryptCipher.doFinal(cipherText);
- assertPadding(encryptKey, expectedBlockType, ORIGINAL_PLAIN_TEXT, plainText);
+ assertPadding(provider, expectedBlockType, ORIGINAL_PLAIN_TEXT, plainText);
}
- private void assertPadding(Key key, byte expectedBlockType, byte[] expectedData,
- byte[] actualDataWithPadding) {
- assertNotNull(actualDataWithPadding);
- assertEquals(getExpectedOutputSize("RSA", key), actualDataWithPadding.length);
- assertEquals(0, actualDataWithPadding[0]);
- byte actualBlockType = actualDataWithPadding[1];
- assertEquals(expectedBlockType, actualBlockType);
+ private void assertPadding(String provider, byte expectedBlockType, byte[] expectedData, byte[] actualDataWithPadding) {
+ assertNotNull(provider, actualDataWithPadding);
+ int expectedOutputSize = getExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, provider);
+ assertEquals(provider, expectedOutputSize, actualDataWithPadding.length);
+ int expectedBlockTypeOffset;
+ if (provider.equals("BC")) {
+ // BC strips the leading 0 for us on decrypt even when NoPadding is specified...
+ expectedBlockTypeOffset = 0;
+ } else {
+ expectedBlockTypeOffset = 1;
+ assertEquals(provider, 0, actualDataWithPadding[0]);
+ }
+ byte actualBlockType = actualDataWithPadding[expectedBlockTypeOffset];
+ assertEquals(provider, expectedBlockType, actualBlockType);
int actualDataOffset = actualDataWithPadding.length - expectedData.length;
if (actualBlockType == 1) {
- for (int i = 2; i < actualDataOffset - 1; i++) {
- assertEquals((byte) 0xFF, actualDataWithPadding[i]);
+ int expectedDataOffset = expectedBlockTypeOffset + 1;
+ for (int i = expectedDataOffset; i < actualDataOffset - 1; i++) {
+ assertEquals(provider, (byte) 0xFF, actualDataWithPadding[i]);
}
}
- assertEquals(0x00, actualDataWithPadding[actualDataOffset-1]);
+ assertEquals(provider, 0x00, actualDataWithPadding[actualDataOffset-1]);
byte[] actualData = new byte[expectedData.length];
System.arraycopy(actualDataWithPadding, actualDataOffset, actualData, 0, actualData.length);
- assertEquals(Arrays.toString(expectedData), Arrays.toString(actualData));
+ assertEquals(provider, Arrays.toString(expectedData), Arrays.toString(actualData));
}
public void testCipherInitWithCertificate () throws Exception {
@@ -1095,13 +1253,19 @@ public final class CipherTest extends TestCase {
};
public void testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually decrypting with private keys, but there is no
@@ -1120,13 +1284,19 @@ public final class CipherTest extends TestCase {
}
public void testRSA_ECB_NoPadding_Private_UpdateThenEmptyDoFinal_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_UpdateThenEmptyDoFinal_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_UpdateThenEmptyDoFinal_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually decrypting with private keys, but there is no
@@ -1148,13 +1318,20 @@ public final class CipherTest extends TestCase {
public void testRSA_ECB_NoPadding_Private_SingleByteUpdateThenEmptyDoFinal_Success()
throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_SingleByteUpdateThenEmptyDoFinal_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_SingleByteUpdateThenEmptyDoFinal_Success(String provider)
+ throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually decrypting with private keys, but there is no
@@ -1180,12 +1357,18 @@ public final class CipherTest extends TestCase {
}
public void testRSA_ECB_NoPadding_Private_OnlyDoFinalWithOffset_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_OnlyDoFinalWithOffset_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_OnlyDoFinalWithOffset_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually decrypting with private keys, but there is no
@@ -1211,12 +1394,18 @@ public final class CipherTest extends TestCase {
}
public void testRSA_ECB_NoPadding_Public_OnlyDoFinal_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Public_OnlyDoFinal_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Public_OnlyDoFinal_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
final PublicKey privKey = kf.generatePublic(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1225,22 +1414,26 @@ public final class CipherTest extends TestCase {
*/
c.init(Cipher.ENCRYPT_MODE, privKey);
byte[] encrypted = c.doFinal(RSA_Vector1_Encrypt_Private);
- assertTrue("Encrypted should match expected",
- Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
c.init(Cipher.DECRYPT_MODE, privKey);
encrypted = c.doFinal(RSA_Vector1_Encrypt_Private);
- assertTrue("Encrypted should match expected",
- Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
}
public void testRSA_ECB_NoPadding_Public_OnlyDoFinalWithOffset_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Public_OnlyDoFinalWithOffset_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Public_OnlyDoFinalWithOffset_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
final PublicKey pubKey = kf.generatePublic(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1252,22 +1445,33 @@ public final class CipherTest extends TestCase {
final int encryptLen = c.doFinal(RSA_Vector1_Encrypt_Private, 0,
RSA_Vector1_Encrypt_Private.length, encrypted, 0);
assertEquals("Encrypted size should match expected", RSA_2048_Vector1.length, encryptLen);
- assertTrue("Encrypted should match expected", Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
c.init(Cipher.DECRYPT_MODE, pubKey);
- final int decryptLen = c.doFinal(RSA_Vector1_Encrypt_Private, 0,
+ int decryptLen = c.doFinal(RSA_Vector1_Encrypt_Private, 0,
RSA_Vector1_Encrypt_Private.length, encrypted, 0);
+ if (provider.equals("BC")) {
+ // BC strips the leading 0 for us on decrypt even when NoPadding is specified...
+ decryptLen++;
+ encrypted = Arrays.copyOf(encrypted, encrypted.length - 1);
+ }
assertEquals("Encrypted size should match expected", RSA_2048_Vector1.length, decryptLen);
- assertTrue("Encrypted should match expected", Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
}
public void testRSA_ECB_NoPadding_Public_UpdateThenEmptyDoFinal_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Public_UpdateThenEmptyDoFinal_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Public_UpdateThenEmptyDoFinal_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
final PublicKey privKey = kf.generatePublic(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1277,22 +1481,29 @@ public final class CipherTest extends TestCase {
c.init(Cipher.ENCRYPT_MODE, privKey);
c.update(RSA_Vector1_Encrypt_Private);
byte[] encrypted = c.doFinal();
- assertTrue("Encrypted should match expected", Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
c.init(Cipher.DECRYPT_MODE, privKey);
c.update(RSA_Vector1_Encrypt_Private);
encrypted = c.doFinal();
- assertTrue("Encrypted should match expected", Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
}
public void testRSA_ECB_NoPadding_Public_SingleByteUpdateThenEmptyDoFinal_Success()
throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Public_SingleByteUpdateThenEmptyDoFinal_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Public_SingleByteUpdateThenEmptyDoFinal_Success(String provider)
+ throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
final PublicKey privKey = kf.generatePublic(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1305,23 +1516,29 @@ public final class CipherTest extends TestCase {
c.update(RSA_Vector1_Encrypt_Private, i, 1);
}
byte[] encrypted = c.doFinal(RSA_Vector1_Encrypt_Private, i, RSA_2048_Vector1.length - i);
- assertTrue("Encrypted should match expected", Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
c.init(Cipher.DECRYPT_MODE, privKey);
for (i = 0; i < RSA_Vector1_Encrypt_Private.length / 2; i++) {
c.update(RSA_Vector1_Encrypt_Private, i, 1);
}
encrypted = c.doFinal(RSA_Vector1_Encrypt_Private, i, RSA_2048_Vector1.length - i);
- assertTrue("Encrypted should match expected", Arrays.equals(RSA_2048_Vector1, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
}
public void testRSA_ECB_NoPadding_Public_TooSmall_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Public_TooSmall_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Public_TooSmall_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
final PublicKey privKey = kf.generatePublic(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1340,13 +1557,19 @@ public final class CipherTest extends TestCase {
}
public void testRSA_ECB_NoPadding_Private_TooSmall_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_TooSmall_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_TooSmall_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1355,24 +1578,48 @@ public final class CipherTest extends TestCase {
*/
c.init(Cipher.ENCRYPT_MODE, privKey);
byte[] encrypted = c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
- assertTrue("Encrypted should match expected",
- Arrays.equals(TooShort_Vector_Zero_Padded, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE,
+ TooShort_Vector_Zero_Padded, encrypted);
c.init(Cipher.DECRYPT_MODE, privKey);
encrypted = c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
- assertTrue("Encrypted should match expected",
- Arrays.equals(TooShort_Vector_Zero_Padded, encrypted));
+ assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE,
+ TooShort_Vector_Zero_Padded, encrypted);
+ }
+
+ private static void assertEncryptedEqualsNoPadding(String provider, int mode,
+ byte[] expected, byte[] actual) {
+ if (provider.equals("BC") && mode == Cipher.DECRYPT_MODE) {
+ // BouncyCastle does us the favor of stripping leading zeroes in DECRYPT_MODE
+ int nonZeroOffset = 0;
+ for (byte b : expected) {
+ if (b != 0) {
+ break;
+ }
+ nonZeroOffset++;
+ }
+ expected = Arrays.copyOfRange(expected, nonZeroOffset, expected.length);
+ }
+ assertEquals("Encrypted should match expected",
+ Arrays.toString(expected), Arrays.toString(actual));
}
public void testRSA_ECB_NoPadding_Private_CombinedUpdateAndDoFinal_TooBig_Failure()
throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_CombinedUpdateAndDoFinal_TooBig_Failure(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_CombinedUpdateAndDoFinal_TooBig_Failure(String provider)
+ throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1386,18 +1633,28 @@ public final class CipherTest extends TestCase {
c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
fail("Should have error when block size is too big.");
} catch (IllegalBlockSizeException success) {
+ assertFalse(provider, "BC".equals(provider));
+ } catch (ArrayIndexOutOfBoundsException success) {
+ assertEquals("BC", provider);
}
}
public void testRSA_ECB_NoPadding_Private_UpdateInAndOutPlusDoFinal_TooBig_Failure()
throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_UpdateInAndOutPlusDoFinal_TooBig_Failure(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_UpdateInAndOutPlusDoFinal_TooBig_Failure(String provider)
+ throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1414,17 +1671,26 @@ public final class CipherTest extends TestCase {
c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
fail("Should have error when block size is too big.");
} catch (IllegalBlockSizeException success) {
+ assertFalse(provider, "BC".equals(provider));
+ } catch (ArrayIndexOutOfBoundsException success) {
+ assertEquals("BC", provider);
}
}
public void testRSA_ECB_NoPadding_Private_OnlyDoFinal_TooBig_Failure() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_Private_OnlyDoFinal_TooBig_Failure(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_Private_OnlyDoFinal_TooBig_Failure(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
RSA_2048_privateExponent);
final PrivateKey privKey = kf.generatePrivate(keySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
/*
* You're actually encrypting with public keys, but there is no
@@ -1443,26 +1709,46 @@ public final class CipherTest extends TestCase {
c.doFinal(tooBig_Vector);
fail("Should have error when block size is too big.");
} catch (IllegalBlockSizeException success) {
+ assertFalse(provider, "BC".equals(provider));
+ } catch (ArrayIndexOutOfBoundsException success) {
+ assertEquals("BC", provider);
}
}
public void testRSA_ECB_NoPadding_GetBlockSize_Success() throws Exception {
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
- assertEquals("RSA is not a block cipher and should return block size of 0",
- 0, c.getBlockSize());
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_GetBlockSize_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_GetBlockSize_Success(String provider) throws Exception {
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+ if (StandardNames.IS_RI) {
+ assertEquals(0, c.getBlockSize());
+ } else {
+ try {
+ c.getBlockSize();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
RSA_2048_publicExponent);
final PublicKey pubKey = kf.generatePublic(pubKeySpec);
c.init(Cipher.ENCRYPT_MODE, pubKey);
-
- assertEquals("RSA is not a block cipher and should return block size of 0",
- 0, c.getBlockSize());
+ assertEquals(getExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, provider), c.getBlockSize());
}
public void testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure() throws Exception {
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure(String provider) throws Exception {
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
try {
c.getOutputSize(RSA_2048_Vector1.length);
fail("Should throw IllegalStateException if getOutputSize is called before init");
@@ -1471,32 +1757,39 @@ public final class CipherTest extends TestCase {
}
public void testRSA_ECB_NoPadding_GetOutputSize_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_GetOutputSize_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_GetOutputSize_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
RSA_2048_publicExponent);
final PublicKey pubKey = kf.generatePublic(pubKeySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
c.init(Cipher.ENCRYPT_MODE, pubKey);
final int modulusInBytes = RSA_2048_modulus.bitLength() / 8;
- assertEquals("Output size should be equal to modulus size",
- modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length));
-
- assertEquals("Output size should be equal to modulus size",
- modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length * 2));
-
- assertEquals("Output size should be equal to modulus size",
- modulusInBytes, c.getOutputSize(0));
+ assertEquals(modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length));
+ assertEquals(modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length * 2));
+ assertEquals(modulusInBytes, c.getOutputSize(0));
}
public void testRSA_ECB_NoPadding_GetIV_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_GetIV_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_GetIV_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
RSA_2048_publicExponent);
final PublicKey pubKey = kf.generatePublic(pubKeySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
assertNull("ECB mode has no IV and should be null", c.getIV());
c.init(Cipher.ENCRYPT_MODE, pubKey);
@@ -1505,12 +1798,18 @@ public final class CipherTest extends TestCase {
}
public void testRSA_ECB_NoPadding_GetParameters_NoneProvided_Success() throws Exception {
+ for (String provider : RSA_PROVIDERS) {
+ testRSA_ECB_NoPadding_GetParameters_NoneProvided_Success(provider);
+ }
+ }
+
+ private void testRSA_ECB_NoPadding_GetParameters_NoneProvided_Success(String provider) throws Exception {
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
RSA_2048_publicExponent);
final PublicKey pubKey = kf.generatePublic(pubKeySpec);
- Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
assertNull("Parameters should be null", c.getParameters());
}
@@ -1686,22 +1985,32 @@ public final class CipherTest extends TestCase {
AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext,
AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted));
- CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC", AES_256_KEY,
- AES_256_CBC_PKCS5Padding_TestVector_1_IV,
- AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
- AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
- AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
+ if (IS_UNLIMITED) {
+ CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC", AES_256_KEY,
+ AES_256_CBC_PKCS5Padding_TestVector_1_IV,
+ AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
+ AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
+ AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
+ }
}
public void testCipher_Success() throws Exception {
+ for (String provider : AES_PROVIDERS) {
+ testCipher_Success(provider);
+ }
+ }
+
+ private void testCipher_Success(String provider) throws Exception {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
for (CipherTestParam p : CIPHER_TEST_PARAMS) {
try {
- checkCipher(p);
+ checkCipher(p, provider);
} catch (Exception e) {
out.append("Error encountered checking " + p.mode + ", keySize="
- + (p.key.length * 8) + "\n");
+ + (p.key.length * 8)
+ + " with provider " + provider + "\n");
+
e.printStackTrace(out);
}
}
@@ -1711,9 +2020,9 @@ public final class CipherTest extends TestCase {
}
}
- private void checkCipher(CipherTestParam p) throws Exception {
+ private void checkCipher(CipherTestParam p, String provider) throws Exception {
SecretKey key = new SecretKeySpec(p.key, "AES");
- Cipher c = Cipher.getInstance(p.mode + "/PKCS5Padding");
+ Cipher c = Cipher.getInstance(p.mode + "/PKCS5Padding", provider);
AlgorithmParameterSpec spec = null;
if (p.iv != null) {
spec = new IvParameterSpec(p.iv);
@@ -1733,10 +2042,33 @@ public final class CipherTest extends TestCase {
// empty decrypt
{
- assertNull(c.doFinal());
+ if (StandardNames.IS_RI) {
+ assertEquals(Arrays.toString(EmptyArray.BYTE),
+ Arrays.toString(c.doFinal()));
+
+ c.update(EmptyArray.BYTE);
+ assertEquals(Arrays.toString(EmptyArray.BYTE),
+ Arrays.toString(c.doFinal()));
+ } else if (provider.equals("BC")) {
+ try {
+ c.doFinal();
+ fail();
+ } catch (IllegalBlockSizeException expected) {
+ }
+ try {
+ c.update(EmptyArray.BYTE);
+ c.doFinal();
+ fail();
+ } catch (IllegalBlockSizeException expected) {
+ }
+ } else if (provider.equals("AndroidOpenSSL")) {
+ assertNull(c.doFinal());
- c.update(EmptyArray.BYTE);
- assertNull(c.doFinal());
+ c.update(EmptyArray.BYTE);
+ assertNull(c.doFinal());
+ } else {
+ throw new AssertionError("Define your behavior here for " + provider);
+ }
}
// .doFinal(input)
@@ -1769,7 +2101,7 @@ public final class CipherTest extends TestCase {
Arrays.toString(Arrays.copyOfRange(actualPlaintext, 1, p.plaintext.length + 1)));
}
- Cipher cNoPad = Cipher.getInstance(p.mode + "/NoPadding");
+ Cipher cNoPad = Cipher.getInstance(p.mode + "/NoPadding", provider);
cNoPad.init(Cipher.DECRYPT_MODE, key, spec);
final byte[] actualPlaintextPadded = cNoPad.doFinal(p.ciphertext);
@@ -1799,14 +2131,21 @@ public final class CipherTest extends TestCase {
}
public void testCipher_ShortBlock_Failure() throws Exception {
+ for (String provider : AES_PROVIDERS) {
+ testCipher_ShortBlock_Failure(provider);
+ }
+ }
+
+ private void testCipher_ShortBlock_Failure(String provider) throws Exception {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
for (CipherTestParam p : CIPHER_TEST_PARAMS) {
try {
- checkCipher_ShortBlock_Failure(p);
+ checkCipher_ShortBlock_Failure(p, provider);
} catch (Exception e) {
out.append("Error encountered checking " + p.mode + ", keySize="
- + (p.key.length * 8) + "\n");
+ + (p.key.length * 8)
+ + " with provider " + provider + "\n");
e.printStackTrace(out);
}
}
@@ -1816,9 +2155,9 @@ public final class CipherTest extends TestCase {
}
}
- private void checkCipher_ShortBlock_Failure(CipherTestParam p) throws Exception {
+ private void checkCipher_ShortBlock_Failure(CipherTestParam p, String provider) throws Exception {
SecretKey key = new SecretKeySpec(p.key, "AES");
- Cipher c = Cipher.getInstance(p.mode + "/NoPadding");
+ Cipher c = Cipher.getInstance(p.mode + "/NoPadding", provider);
if (c.getBlockSize() == 0) {
return;
}
@@ -1832,8 +2171,14 @@ public final class CipherTest extends TestCase {
}
public void testAES_ECB_PKCS5Padding_ShortBuffer_Failure() throws Exception {
+ for (String provider : AES_PROVIDERS) {
+ testAES_ECB_PKCS5Padding_ShortBuffer_Failure(provider);
+ }
+ }
+
+ private void testAES_ECB_PKCS5Padding_ShortBuffer_Failure(String provider) throws Exception {
SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
- Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding", provider);
c.init(Cipher.ENCRYPT_MODE, key);
final byte[] fragmentOutput = c.update(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext);
@@ -1880,8 +2225,14 @@ public final class CipherTest extends TestCase {
}
public void testAES_ECB_NoPadding_IncrementalUpdate_Success() throws Exception {
+ for (String provider : AES_PROVIDERS) {
+ testAES_ECB_NoPadding_IncrementalUpdate_Success(provider);
+ }
+ }
+
+ private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
- Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
c.init(Cipher.ENCRYPT_MODE, key);
for (int i = 0; i < AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1; i++) {
@@ -1906,8 +2257,14 @@ public final class CipherTest extends TestCase {
};
public void testAES_ECB_NoPadding_IvParameters_Failure() throws Exception {
+ for (String provider : AES_PROVIDERS) {
+ testAES_ECB_NoPadding_IvParameters_Failure(provider);
+ }
+ }
+
+ private void testAES_ECB_NoPadding_IvParameters_Failure(String provider) throws Exception {
SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
- Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
+ Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
try {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index 8c9239e..4095081 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -19,6 +19,7 @@ package libcore.javax.net.ssl;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
@@ -1012,7 +1013,7 @@ public class SSLSocketTest extends TestCase {
assertEquals(0, wrapping.getSoTimeout());
// setting wrapper sets underlying and ...
- int expectedTimeoutMillis = 1000; // Using a small value such as 10 was affected by rounding
+ int expectedTimeoutMillis = 1000; // 10 was too small because it was affected by rounding
wrapping.setSoTimeout(expectedTimeoutMillis);
assertEquals(expectedTimeoutMillis, wrapping.getSoTimeout());
assertEquals(expectedTimeoutMillis, underlying.getSoTimeout());
@@ -1050,6 +1051,52 @@ public class SSLSocketTest extends TestCase {
listening.close();
}
+ public void test_SSLSocket_setSoWriteTimeout() throws Exception {
+ if (StandardNames.IS_RI) {
+ // RI does not support write timeout on sockets
+ return;
+ }
+
+ final TestSSLContext c = TestSSLContext.create();
+ SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
+ c.port);
+ final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ Future<Void> future = executor.submit(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ server.startHandshake();
+ return null;
+ }
+ });
+ executor.shutdown();
+ client.startHandshake();
+
+ // Reflection is used so this can compile on the RI
+ String expectedClassName = "org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl";
+ Class actualClass = client.getClass();
+ assertEquals(expectedClassName, actualClass.getName());
+ Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout",
+ new Class[] { Integer.TYPE });
+ setSoWriteTimeout.invoke(client, 1);
+
+ // Try to make the size smaller (it can be 512k or even megabytes).
+ // Note that it may not respect your request, so read back the actual value.
+ int sendBufferSize = 1024;
+ client.setSendBufferSize(sendBufferSize);
+ sendBufferSize = client.getSendBufferSize();
+
+ try {
+ client.getOutputStream().write(new byte[sendBufferSize + 1]);
+ fail();
+ } catch (SocketTimeoutException expected) {
+ }
+
+ future.get();
+ client.close();
+ server.close();
+ c.close();
+ }
+
public void test_SSLSocket_interrupt() throws Exception {
ServerSocket listening = new ServerSocket(0);
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
index a1122ce..b4da1b8 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
@@ -47,6 +47,7 @@ import javax.crypto.ShortBufferException;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
+import libcore.java.security.StandardNames;
import org.apache.harmony.crypto.tests.support.MyCipher;
import tests.support.resource.Support_Resources;
@@ -545,7 +546,10 @@ public class CipherTest extends junit.framework.TestCase {
try {
c.doFinal(b, 3, 6, b1, 5);
fail();
- } catch (ShortBufferException expected) {
+ } catch (IllegalBlockSizeException maybeExpected) {
+ assertTrue(StandardNames.IS_RI);
+ } catch (ShortBufferException maybeExpected) {
+ assertFalse(StandardNames.IS_RI);
}
}
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyRepTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyRepTest.java
index 0dad827..a6529e8 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyRepTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyRepTest.java
@@ -26,199 +26,146 @@ import java.io.NotSerializableException;
import java.io.ObjectStreamException;
import java.security.KeyRep;
import java.security.Security;
-import java.util.Iterator;
import java.util.Set;
-
import junit.framework.TestCase;
-/**
- *
- *
- */
public class KeyRepTest extends TestCase {
- private static final Set<String> keyFactoryAlgorithm;
+ private static final Set<String> keyFactoryAlgorithms = Security.getAlgorithms("KeyFactory");
static {
- keyFactoryAlgorithm = Security.getAlgorithms("KeyFactory");
+ assertFalse(keyFactoryAlgorithms.isEmpty());
}
public final void testKeyRep01() {
- try {
- assertNotNull(new KeyRep(KeyRep.Type.SECRET, "", "", new byte[] {}));
- } catch (Exception e) {
- fail("Unexpected exception " + e.getMessage());
- }
-
- try {
- assertNotNull(new KeyRep(KeyRep.Type.PUBLIC, "", "", new byte[] {}));
- } catch (Exception e) {
- fail("Unexpected exception " + e.getMessage());
- }
-
- try {
- assertNotNull(new KeyRep(KeyRep.Type.PRIVATE, "", "", new byte[] {}));
- } catch (Exception e) {
- fail("Unexpected exception " + e.getMessage());
- }
+ assertNotNull(new KeyRep(KeyRep.Type.SECRET, "", "", new byte[] {}));
+ assertNotNull(new KeyRep(KeyRep.Type.PUBLIC, "", "", new byte[] {}));
+ assertNotNull(new KeyRep(KeyRep.Type.PRIVATE, "", "", new byte[] {}));
}
public final void testKeyRep02() {
try {
new KeyRep(null, "", "", new byte[] {});
fail("NullPointerException has not been thrown (type)");
- } catch (NullPointerException ok) {
-
+ } catch (NullPointerException expected) {
}
try {
new KeyRep(KeyRep.Type.SECRET, null, "", new byte[] {});
fail("NullPointerException has not been thrown (alg)");
- } catch (NullPointerException ok) {
-
+ } catch (NullPointerException expected) {
}
try {
new KeyRep(KeyRep.Type.PRIVATE, "", null, new byte[] {});
fail("NullPointerException has not been thrown (format)");
- } catch (NullPointerException ok) {
-
+ } catch (NullPointerException expected) {
}
try {
new KeyRep(KeyRep.Type.PUBLIC, "", "", null);
fail("NullPointerException has not been thrown (encoding)");
- } catch (NullPointerException ok) {
-
+ } catch (NullPointerException expected) {
}
}
- public final void testReadResolve01() throws ObjectStreamException {
- KeyRepChild kr = new KeyRepChild(KeyRep.Type.SECRET, "", "",
- new byte[] {});
+ public final void testReadResolve01() throws Exception {
+ KeyRepChild kr = new KeyRepChild(KeyRep.Type.SECRET, "", "", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (no format)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
kr = new KeyRepChild(KeyRep.Type.SECRET, "", "X.509", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (unacceptable format)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
kr = new KeyRepChild(KeyRep.Type.SECRET, "", "RAW", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (empty key)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
}
- public final void testReadResolve02() throws ObjectStreamException {
- KeyRepChild kr = new KeyRepChild(KeyRep.Type.PUBLIC, "", "",
- new byte[] {});
+ public final void testReadResolve02() throws Exception {
+ KeyRepChild kr = new KeyRepChild(KeyRep.Type.PUBLIC, "", "", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (no format)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
kr = new KeyRepChild(KeyRep.Type.PUBLIC, "", "RAW", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (unacceptable format)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
- kr = new KeyRepChild(KeyRep.Type.PUBLIC, "bla-bla", "X.509",
- new byte[] {});
+ kr = new KeyRepChild(KeyRep.Type.PUBLIC, "bla-bla", "X.509", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (unknown KeyFactory algorithm)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
}
- public final void testReadResolve03() throws ObjectStreamException {
- KeyRepChild kr = new KeyRepChild(KeyRep.Type.PRIVATE, "", "",
- new byte[] {});
+ public final void testReadResolve03() throws Exception {
+ KeyRepChild kr = new KeyRepChild(KeyRep.Type.PRIVATE, "", "", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (no format)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
kr = new KeyRepChild(KeyRep.Type.PRIVATE, "", "RAW", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (unacceptable format)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
- kr = new KeyRepChild(KeyRep.Type.PRIVATE, "bla-bla", "PKCS#8",
- new byte[] {});
+ kr = new KeyRepChild(KeyRep.Type.PRIVATE, "bla-bla", "PKCS#8", new byte[] {});
try {
kr.readResolve();
fail("NotSerializableException has not been thrown (unknown KeyFactory algorithm)");
- } catch (NotSerializableException ok) {
-
+ } catch (NotSerializableException expected) {
}
}
- public final void testReadResolve04() throws ObjectStreamException {
- if (keyFactoryAlgorithm.isEmpty()) {
- System.err.println(getName()
- + ": skipped - no KeyFactory algorithms available");
- return;
- } else {
- }
- for (Iterator<String> i = keyFactoryAlgorithm.iterator(); i.hasNext();) {
- KeyRepChild kr = new KeyRepChild(KeyRep.Type.PUBLIC, i.next(),
- "X.509", new byte[] { 1, 2, 3 });
+ public final void testReadResolve04() throws Exception {
+ for (String algorithm : keyFactoryAlgorithms) {
+ KeyRepChild kr = new KeyRepChild(KeyRep.Type.PUBLIC, algorithm, "X.509",
+ new byte[] { 1, 2, 3 });
try {
kr.readResolve();
- fail("NotSerializableException has not been thrown (no format)");
- } catch (NotSerializableException ok) {
-
+ fail("NotSerializableException has not been thrown (no format) " + algorithm);
+ } catch (NotSerializableException expected) {
}
}
}
- public final void testReadResolve05() throws ObjectStreamException {
- if (keyFactoryAlgorithm.isEmpty()) {
- System.err.println(getName()
- + ": skipped - no KeyFactory algorithms available");
- return;
- } else {
- }
- for (Iterator<String> i = keyFactoryAlgorithm.iterator(); i.hasNext();) {
- KeyRepChild kr = new KeyRepChild(KeyRep.Type.PRIVATE, i.next(),
- "PKCS#8", new byte[] { 1, 2, 3 });
+ public final void testReadResolve05() throws Exception {
+ for (String algorithm : keyFactoryAlgorithms) {
+ KeyRepChild kr = new KeyRepChild(KeyRep.Type.PRIVATE, algorithm, "PKCS#8",
+ new byte[] { 1, 2, 3 });
try {
kr.readResolve();
- fail("NotSerializableException has not been thrown (no format)");
- } catch (NotSerializableException ok) {
-
+ fail("NotSerializableException has not been thrown (no format) " + algorithm);
+ } catch (NotSerializableException expected) {
}
}
}
class KeyRepChild extends KeyRep {
- public KeyRepChild(KeyRep.Type type, String algorithm, String format,
- byte[] encoded) {
+ public KeyRepChild(KeyRep.Type type, String algorithm, String format, byte[] encoded) {
super(type, algorithm, format, encoded);
}
- public Object readResolve() throws ObjectStreamException {
+ // Overriden to make public for testing
+ @Override public Object readResolve() throws ObjectStreamException {
return super.readResolve();
}
-
}
}
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreLoadStoreParameterTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreLoadStoreParameterTest.java
deleted file mode 100644
index 81ec30d..0000000
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreLoadStoreParameterTest.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.apache.harmony.security.tests.java.security;
-
-import java.security.KeyStore;
-
-public class KeyStoreLoadStoreParameterTest {
-
- class MyLoadStoreParameter implements KeyStore.LoadStoreParameter {
- public KeyStore.ProtectionParameter getProtectionParameter() {
- return null;
- }
- }
-
-
-
-}
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java
index d9f4dd7..68e7cbc 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java
@@ -20,14 +20,14 @@ package org.apache.harmony.security.tests.java.security;
import java.security.InvalidParameterException;
import java.security.Provider;
import java.security.Security;
-import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import junit.framework.TestCase;
import tests.support.Support_ProviderTrust;
import tests.support.Support_TestProvider;
-public class Security2Test extends junit.framework.TestCase {
+public class Security2Test extends TestCase {
/**
* java.security.Security#getProviders(java.lang.String)
@@ -36,16 +36,13 @@ public class Security2Test extends junit.framework.TestCase {
// Test for method void
// java.security.Security.getProviders(java.lang.String)
- Hashtable<String, Integer> allSupported = new Hashtable<String, Integer>();
+ Map<String, Integer> allSupported = new HashMap<String, Integer>();
Provider[] allProviders = Security.getProviders();
// Add all non-alias entries to allSupported
- for (int i = 0; i < allProviders.length; i++) {
- Provider provider = allProviders[i];
- Iterator it = provider.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry entry = (Map.Entry) it.next();
- String key = (String) entry.getKey();
+ for (Provider provider : allProviders) {
+ for (Object k : provider.keySet()) {
+ String key = (String) k;
// No aliases and no provider data
if (!isAlias(key) && !isProviderData(key)) {
addOrIncrementTable(allSupported, key);
@@ -56,22 +53,18 @@ public class Security2Test extends junit.framework.TestCase {
// Now walk through aliases. If an alias has actually been added
// to the allSupported table then increment the count of the
// entry that is being aliased.
- for (int i = 0; i < allProviders.length; i++) {
- Provider provider = allProviders[i];
- Iterator it = provider.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry entry = (Map.Entry) it.next();
+ for (Provider provider : allProviders) {
+ for (Map.Entry entry : provider.entrySet()) {
String key = (String) entry.getKey();
if (isAlias(key)) {
String aliasVal = key.substring("ALG.ALIAS.".length());
- String aliasKey = aliasVal.substring(0, aliasVal
- .indexOf(".") + 1)
+ String aliasKey = aliasVal.substring(0, aliasVal.indexOf(".") + 1)
+ entry.getValue();
// Skip over nonsense alias declarations where alias and
// aliased are identical. Such entries can occur.
- if (!aliasVal.equals(aliasKey)) {
+ if (!aliasVal.equalsIgnoreCase(aliasKey)) {
// Has a real entry been added for aliasValue ?
- if (allSupported.containsKey(aliasVal)) {
+ if (allSupported.containsKey(aliasVal.toUpperCase())) {
// Add 1 to the provider count of the thing being
// aliased
addOrIncrementTable(allSupported, aliasKey);
@@ -81,17 +74,13 @@ public class Security2Test extends junit.framework.TestCase {
}// end while more entries
}// end for all providers
- Provider provTest[] = null;
- Iterator it = allSupported.keySet().iterator();
- while (it.hasNext()) {
- String filterString = (String) it.next();
+ for (String filterString : allSupported.keySet()) {
try {
- provTest = Security.getProviders(filterString);
- int expected = ((Integer) allSupported.get(filterString))
- .intValue();
- assertEquals(
- "Unexpected number of providers returned for filter "
- + filterString, expected, provTest.length);
+ Provider[] provTest = Security.getProviders(filterString);
+ int expected = allSupported.get(filterString);
+ assertEquals("Unexpected number of providers returned for filter " + filterString
+ + ":\n" + allSupported,
+ expected, provTest.length);
} catch (InvalidParameterException e) {
// NO OP
}
@@ -99,62 +88,43 @@ public class Security2Test extends junit.framework.TestCase {
// exception
try {
- provTest = Security.getProviders("Signature.SHA1withDSA :512");
+ Security.getProviders("Signature.SHA1withDSA :512");
fail("InvalidParameterException should be thrown <Signature.SHA1withDSA :512>");
} catch (InvalidParameterException e) {
// Expected
}
}
- /**
- * @param key
- * @return
- */
private boolean isProviderData(String key) {
return key.toUpperCase().startsWith("PROVIDER.");
}
- /**
- * @param key
- * @return
- */
private boolean isAlias(String key) {
return key.toUpperCase().startsWith("ALG.ALIAS.");
}
- /**
- * @param table
- * @param key
- */
- private void addOrIncrementTable(Hashtable<String, Integer> table, String key) {
+ private void addOrIncrementTable(Map<String, Integer> table, String k) {
+ String key = k.toUpperCase();
if (table.containsKey(key)) {
- Integer before = (Integer) table.get(key);
- table.put(key, new Integer(before.intValue() + 1));
+ int before = table.get(key);
+ table.put(key, before + 1);
} else {
- table.put(key, new Integer(1));
+ table.put(key, 1);
}
}
- /**
- * @param filterMap
- * @return
- */
private int getProvidersCount(Map filterMap) {
int result = 0;
Provider[] allProviders = Security.getProviders();
// for each provider
- for (int i = 0; i < allProviders.length; i++) {
- Provider provider = allProviders[i];
+ for (Provider provider : allProviders) {
Set allProviderKeys = provider.keySet();
boolean noMatchFoundForFilterEntry = false;
// for each filter item
- Set allFilterKeys = filterMap.keySet();
- Iterator fkIter = allFilterKeys.iterator();
- while (fkIter.hasNext()) {
- String filterString = ((String) fkIter.next()).trim();
-
+ for (Object filter : filterMap.keySet()) {
+ String filterString = (String) filter;
// Remove any "=" characters that may be on the end of the
// map keys (no, I don't know why they might be there either
// but I have seen them)
@@ -211,10 +181,10 @@ public class Security2Test extends junit.framework.TestCase {
// Test for method void
// java.security.Security.getProviders(java.util.Map)
- Map<String, String> filter = new Hashtable<String, String>();
+ Map<String, String> filter = new HashMap<String, String>();
filter.put("KeyStore.BKS", "");
filter.put("Signature.SHA1withDSA", "");
- Provider provTest[] = Security.getProviders(filter);
+ Provider[] provTest = Security.getProviders(filter);
if (provTest == null) {
assertEquals("Filter : <KeyStore.BKS>,<Signature.SHA1withDSA>",
0, getProvidersCount(filter));
@@ -223,7 +193,7 @@ public class Security2Test extends junit.framework.TestCase {
getProvidersCount(filter), provTest.length);
}
- filter = new Hashtable<String, String>();
+ filter = new HashMap<String, String>();
filter.put("MessageDigest.SHA-384", "");
filter.put("CertificateFactory.X.509", "");
filter.put("KeyFactory.RSA", "");
@@ -237,7 +207,7 @@ public class Security2Test extends junit.framework.TestCase {
getProvidersCount(filter), provTest.length);
}
- filter = new Hashtable<String, String>();
+ filter = new HashMap<String, String>();
filter.put("MessageDigest.SHA1", "");
filter.put("TrustManagerFactory.X509", "");
provTest = Security.getProviders(filter);
@@ -250,7 +220,7 @@ public class Security2Test extends junit.framework.TestCase {
getProvidersCount(filter), provTest.length);
}
- filter = new Hashtable<String, String>();
+ filter = new HashMap<String, String>();
filter.put("CertificateFactory.X509", "");
provTest = Security.getProviders(filter);
if (provTest == null) {
@@ -261,7 +231,7 @@ public class Security2Test extends junit.framework.TestCase {
getProvidersCount(filter), provTest.length);
}
- filter = new Hashtable<String, String>();
+ filter = new HashMap<String, String>();
filter.put("Provider.id name", "DRLCertFactory");
provTest = Security.getProviders(filter);
assertNull("Filter : <Provider.id name, DRLCertFactory >",
@@ -270,7 +240,7 @@ public class Security2Test extends junit.framework.TestCase {
// exception - no attribute name after the service.algorithm yet we
// still supply an expected value. This is not valid.
try {
- filter = new Hashtable<String, String>();
+ filter = new HashMap<String, String>();
filter.put("Signature.SHA1withDSA", "512");
provTest = Security.getProviders(filter);
fail("InvalidParameterException should be thrown <Signature.SHA1withDSA><512>");
@@ -280,7 +250,7 @@ public class Security2Test extends junit.framework.TestCase {
// exception - space character in the service.algorithm pair. Not valid.
try {
- filter = new Hashtable<String, String>();
+ filter = new HashMap<String, String>();
filter.put("Signature. KeySize", "512");
provTest = Security.getProviders(filter);
fail("InvalidParameterException should be thrown <Signature. KeySize><512>");
@@ -320,11 +290,9 @@ public class Security2Test extends junit.framework.TestCase {
assertTrue("Failed to add provider", addResult != -1);
Security.removeProvider(entrust.getName());
- Provider provTest[] = Security.getProviders();
- for (int i = 0; i < provTest.length; i++) {
- assertTrue(
- "the provider entrust is found after it was removed",
- provTest[i].getName() != entrust.getName());
+ for (Provider provider : Security.getProviders()) {
+ assertTrue("the provider entrust is found after it was removed",
+ provider.getName() != entrust.getName());
}
} finally {
// Tidy up - the following calls do nothing if the providers were
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java
new file mode 100644
index 0000000..8359c99
--- /dev/null
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import libcore.java.security.TestKeyStore;
+
+public class CertPinManagerTest extends TestCase {
+
+ private X509Certificate[] chain;
+ private List<X509Certificate> shortChain;
+ private List<X509Certificate> longChain;
+ private String shortPin;
+ private String longPin;
+ private List<File> tmpFiles = new ArrayList<File>();
+
+ private String writeTmpPinFile(String text) throws Exception {
+ File tmp = File.createTempFile("pins", null);
+ FileWriter fstream = new FileWriter(tmp);
+ fstream.write(text);
+ fstream.close();
+ tmpFiles.add(tmp);
+ return tmp.getPath();
+ }
+
+ private static String getFingerprint(X509Certificate cert) throws NoSuchAlgorithmException {
+ MessageDigest dgst = MessageDigest.getInstance("SHA512");
+ byte[] encoded = cert.getPublicKey().getEncoded();
+ byte[] fingerprint = dgst.digest(encoded);
+ return IntegralToString.bytesToHexString(fingerprint, false);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ // build some valid chains
+ KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+ chain = (X509Certificate[]) pke.getCertificateChain();
+ X509Certificate root = chain[2];
+ X509Certificate server = chain[0];
+
+ // build the short and long chains
+ shortChain = new ArrayList<X509Certificate>();
+ shortChain.add(root);
+ longChain = new ArrayList<X509Certificate>();
+ longChain.add(server);
+
+ // we'll use the root as the pin for the short entry and the server as the pin for the long
+ shortPin = getFingerprint(root);
+ longPin = getFingerprint(server);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ for (File f : tmpFiles) {
+ f.delete();
+ }
+ tmpFiles.clear();
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ public void testPinFileMaximumLookup() throws Exception {
+
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=true|" + shortPin;
+ String longEntry = "*.clients.google.com=true|" + longPin;
+
+ // create the pinFile
+ String path = writeTmpPinFile(shortEntry + "\n" + longEntry);
+ CertPinManager pf = new CertPinManager(path, new TrustedCertificateStore());
+
+ // verify that the shorter chain doesn't work for a name matching the longer
+ assertTrue("short chain long uri failed",
+ pf.chainIsNotPinned("android.clients.google.com", shortChain));
+ // verify that the longer chain doesn't work for a name matching the shorter
+ assertTrue("long chain short uri failed",
+ pf.chainIsNotPinned("android.google.com", longChain));
+ // verify that the shorter chain works for the shorter domain
+ assertTrue("short chain short uri failed",
+ !pf.chainIsNotPinned("android.google.com", shortChain));
+ // and the same for the longer
+ assertTrue("long chain long uri failed",
+ !pf.chainIsNotPinned("android.clients.google.com", longChain));
+ }
+
+ public void testPinEntryMalformedEntry() throws Exception {
+ // set up the pinEntry with a bogus entry
+ String entry = "*.google.com=";
+ try {
+ new PinListEntry(entry, new TrustedCertificateStore());
+ fail("Accepted an empty pin list entry.");
+ } catch (PinEntryException expected) {
+ }
+ }
+
+ public void testPinEntryNull() throws Exception {
+ // set up the pinEntry with a bogus entry
+ String entry = null;
+ try {
+ new PinListEntry(entry, new TrustedCertificateStore());
+ fail("Accepted a basically wholly bogus entry.");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testPinEntryEmpty() throws Exception {
+ // set up the pinEntry with a bogus entry
+ try {
+ new PinListEntry("", new TrustedCertificateStore());
+ fail("Accepted an empty entry.");
+ } catch (PinEntryException expected) {
+ }
+ }
+
+ public void testPinEntryPinFailure() throws Exception {
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=true|" + shortPin;
+
+ // set up the pinEntry with a pinlist that doesn't match what we'll give it
+ PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
+ assertTrue("Not enforcing!", e.getEnforcing());
+ // verify that it doesn't accept
+ boolean retval = e.chainIsNotPinned(longChain);
+ assertTrue("Accepted an incorrect pinning, this is very bad", retval);
+ }
+
+ public void testPinEntryPinSuccess() throws Exception {
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=true|" + shortPin;
+
+ // set up the pinEntry with a pinlist that matches what we'll give it
+ PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
+ assertTrue("Not enforcing!", e.getEnforcing());
+ // verify that it accepts
+ boolean retval = e.chainIsNotPinned(shortChain);
+ assertTrue("Failed on a correct pinning, this is very bad", !retval);
+ }
+
+ public void testPinEntryNonEnforcing() throws Exception {
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=false|" + shortPin;
+
+ // set up the pinEntry with a pinlist that matches what we'll give it
+ PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
+ assertFalse("Enforcing!", e.getEnforcing());
+ // verify that it accepts
+ boolean retval = e.chainIsNotPinned(shortChain);
+ assertTrue("Failed on an unenforced pinning, this is bad-ish", !retval);
+ }
+}
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
index b861353..687e4a7 100644
--- a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
@@ -22,10 +22,14 @@ import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -39,6 +43,7 @@ import javax.net.ssl.SSLException;
import javax.net.ssl.SSLProtocolException;
import javax.security.auth.x500.X500Principal;
import junit.framework.TestCase;
+import libcore.io.IoUtils;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
import org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSLHandshakeCallbacks;
@@ -48,7 +53,8 @@ public class NativeCryptoTest extends TestCase {
private static final int NULL = 0;
private static final FileDescriptor INVALID_FD = new FileDescriptor();
- private static final SSLHandshakeCallbacks DUMMY_CB = new TestSSLHandshakeCallbacks(-1, null);
+ private static final SSLHandshakeCallbacks DUMMY_CB
+ = new TestSSLHandshakeCallbacks(null, 0, null);
private static final long TIMEOUT_SECONDS = 5;
@@ -137,6 +143,87 @@ public class NativeCryptoTest extends TestCase {
assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual));
}
+ public void test_EVP_PKEY_cmp() throws Exception {
+ try {
+ NativeCrypto.EVP_PKEY_cmp(NULL, NULL);
+ fail("Should throw NullPointerException when arguments are NULL");
+ } catch (NullPointerException expected) {
+ }
+
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(512);
+
+ KeyPair kp1 = kpg.generateKeyPair();
+ RSAPrivateCrtKey privKey1 = (RSAPrivateCrtKey) kp1.getPrivate();
+
+ KeyPair kp2 = kpg.generateKeyPair();
+ RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate();
+
+ int pkey1 = 0, pkey1_copy = 0, pkey2 = 0;
+ try {
+ pkey1 = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
+ privKey1.getPublicExponent().toByteArray(),
+ privKey1.getPrivateExponent().toByteArray(),
+ privKey1.getPrimeP().toByteArray(),
+ privKey1.getPrimeQ().toByteArray(),
+ privKey1.getPrimeExponentP().toByteArray(),
+ privKey1.getPrimeExponentQ().toByteArray(),
+ privKey1.getCrtCoefficient().toByteArray());
+ assertNotSame(NULL, pkey1);
+
+ pkey1_copy = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
+ privKey1.getPublicExponent().toByteArray(),
+ privKey1.getPrivateExponent().toByteArray(),
+ privKey1.getPrimeP().toByteArray(),
+ privKey1.getPrimeQ().toByteArray(),
+ privKey1.getPrimeExponentP().toByteArray(),
+ privKey1.getPrimeExponentQ().toByteArray(),
+ privKey1.getCrtCoefficient().toByteArray());
+ assertNotSame(NULL, pkey1_copy);
+
+ pkey2 = NativeCrypto.EVP_PKEY_new_RSA(privKey2.getModulus().toByteArray(),
+ privKey2.getPublicExponent().toByteArray(),
+ privKey2.getPrivateExponent().toByteArray(),
+ privKey2.getPrimeP().toByteArray(),
+ privKey2.getPrimeQ().toByteArray(),
+ privKey2.getPrimeExponentP().toByteArray(),
+ privKey2.getPrimeExponentQ().toByteArray(),
+ privKey2.getCrtCoefficient().toByteArray());
+ assertNotSame(NULL, pkey2);
+
+ try {
+ NativeCrypto.EVP_PKEY_cmp(pkey1, NULL);
+ fail("Should throw NullPointerException when arguments are NULL");
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ NativeCrypto.EVP_PKEY_cmp(NULL, pkey1);
+ fail("Should throw NullPointerException when arguments are NULL");
+ } catch (NullPointerException expected) {
+ }
+
+ assertEquals("Same keys should be the equal", 1,
+ NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1));
+
+ assertEquals("Same keys should be the equal", 1,
+ NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1_copy));
+
+ assertEquals("Different keys should not be equal", 0,
+ NativeCrypto.EVP_PKEY_cmp(pkey1, pkey2));
+ } finally {
+ if (pkey1 != 0) {
+ NativeCrypto.EVP_PKEY_free(pkey1);
+ }
+ if (pkey1_copy != 0) {
+ NativeCrypto.EVP_PKEY_free(pkey1_copy);
+ }
+ if (pkey2 != 0) {
+ NativeCrypto.EVP_PKEY_free(pkey2);
+ }
+ }
+ }
+
public void test_SSL_CTX_new() throws Exception {
int c = NativeCrypto.SSL_CTX_new();
assertTrue(c != NULL);
@@ -496,11 +583,14 @@ public class NativeCryptoTest extends TestCase {
}
public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks {
+ private final Socket socket;
private final int sslNativePointer;
private final Hooks hooks;
- public TestSSLHandshakeCallbacks(int sslNativePointer,
+ public TestSSLHandshakeCallbacks(Socket socket,
+ int sslNativePointer,
Hooks hooks) {
+ this.socket = socket;
this.sslNativePointer = sslNativePointer;
this.hooks = hooks;
}
@@ -552,6 +642,10 @@ public class NativeCryptoTest extends TestCase {
}
this.handshakeCompletedCalled = true;
}
+
+ public Socket getSocket() {
+ return socket;
+ }
}
public static class ServerHooks extends Hooks {
@@ -589,12 +683,13 @@ public class NativeCryptoTest extends TestCase {
listener.getLocalPort())
: listener.accept());
if (timeout == -1) {
- return null;
+ return new TestSSLHandshakeCallbacks(socket, 0, null);
}
FileDescriptor fd = socket.getFileDescriptor$();
int c = hooks.getContext();
int s = hooks.beforeHandshake(c);
- TestSSLHandshakeCallbacks callback = new TestSSLHandshakeCallbacks(s, hooks);
+ TestSSLHandshakeCallbacks callback
+ = new TestSSLHandshakeCallbacks(socket, s, hooks);
if (DEBUG) {
System.out.println("ssl=0x" + Integer.toString(s, 16)
+ " handshake"
@@ -604,14 +699,19 @@ public class NativeCryptoTest extends TestCase {
+ " timeout=" + timeout
+ " client=" + client);
}
- int session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client,
- npnProtocols);
- if (DEBUG) {
- System.out.println("ssl=0x" + Integer.toString(s, 16)
- + " handshake"
- + " session=0x" + Integer.toString(session, 16));
+ int session = NULL;
+ try {
+ session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client,
+ npnProtocols);
+ if (DEBUG) {
+ System.out.println("ssl=0x" + Integer.toString(s, 16)
+ + " handshake"
+ + " session=0x" + Integer.toString(session, 16));
+ }
+ } finally {
+ // Ensure afterHandshake is called to free resources
+ hooks.afterHandshake(session, s, c, socket, fd, callback);
}
- hooks.afterHandshake(session, s, c, socket, fd, callback);
return callback;
}
});
@@ -783,17 +883,21 @@ public class NativeCryptoTest extends TestCase {
Socket sock, FileDescriptor fd,
SSLHandshakeCallbacks callback)
throws Exception {
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- NativeCrypto.SSL_set_options(
- s, NativeCrypto.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
- NativeCrypto.SSL_renegotiate(s);
- NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1);
- super.afterHandshake(session, s, c, sock, fd, callback);
+ try {
+ NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
+ NativeCrypto.SSL_set_options(
+ s, NativeCrypto.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
+ NativeCrypto.SSL_renegotiate(s);
+ NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1,
+ (int) ((TIMEOUT_SECONDS * 1000) / 2));
+ } catch (IOException expected) {
+ } finally {
+ super.afterHandshake(session, s, c, sock, fd, callback);
+ }
}
};
Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null);
Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
try {
client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (ExecutionException e) {
@@ -801,35 +905,49 @@ public class NativeCryptoTest extends TestCase {
throw e;
}
}
+ server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
public void test_SSL_do_handshake_client_timeout() throws Exception {
// client timeout
final ServerSocket listener = new ServerSocket(0);
+ Socket serverSocket = null;
try {
Hooks cHooks = new Hooks();
Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
Future<TestSSLHandshakeCallbacks> client = handshake(listener, 1, true, cHooks, null);
Future<TestSSLHandshakeCallbacks> server = handshake(listener, -1, false, sHooks, null);
+ serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
fail();
} catch (ExecutionException expected) {
+ if (SocketTimeoutException.class != expected.getCause().getClass()) {
+ expected.printStackTrace();
+ }
assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
+ } finally {
+ // Manually close peer socket when testing timeout
+ IoUtils.closeQuietly(serverSocket);
}
}
public void test_SSL_do_handshake_server_timeout() throws Exception {
// server timeout
final ServerSocket listener = new ServerSocket(0);
+ Socket clientSocket = null;
try {
Hooks cHooks = new Hooks();
Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
Future<TestSSLHandshakeCallbacks> client = handshake(listener, -1, true, cHooks, null);
Future<TestSSLHandshakeCallbacks> server = handshake(listener, 1, false, sHooks, null);
+ clientSocket = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
fail();
} catch (ExecutionException expected) {
assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
+ } finally {
+ // Manually close peer socket when testing timeout
+ IoUtils.closeQuietly(clientSocket);
}
}
@@ -1156,7 +1274,7 @@ public class NativeCryptoTest extends TestCase {
SSLHandshakeCallbacks callback)
throws Exception {
NativeCrypto.SSL_renegotiate(s);
- NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1);
+ NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 0);
super.afterHandshake(session, s, c, sock, fd, callback);
}
};
@@ -1323,7 +1441,7 @@ public class NativeCryptoTest extends TestCase {
Socket sock, FileDescriptor fd,
SSLHandshakeCallbacks callback)
throws Exception {
- NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length);
+ NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length, 0);
super.afterHandshake(session, s, c, sock, fd, callback);
}
};
@@ -1366,7 +1484,7 @@ public class NativeCryptoTest extends TestCase {
public void test_SSL_write() throws Exception {
try {
- NativeCrypto.SSL_write(NULL, null, null, null, 0, 0);
+ NativeCrypto.SSL_write(NULL, null, null, null, 0, 0, 0);
fail();
} catch (NullPointerException expected) {
}
@@ -1376,7 +1494,7 @@ public class NativeCryptoTest extends TestCase {
int c = NativeCrypto.SSL_CTX_new();
int s = NativeCrypto.SSL_new(c);
try {
- NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1);
+ NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0);
fail();
} catch (NullPointerException expected) {
}
@@ -1389,7 +1507,7 @@ public class NativeCryptoTest extends TestCase {
int c = NativeCrypto.SSL_CTX_new();
int s = NativeCrypto.SSL_new(c);
try {
- NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1);
+ NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0);
fail();
} catch (NullPointerException expected) {
}
@@ -1402,7 +1520,7 @@ public class NativeCryptoTest extends TestCase {
int c = NativeCrypto.SSL_CTX_new();
int s = NativeCrypto.SSL_new(c);
try {
- NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1);
+ NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0);
fail();
} catch (NullPointerException expected) {
}
@@ -1415,7 +1533,7 @@ public class NativeCryptoTest extends TestCase {
int c = NativeCrypto.SSL_CTX_new();
int s = NativeCrypto.SSL_new(c);
try {
- NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1);
+ NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
fail();
} catch (SSLException expected) {
}
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImplTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImplTest.java
index 26ebc85..fe5f4f0 100644
--- a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImplTest.java
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImplTest.java
@@ -16,9 +16,15 @@
package org.apache.harmony.xnet.provider.jsse;
-import java.security.KeyStore;
+import java.io.File;
+import java.io.FileWriter;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
@@ -27,12 +33,41 @@ import libcore.java.security.TestKeyStore;
public class TrustManagerImplTest extends TestCase {
+ private List<File> tmpFiles = new ArrayList<File>();
+
+ private String getFingerprint(X509Certificate cert) throws Exception {
+ MessageDigest dgst = MessageDigest.getInstance("SHA512");
+ byte[] encoded = cert.getPublicKey().getEncoded();
+ byte[] fingerprint = dgst.digest(encoded);
+ return IntegralToString.bytesToHexString(fingerprint, false);
+ }
+
+ private String writeTmpPinFile(String text) throws Exception {
+ File tmp = File.createTempFile("pins", null);
+ FileWriter fstream = new FileWriter(tmp);
+ fstream.write(text);
+ fstream.close();
+ tmpFiles.add(tmp);
+ return tmp.getPath();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ for (File f : tmpFiles) {
+ f.delete();
+ }
+ tmpFiles.clear();
+ } finally {
+ super.tearDown();
+ }
+ }
+
/**
* Ensure that our non-standard behavior of learning to trust new
* intermediate CAs does not regress. http://b/3404902
*/
public void testLearnIntermediate() throws Exception {
-
// chain3 should be server/intermediate/root
KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
@@ -63,6 +98,52 @@ public class TrustManagerImplTest extends TestCase {
assertValid(chain1, tm);
}
+ public void testGetFullChain() throws Exception {
+ // build the trust manager
+ KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+ X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
+ X509Certificate root = chain3[2];
+ X509TrustManager tm = trustManager(root);
+
+ // build the chains we'll use for testing
+ X509Certificate intermediate = chain3[1];
+ X509Certificate server = chain3[0];
+ X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
+ X509Certificate[] chain1 = new X509Certificate[] { server };
+
+ assertTrue(tm instanceof TrustManagerImpl);
+ TrustManagerImpl tmi = (TrustManagerImpl) tm;
+ List<X509Certificate> certs = tmi.checkServerTrusted(chain2, "RSA", "purple.com");
+ assertEquals(Arrays.asList(chain3), certs);
+ certs = tmi.checkServerTrusted(chain1, "RSA", "purple.com");
+ assertEquals(Arrays.asList(chain3), certs);
+ }
+
+ public void testCertPinning() throws Exception {
+ // chain3 should be server/intermediate/root
+ KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+ X509Certificate[] chain3 = (X509Certificate[]) pke.getCertificateChain();
+ X509Certificate root = chain3[2];
+ X509Certificate intermediate = chain3[1];
+ X509Certificate server = chain3[0];
+ X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
+ X509Certificate[] chain1 = new X509Certificate[] { server };
+
+ // test without a hostname, expecting failure
+ assertInvalidPinned(chain1, trustManager(root, "gugle.com", root), null);
+ // test without a hostname, expecting success
+ assertValidPinned(chain3, trustManager(root, "gugle.com", root), null, chain3);
+ // test an unpinned hostname that should fail
+ assertInvalidPinned(chain1, trustManager(root, "gugle.com", root), "purple.com");
+ // test an unpinned hostname that should succeed
+ assertValidPinned(chain3, trustManager(root, "gugle.com", root), "purple.com", chain3);
+ // test a pinned hostname that should fail
+ assertInvalidPinned(chain1, trustManager(intermediate, "gugle.com", root), "gugle.com");
+ // test a pinned hostname that should succeed
+ assertValidPinned(chain2, trustManager(intermediate, "gugle.com", server), "gugle.com",
+ chain2);
+ }
+
private X509TrustManager trustManager(X509Certificate ca) throws Exception {
KeyStore keyStore = TestKeyStore.createKeyStore();
keyStore.setCertificateEntry("alias", ca);
@@ -73,10 +154,45 @@ public class TrustManagerImplTest extends TestCase {
return (X509TrustManager) tmf.getTrustManagers()[0];
}
+ private TrustManagerImpl trustManager(X509Certificate ca, String hostname, X509Certificate pin)
+ throws Exception {
+ // build the cert pin manager
+ CertPinManager cm = certManager(hostname, pin);
+ // insert it into the trust manager
+ KeyStore keyStore = TestKeyStore.createKeyStore();
+ keyStore.setCertificateEntry("alias", ca);
+ return new TrustManagerImpl(keyStore, cm);
+ }
+
+ private CertPinManager certManager(String hostname, X509Certificate pin) throws Exception {
+ String pinString = "";
+ if (pin != null) {
+ pinString = hostname + "=true|" + getFingerprint(pin);
+ }
+ // write it to a pinfile
+ String path = writeTmpPinFile(pinString);
+ // build the certpinmanager
+ return new CertPinManager(path, new TrustedCertificateStore());
+ }
+
private void assertValid(X509Certificate[] chain, X509TrustManager tm) throws Exception {
- tm.checkClientTrusted(chain, "RSA");
+ if (tm instanceof TrustManagerImpl) {
+ TrustManagerImpl tmi = (TrustManagerImpl) tm;
+ tmi.checkServerTrusted(chain, "RSA");
+ }
tm.checkServerTrusted(chain, "RSA");
}
+
+ private void assertValidPinned(X509Certificate[] chain, X509TrustManager tm, String hostname,
+ X509Certificate[] fullChain) throws Exception {
+ if (tm instanceof TrustManagerImpl) {
+ TrustManagerImpl tmi = (TrustManagerImpl) tm;
+ List<X509Certificate> checkedChain = tmi.checkServerTrusted(chain, "RSA", hostname);
+ assertEquals(checkedChain, Arrays.asList(fullChain));
+ }
+ tm.checkServerTrusted(chain, "RSA");
+ }
+
private void assertInvalid(X509Certificate[] chain, X509TrustManager tm) {
try {
tm.checkClientTrusted(chain, "RSA");
@@ -89,4 +205,15 @@ public class TrustManagerImplTest extends TestCase {
} catch (CertificateException expected) {
}
}
+
+ private void assertInvalidPinned(X509Certificate[] chain, X509TrustManager tm, String hostname)
+ throws Exception {
+ assertTrue(tm.getClass().getName(), tm instanceof TrustManagerImpl);
+ try {
+ TrustManagerImpl tmi = (TrustManagerImpl) tm;
+ tmi.checkServerTrusted(chain, "RSA", hostname);
+ fail();
+ } catch (CertificateException expected) {
+ }
+ }
}
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStoreTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStoreTest.java
index 52880df..8f9b7fa 100644
--- a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStoreTest.java
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/TrustedCertificateStoreTest.java
@@ -530,6 +530,26 @@ public class TrustedCertificateStoreTest extends TestCase {
assertDeleted(getCa1(), getAliasSystemCa1());
}
+ public void testIsUserAddedCertificate() throws Exception {
+ assertFalse(store.isUserAddedCertificate(getCa1()));
+ assertFalse(store.isUserAddedCertificate(getCa2()));
+ install(getCa1(), getAliasSystemCa1());
+ assertFalse(store.isUserAddedCertificate(getCa1()));
+ assertFalse(store.isUserAddedCertificate(getCa2()));
+ install(getCa1(), getAliasUserCa1());
+ assertTrue(store.isUserAddedCertificate(getCa1()));
+ assertFalse(store.isUserAddedCertificate(getCa2()));
+ install(getCa2(), getAliasUserCa2());
+ assertTrue(store.isUserAddedCertificate(getCa1()));
+ assertTrue(store.isUserAddedCertificate(getCa2()));
+ store.deleteCertificateEntry(getAliasUserCa1());
+ assertFalse(store.isUserAddedCertificate(getCa1()));
+ assertTrue(store.isUserAddedCertificate(getCa2()));
+ store.deleteCertificateEntry(getAliasUserCa2());
+ assertFalse(store.isUserAddedCertificate(getCa1()));
+ assertFalse(store.isUserAddedCertificate(getCa2()));
+ }
+
private void assertRootCa(X509Certificate x, String alias) {
assertIntermediateCa(x, alias);
assertEquals(x, store.findIssuer(x));
diff --git a/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
index bdc580d..9c9f346 100644
--- a/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
+++ b/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
@@ -17,7 +17,8 @@
package tests.api.org.apache.harmony.kernel.dalvik;
import java.lang.reflect.Field;
-
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
import junit.framework.TestCase;
import sun.misc.Unsafe;
@@ -50,10 +51,11 @@ public class ThreadsTest extends TestCase {
/** Test the case where the park times out. */
public void test_parkFor_1() {
- Parker parker = new Parker(false, 500);
+ CyclicBarrier barrier = new CyclicBarrier(2);
+ Parker parker = new Parker(barrier, false, 500);
Thread parkerThread = new Thread(parker);
Thread waiterThread =
- new Thread(new WaitAndUnpark(1000, parkerThread));
+ new Thread(new WaitAndUnpark(barrier, 1000, parkerThread));
parkerThread.start();
waiterThread.start();
@@ -62,10 +64,11 @@ public class ThreadsTest extends TestCase {
/** Test the case where the unpark happens before the timeout. */
public void test_parkFor_2() {
- Parker parker = new Parker(false, 1000);
+ CyclicBarrier barrier = new CyclicBarrier(2);
+ Parker parker = new Parker(barrier, false, 1000);
Thread parkerThread = new Thread(parker);
Thread waiterThread =
- new Thread(new WaitAndUnpark(300, parkerThread));
+ new Thread(new WaitAndUnpark(barrier, 300, parkerThread));
parkerThread.start();
waiterThread.start();
@@ -74,7 +77,8 @@ public class ThreadsTest extends TestCase {
/** Test the case where the thread is preemptively unparked. */
public void test_parkFor_3() {
- Parker parker = new Parker(false, 1000);
+ CyclicBarrier barrier = new CyclicBarrier(1);
+ Parker parker = new Parker(barrier, false, 1000);
Thread parkerThread = new Thread(parker);
UNSAFE.unpark(parkerThread);
@@ -84,10 +88,11 @@ public class ThreadsTest extends TestCase {
/** Test the case where the park times out. */
public void test_parkUntil_1() {
- Parker parker = new Parker(true, 500);
+ CyclicBarrier barrier = new CyclicBarrier(2);
+ Parker parker = new Parker(barrier, true, 500);
Thread parkerThread = new Thread(parker);
Thread waiterThread =
- new Thread(new WaitAndUnpark(1000, parkerThread));
+ new Thread(new WaitAndUnpark(barrier, 1000, parkerThread));
parkerThread.start();
waiterThread.start();
@@ -96,10 +101,11 @@ public class ThreadsTest extends TestCase {
/** Test the case where the unpark happens before the timeout. */
public void test_parkUntil_2() {
- Parker parker = new Parker(true, 1000);
+ CyclicBarrier barrier = new CyclicBarrier(2);
+ Parker parker = new Parker(barrier, true, 1000);
Thread parkerThread = new Thread(parker);
Thread waiterThread =
- new Thread(new WaitAndUnpark(300, parkerThread));
+ new Thread(new WaitAndUnpark(barrier, 300, parkerThread));
parkerThread.start();
waiterThread.start();
@@ -108,7 +114,8 @@ public class ThreadsTest extends TestCase {
/** Test the case where the thread is preemptively unparked. */
public void test_parkUntil_3() {
- Parker parker = new Parker(true, 1000);
+ CyclicBarrier barrier = new CyclicBarrier(1);
+ Parker parker = new Parker(barrier, true, 1000);
Thread parkerThread = new Thread(parker);
UNSAFE.unpark(parkerThread);
@@ -123,6 +130,9 @@ public class ThreadsTest extends TestCase {
* the indicated value, noting the duration of time actually parked.
*/
private static class Parker implements Runnable {
+
+ private final CyclicBarrier barrier;
+
/** whether {@link #amount} is milliseconds to wait in an
* absolute fashion (<code>true</code>) or nanoseconds to wait
* in a relative fashion (<code>false</code>) */
@@ -147,7 +157,8 @@ public class ThreadsTest extends TestCase {
* either case, this constructor takes a duration to park for
* @param parkMillis the number of milliseconds to be parked
*/
- public Parker(boolean absolute, long parkMillis) {
+ public Parker(CyclicBarrier barrier, boolean absolute, long parkMillis) {
+ this.barrier = barrier;
this.absolute = absolute;
// Multiply by 1000000 because parkFor() takes nanoseconds.
@@ -155,8 +166,14 @@ public class ThreadsTest extends TestCase {
}
public void run() {
+ try {
+ barrier.await(60, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ throw new AssertionError(e);
+ }
boolean absolute = this.absolute;
long amount = this.amount;
+ long startNanos = System.nanoTime();
long start = System.currentTimeMillis();
if (absolute) {
@@ -165,11 +182,11 @@ public class ThreadsTest extends TestCase {
UNSAFE.park(false, amount);
}
- long end = System.currentTimeMillis();
+ long endNanos = System.nanoTime();
synchronized (this) {
- startMillis = start;
- endMillis = end;
+ startMillis = startNanos / 1000000;
+ endMillis = endNanos / 1000000;
completed = true;
notifyAll();
}
@@ -230,16 +247,23 @@ public class ThreadsTest extends TestCase {
* specified amount of time and then unparks an indicated thread.
*/
private static class WaitAndUnpark implements Runnable {
+ private final CyclicBarrier barrier;
private final long waitMillis;
private final Thread thread;
- public WaitAndUnpark(long waitMillis, Thread thread) {
+ public WaitAndUnpark(CyclicBarrier barrier, long waitMillis, Thread thread) {
+ this.barrier = barrier;
this.waitMillis = waitMillis;
this.thread = thread;
}
public void run() {
try {
+ barrier.await(60, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ throw new AssertionError(e);
+ }
+ try {
Thread.sleep(waitMillis);
} catch (InterruptedException ex) {
throw new RuntimeException("shouldn't happen", ex);
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index d5ceedf..7778896 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -352,14 +352,6 @@ public final class StandardNames extends Assert {
// different names: added "Encryption" suffix
unprovide("Signature", "MD5withRSA");
provide("Signature", "MD5WithRSAEncryption");
- unprovide("Signature", "SHA1withRSA");
- provide("Signature", "SHA1WithRSAEncryption");
- unprovide("Signature", "SHA256WithRSA");
- provide("Signature", "SHA256WithRSAEncryption");
- unprovide("Signature", "SHA384WithRSA");
- provide("Signature", "SHA384WithRSAEncryption");
- unprovide("Signature", "SHA512WithRSA");
- provide("Signature", "SHA512WithRSAEncryption");
// Added to support Android KeyStore operations
provide("Signature", "NONEwithRSA");
@@ -498,6 +490,12 @@ public final class StandardNames extends Assert {
// Android's CA store
provide("KeyStore", "AndroidCAStore");
+
+ // Android's KeyStore provider
+ if (Security.getProvider("AndroidKeyStoreProvider") != null) {
+ provide("KeyStore", "AndroidKeyStore");
+ provide("KeyPairGenerator", "AndroidKeyPairGenerator");
+ }
}
}