diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..3fe4c92
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,441 @@
+//
+// Copyright (C) 2016 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 {
+    default_visibility: [
+        ":__subpackages__",
+    ],
+}
+
+//
+// Definitions for building the Conscrypt Java library, native code,
+// and associated tests.
+//
+
+// Conscrypt is divided into subdirectories.
+//
+// The structure is:
+//
+//   constants/
+//       src/gen             # Generates NativeConstants.java.
+//   common/
+//       src/main/java       # Common Java source for all platforms.
+//       src/jni/
+//            main           # Common C++ source for all platforms.
+//            unbundled      # C++ source used for OpenJDK and unbundled Android.
+//       src/test/java       # Common test files for all platforms.
+//   android/
+//       src/main/java       # Java source for unbundled Android.
+//   openjdk/
+//       src/main/java       # Java source for OpenJDK.
+//       src/test
+//            java/          # Java source for common tests.
+//            resources/     # Support files for tests
+//   platform/
+//       src/main/java       # Java source for bundled Android.
+//       src/test
+//            java/          # Java source for bundled tests.
+//
+
+cc_defaults {
+    name: "conscrypt_global",
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wunused",
+    ],
+
+    srcs: [
+        "common/src/jni/main/cpp/conscrypt/compatibility_close_monitor.cc",
+        "common/src/jni/main/cpp/conscrypt/jniload.cc",
+        "common/src/jni/main/cpp/conscrypt/jniutil.cc",
+        "common/src/jni/main/cpp/conscrypt/native_crypto.cc",
+        "common/src/jni/main/cpp/conscrypt/netutil.cc",
+        "common/src/jni/main/cpp/conscrypt/trace.cc",
+    ],
+
+    local_include_dirs: [
+        "common/src/jni/main/include",
+    ],
+
+    compile_multilib: "both",
+    stl: "c++_static",
+}
+
+cc_defaults {
+    name: "conscrypt_unbundled-jni-defaults",
+
+    local_include_dirs: [
+        "common/src/jni/unbundled/include",
+    ],
+
+    shared_libs: [
+        "liblog",
+    ],
+
+    static_libs: [
+        "libssl",
+        "libcrypto",
+    ],
+
+    sdk_version: "9",
+}
+
+cc_library {
+    name: "libconscrypt_jni",
+    defaults: [
+        "conscrypt_global",
+        "conscrypt_unbundled-jni-defaults",
+    ],
+}
+
+cc_library_host_shared {
+    name: "libconscrypt_openjdk_jni",
+    defaults: ["conscrypt_global"],
+
+    cflags: [
+        "-DCONSCRYPT_OPENJDK",
+    ],
+
+    local_include_dirs: [
+        "common/src/jni/unbundled/include",
+    ],
+
+    static_libs: [
+        "libssl",
+        "libcrypto",
+    ],
+
+    // TODO: b/26097626. ASAN breaks use of this library in JVM.
+    // Re-enable sanitization when the issue with making clients of this library
+    // preload ASAN runtime is resolved. Without that, clients are getting runtime
+    // errors due to unresolved ASAN symbols, such as
+    // __asan_option_detect_stack_use_after_return.
+    sanitize: {
+        never: true,
+    },
+
+    stl: "libc++_static",
+
+    // The post-build signing tools need signapk.jar and its shared libs
+    multilib: {
+        lib64: {
+            dist: {
+                targets: ["droidcore"],
+            },
+        },
+    },
+}
+
+cc_binary_host {
+    name: "conscrypt_generate_constants",
+    srcs: ["constants/src/gen/cpp/generate_constants.cc"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "libssl",
+    ],
+}
+
+genrule {
+    name: "conscrypt-nojarjar_generated_constants",
+    out: ["org/conscrypt/NativeConstants.java"],
+    cmd: "$(location conscrypt_generate_constants) > $(out)",
+    tools: ["conscrypt_generate_constants"],
+}
+
+// Create the conscrypt library without jarjar for tests
+java_library {
+    name: "conscrypt-nojarjar",
+    visibility: [
+        "//build/make/tools/signapk",
+    ],
+    host_supported: true,
+    hostdex: true,
+
+    srcs: [
+        "common/src/main/java/**/*.java",
+        ":conscrypt-nojarjar_generated_constants",
+    ],
+
+    sdk_version: "none",
+    system_modules: "core-all-system-modules",
+    target: {
+        android: {
+            srcs: ["platform/src/main/java/**/*.java"],
+            libs: ["core-all"],
+        },
+        host: {
+            srcs: ["openjdk/src/main/java/**/*.java"],
+            javacflags: ["-XDignore.symbol.file"],
+        },
+    },
+
+    required: ["libjavacrypto"],
+    java_version: "1.7",
+}
+
+genrule {
+    name: "conscrypt_generated_constants",
+    out: ["com/android/org/conscrypt/NativeConstants.java"],
+    cmd: "$(location conscrypt_generate_constants) com.android.org.conscrypt > $(out)",
+    tools: ["conscrypt_generate_constants"],
+}
+
+filegroup {
+    name: "conscrypt_java_files",
+    visibility: [
+        "//libcore",
+    ],
+    srcs: [
+        "repackaged/common/src/main/java/**/*.java",
+        "repackaged/platform/src/main/java/**/*.java",
+        ":conscrypt_generated_constants",
+    ],
+}
+
+filegroup {
+    name: "conscrypt_public_api_files",
+    visibility: [
+        "//libcore",
+    ],
+    srcs: ["publicapi/src/main/java/**/*.java"],
+}
+
+// Create the conscrypt library from the source produced by the srcgen/generate_android_src.sh
+// script.
+java_library {
+    name: "conscrypt",
+    visibility: [
+        "//art/build",
+        "//device:__subpackages__",
+        "//external/okhttp",
+        "//external/robolectric-shadows",
+        "//external/wycheproof",
+        "//libcore",
+        "//system/apex/tests",
+        ":__subpackages__",
+    ],
+    installable: true,
+    hostdex: true,
+
+    srcs: [
+        ":conscrypt_java_files",
+        ":conscrypt_public_api_files",
+    ],
+
+    // Conscrypt can be updated independently from the other core libraries so it must only depend
+    // on public SDK and intra-core APIs.
+    sdk_version: "none",
+    libs: ["core.intra.stubs"],
+    patch_module: "java.base",
+    system_modules: "core-intra-stubs-system-modules",
+
+    // Workaround for b/124476339: libjavacrypto is required for both APEX and
+    // hostdex builds, but adding a top-level required property results in
+    // it being installed to /system on Android.
+    // TODO(b/124476339): move required back to a top level property
+    target: {
+        hostdex: {
+            required: ["libjavacrypto"],
+        },
+    },
+
+    permitted_packages: [
+        "android.net.ssl",
+        "com.android.org.conscrypt",
+    ],
+}
+
+// A guaranteed unstripped version of conscrypt.
+// The build system may or may not strip the conscrypt jar, but this one will
+// not be stripped. See b/24535627.
+java_library {
+    name: "conscrypt-testdex",
+    installable: true,
+
+    static_libs: ["conscrypt"],
+    dex_preopt: {
+        enabled: false,
+    },
+
+    sdk_version: "core_platform",
+
+    required: ["libjavacrypto"],
+}
+
+// Platform conscrypt crypto JNI library
+cc_defaults {
+    name: "libjavacrypto-defaults",
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wunused",
+        "-fvisibility=hidden",
+    ],
+
+    srcs: ["common/src/jni/main/cpp/**/*.cc"],
+    local_include_dirs: ["common/src/jni/main/include"],
+}
+
+// Platform conscrypt crypto JNI library
+cc_library_shared {
+    name: "libjavacrypto",
+    host_supported: true,
+    defaults: ["libjavacrypto-defaults"],
+
+    cflags: ["-DJNI_JARJAR_PREFIX=com/android/"],
+    header_libs: ["libnativehelper_header_only"],
+    shared_libs: [
+        "libcrypto",
+        "liblog",
+        "libssl",
+    ],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+// Unbundled Conscrypt jar
+java_library {
+    name: "conscrypt_unbundled",
+
+    srcs: [
+        "common/src/main/java/**/*.java",
+        "android/src/main/java/**/*.java",
+        ":conscrypt-nojarjar_generated_constants",
+    ],
+
+    libs: ["conscrypt-stubs"],
+
+    sdk_version: "current",
+    java_version: "1.7",
+}
+
+// Stub library for unbundled builds
+java_library {
+    name: "conscrypt-stubs",
+
+    srcs: ["android-stub/src/main/java/**/*.java"],
+
+    sdk_version: "current",
+    java_version: "1.7",
+}
+
+// Static unbundled Conscrypt crypto JNI library
+cc_library_static {
+    name: "libconscrypt_static",
+    defaults: ["libjavacrypto-defaults"],
+
+    cflags: [
+        "-DJNI_JARJAR_PREFIX=com/google/android/gms/",
+        "-DCONSCRYPT_UNBUNDLED",
+        "-DSTATIC_LIB",
+    ],
+
+    local_include_dirs: ["common/src/jni/unbundled/include"],
+
+    static_libs: [
+        "libssl",
+        "libcrypto",
+    ],
+    sdk_version: "9",
+    stl: "c++_shared",
+}
+
+// Make the conscrypt-tests library.
+java_test {
+    name: "conscrypt-tests",
+    visibility: [
+        "//cts/tests/libcore/luni",
+    ],
+    hostdex: true,
+    srcs: [
+        "repackaged/platform/src/test/java/**/*.java",
+        "repackaged/common/src/test/java/**/*.java",
+        "repackaged/openjdk-integ-tests/src/test/java/**/*.java",
+        "repackaged/testing/src/main/java/**/*.java",
+        "publicapi/src/test/java/**/*.java",
+    ],
+    java_resource_dirs: [
+        // Resource directories do not need repackaging.
+        "openjdk/src/test/resources",
+        "openjdk-integ-tests/src/test/resources",
+    ],
+
+    sdk_version: "none",
+    libs: [
+        "core-all",
+        "conscrypt",
+        "junit",
+        "mockito-target-minus-junit4",
+    ],
+    system_modules: "core-all-system-modules",
+
+    static_libs: [
+        "bouncycastle-unbundled",
+        "bouncycastle-bcpkix-unbundled",
+        "bouncycastle-ocsp-unbundled",
+    ],
+    javacflags: [
+        "-Xmaxwarns 9999999",
+        //"-Xlint:all",
+        //"-Xlint:-serial,-deprecation,-unchecked",
+    ],
+
+    required: ["libjavacrypto"],
+    java_version: "1.7",
+}
+
+// Make the conscrypt-benchmarks library.
+java_test {
+    name: "conscrypt-benchmarks",
+    srcs: [
+        "repackaged/testing/src/main/java/**/*.java",
+        "repackaged/benchmark-base/src/main/java/**/*.java",
+        "repackaged/benchmark-android/src/main/java/**/*.java",
+    ],
+    sdk_version: "none",
+    libs: [
+        "core-all",
+        "conscrypt",
+        "junit",
+        "bouncycastle-unbundled",
+        "bouncycastle-bcpkix-unbundled",
+        "bouncycastle-ocsp-unbundled",
+        "caliper-api-target",
+    ],
+    system_modules: "core-all-system-modules",
+
+    javacflags: [
+        "-Xmaxwarns 9999999",
+        //"-Xlint:all",
+        //"-Xlint:-serial,-deprecation,-unchecked",
+    ],
+
+    required: ["libjavacrypto"],
+    java_version: "1.7",
+}
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..105c94b
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,6 @@
+flooey@google.com
+kroot@google.com
+narayan@google.com
+nfuller@google.com
+prb@google.com
+tobiast@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 4c8d137..84d310f 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,4 @@
 [Builtin Hooks]
 commit_msg_test_field = true
 clang_format = true
+bpfmt = true
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..1b2919c
--- /dev/null
+++ b/README.android
@@ -0,0 +1,12 @@
+Conscrypt in Android is made up of the contents of the Conscrypt
+GitHub repo (https://github.com/google/conscrypt) plus some
+Android-specific additions.  Specifically, the following are
+Android-only:
+
+Android.bp
+OWNERS
+README.android
+apex/...
+publicapi/...
+repackaged/...
+srcgen/...
diff --git a/apex/Android.bp b/apex/Android.bp
new file mode 100644
index 0000000..129da6a
--- /dev/null
+++ b/apex/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2018 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.
+
+// Defaults shared between real and test versions of the APEX.
+apex_defaults {
+    name: "com.android.conscrypt-defaults",
+    androidManifest: ":com.android.conscrypt-androidManifest",
+    compile_multilib: "both",
+    java_libs: ["conscrypt"],
+    native_shared_libs: ["libjavacrypto"],
+    key: "apex.conscrypt.key",
+    certificate: ":com.android.conscrypt.certificate",
+}
+
+filegroup {
+    name: "com.android.conscrypt-androidManifest",
+    srcs: ["AndroidManifest.xml"],
+}
+
+apex_key {
+    name: "apex.conscrypt.key",
+    public_key: "com.android.conscrypt.avbpubkey",
+    private_key: "com.android.conscrypt.pem",
+}
+
+android_app_certificate {
+    name: "com.android.conscrypt.certificate",
+    certificate: "com.android.conscrypt",
+}
+
+// Production APEX
+apex {
+    name: "com.android.conscrypt",
+    defaults: ["com.android.conscrypt-defaults"],
+    manifest: "apex_manifest.json",
+}
diff --git a/apex/AndroidManifest.xml b/apex/AndroidManifest.xml
new file mode 100644
index 0000000..c25cc17
--- /dev/null
+++ b/apex/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="com.android.conscrypt">
+  <!-- APEX does not have classes.dex -->
+  <application android:hasCode="false" />
+  <!--
+    *  API levels the Conscrypt APEX is known to work with.
+    -->
+  <uses-sdk android:minSdkVersion="28" android:maxSdkVersion="28" />
+</manifest>
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
new file mode 100644
index 0000000..98222ad
--- /dev/null
+++ b/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.conscrypt",
+  "version": 1
+}
diff --git a/apex/com.android.conscrypt.avbpubkey b/apex/com.android.conscrypt.avbpubkey
new file mode 100644
index 0000000..5ce0fbd
--- /dev/null
+++ b/apex/com.android.conscrypt.avbpubkey
Binary files differ
diff --git a/apex/com.android.conscrypt.pem b/apex/com.android.conscrypt.pem
new file mode 100644
index 0000000..7979607
--- /dev/null
+++ b/apex/com.android.conscrypt.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEAwWI5g+8IxjlN9HY4tNVcE12z7CHRoD1EU7WUnPIJR/OeaIBm
+eDQIyfDSkcE+KQ8RbiRLHbp5xxbTvstNNt5l7cb3U6HWhNar8bEkGadSy8jer+BI
+Hn9UY14SeEh3TUfLA8VBU7H20k3lfpzvOCdzECMthqPryIx4DWK3Thir1qwak/3b
+nF5hXAUx6FJalZ3eEvZPtFy+qW/Xk6PFKfKybQCLTb/3n0ppegMCPAaWuqYT9GOz
+JKtDEqekIeEYdMIh+Lf29aVMQNusB+3Smb+t9ys1qk/Bz3CyXTej3A+m55btWW2i
+GE5j3fWvdIGsBOjoeBE7WkXnvbNEwjkRDYY/IS6kLq10Y1uhdwuHv0VpuIkrm7c/
+bazPF6z5CRLqgCrik/Y00xV7/osR9e9+ywfAhJL0NMuta1bfu0Veny6rC3PlxbhK
+4EbUaGzj4mWnIwqml15QxmQFjTVOrnqFs93kpb/3ZTtA53bR8wLKQph5/TJv6IMH
+BOAVHNxC73sCH2TlabFAHPnJzdsHcdvtOIHRp5EYdV++T4a9k1syKWGKStzyIAA2
+tZ434ca/YqQpa3m6+H9NTcJeR6cfP1repbJouNhnlTMl07ttcxFKss+mbcXJhi78
+rllwGrGqVGb2+mcY2cgvpYYo3xAwa5e3qrMkaThCxrXpdleDzh/8S+qrky0CAwEA
+AQKCAgA4g0vrkl8uDnEJj8LilbdisW9zAi8QdNcS322er9ymejtArsVDO3GWEhp3
+HdHcjdq6JUEOXwBXfgRDLYZTEosXAZ4lgpX+G/4Dk5DJLmyzwO/S1eg9gVhX8ZXU
+MNksbF6Xq317x/YpXzpB1frSnjSx8pXLUvwEj4hF4SNQX0VYZtMdjIIxICOzkJEV
+I3v1XT0YrYJ9Yt0VBuoo6yMjLxmVYSNUhVUH5+cLEPYGNKa3xPDv6nLftGzVdsgw
+XmeXN2RWGuzAvJ2cFpYfexCgfbOJF8eHDefFh1mYhDoOhURxSVnzWGaWU9I7eyDb
+G0n55VaKP/7oUqV2en0NhT/GhATOW21whRm5D34oJyWSqry5mxE3wxmwJUOcon4q
+oiRn5iBq7rnUoEAzEK1pgdTKSNxIkuGmWmo/b1n0oxCSmDS+VTp1nC6i0eZ7YXGX
+aYxnouJDcNICTOnqKo2DYEZ26jQzqw53gcdeP9NXYgRrSa1ZUT0malD/I0m1CLUl
+lwdu+VDEEmnA0FXbs9BNUzWZut1XBelz6MsDrbcNKte/2Ikk7OhpvGKdnw7rqpWW
+MEueusIcBGK7YABJlwheIpynQBtaVWGalAy3hi1bZC5NqT0xQP2V1536pljsai+t
+cdi98bn5bZa7OluZLTN1uLIKfIKjDbPt43vYYuh/qi0D7sa8wQKCAQEA6fYRE8Dw
+3dUhkitkLuhmpVsBrxjfic9d9ypgLd1u57chd7tc8HlKE8+tTY+AI4EvKUcEweiE
+eO/DAnYijZRNY89g9JZcur4exo79UvPnayWRVS4wCwf57DrvjxkDJS97vWZRI1ns
+MS9/bNtg2RCrfReHpSC4vxZAfH6Gmt1wfJZpVcOAPPqeZX19n6N7VkFSzhw8axAj
+Py3HG5uGvE3jhouiMG1vHiMumUdkOOxkc7cjMojujQ0XIVIso02/zQSKf6QUe6bl
+ZUJTkl1GHWkEFU0bmKylfwW9GVW1fxw2qjlrLWpWFaKrbgQptvae+K1zSfQsGXab
+w6mhDvdrtDKKJwKCAQEA05mjcqPcBN3E1BI57ylcsWlD/8pVsIeBmFzrng9JJ672
+P4iZ8IxkQO4Y8zoywYNTEkgeVvertghMIy+hFVW+/7dKlXPwZhurtY6FUzy79BA7
+CKJwSyPDWJY7ol0yGkv4ME5RQZ8fGw23him7RuNl1LKHQ2NIplS5ezhZUHa6ckHG
+yM1pRjy9H9TK6XtlsSME8gej3BmU9UsAMWhMBmz8UpYYX8SmgTJIwhcZ7eM3RbyG
+S7bmw5jrxe9v0RYBh0EuVkBm+iAIY8pvCL4imNu/sEmjaBDpyNSe/0DXxjHPydAZ
+K46n92I5gRF8GfeKJMuogZGagxUFXijYVsjN4FrwiwKCAQEAvIJUjisGqGajDwhB
+R35fvloOiEutSXe5CX6uUiY5xyAKKlPf9a50nnPV+klmgLUFD+g2EBtOKbdd1Czl
+eFgG5yXfxBMnEhw/5dKukFkPnIh/ijeV5D2ABPQTs6P+ocaZmCjJtYctxQ+1RzuX
+1C4XTspXtBgiY20Fdonn4P4NNYVnx/+m4vs4ByROxQLPTNeDZajgkY9GJxC2fisZ
+K75CVlVJ0GVMg+brE/uu6CKoaYglJwGn3CSw/1sbtlTd9s3y3heRnXQDH0yK08Kt
+zOKhtJwVYTWyfx9blv81Jv7PmOZ80fH8/J++Kv3VsqMRweLXor3Hjpi/tq6Fo+59
+bIrQPwKCAQEApInWuCFEyB/umv2lQRzHsEjrkG60nTVxh5nRubGnMA1z/Elrcsqo
+dnjuu8uohiNpKFEeDoA+bKkdE0tJFf78K3pKq9Zgu/WOWvp9IBGdEZbBYOB3M2aW
+0z7XFlUjzaD/WAi+VKm4FWBgMhonP2M53uAIIFWGu5gsNu3FPbVlG82cFq7ryqsW
+YTclpdLHa6uQf+eC+naGBwuQFdtFKsX6mvmN8IJI+zOvsgUmq33AkCCdyShrXvN9
+ewfJyiszeworTvR7Xsoj2/0gxAqdeoF+GEXao+Rq9jinflLctogrTIHd4KnoYIxn
+rL584vBC4oPe/wnKvV1OND7Mowc4V9o/KwKCAQEAxe9wolYg+mz64b4D3JGH4Vs1
+vmGUqpk/CjrYVR/oQ0AeZIpzCVr3bTREbAjrhm/80CXkKiUvFFHV91desQui3kSo
+JC4aMOfBF0ykHhTHnQUD2LffUO8IrXFkzDp8pLNSzj9pxAFwAzvYRsJalYv24x0N
+B2Ek6m/bkiRBGHpDryCwf9R7C3QYyZlWzNWCiPSEcPtCdmLIIsG7ZZ4IzDr6Uphi
+Uc+2xqOW19BeVNXu7gi4xGpsOh/lmQbgg5jmX+MwQutM4l7KVe+rEqJu6tFvZkq2
+MQRWfwuqlTnMMweYXordjyKeCMRU20tgxYeBnayny98mc8QT6ENi8p0d9PFulQ==
+-----END RSA PRIVATE KEY-----
diff --git a/apex/com.android.conscrypt.pk8 b/apex/com.android.conscrypt.pk8
new file mode 100644
index 0000000..4c04deb
--- /dev/null
+++ b/apex/com.android.conscrypt.pk8
Binary files differ
diff --git a/apex/com.android.conscrypt.x509.pem b/apex/com.android.conscrypt.x509.pem
new file mode 100644
index 0000000..ba914fa
--- /dev/null
+++ b/apex/com.android.conscrypt.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF1DCCA7ygAwIBAgIJAN0lMAb+9i0JMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMR4wHAYDVQQD
+DBVjb20uYW5kcm9pZC5jb25zY3J5cHQwIBcNMTkwMTI1MTcxNjM3WhgPNDc1NjEy
+MjExNzE2MzdaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYw
+FAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQL
+DAdBbmRyb2lkMR4wHAYDVQQDDBVjb20uYW5kcm9pZC5jb25zY3J5cHQwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCcfdThwuWhAk0362p7+s/8xL0Hi6Fe
+orQL30Kat8iK4ZPWM5HxOY1zmktBzjgKQ0qM4fuvHzrQJr2+SLl+l2miX4XTruAL
+w7MBS1EGzh0YC4cOBq9z8IsAW/lB6MDeAJ6TuflTk5BRun+bDB70IkWd0ylYSiTi
+AWEs4LM03rBbTcxpNuoLMj1PDNkNOmWiu0rtRbO2Y5+GI9Kw2lyPsWKkU0ixifq2
+o3gHAepmwD7bt5tDFSuOW+uCeF7TzyqsE/CFvqWYUn+5rlOlcyFARAgCh1NZXqxq
+mkcyI9vmtneIUimYw0dzgNoG0dijYAvpuQgSr0HSa2JBiQOgMrJug2PtmWpH2PNk
+UubVZYSfPiO4wTB9Jus63Y27KRdo4Bz4R4n/u0FjIi/cu0Zms07MTo60NPaGHNM/
+nMJSEDDjQ7ppoPXsamn0DID8HlZMivmcQgzokWswxw4b/i1O2fUotKEDf3wvJhUB
+4U7bAgF55FNWWfcaHYqhytWc0qO4zdMUyVqFF+/Db3hz4IkhJyzjCYxBovSSx4yN
+atHa93SwM+uH1s2iI3gOJbn/SrsfKbkrU85S5zVRDEOQg9lm2d99PMnXqXED7bRw
+G9pKmUfOzMANm8yhvL/urlSXVDHxtdw+IJGSVUlzYT3OAx2eFdnpiymiQyWotr8W
+IXfOyr/lB6IkvQIDAQABo1MwUTAdBgNVHQ4EFgQU/vXb6Hy1AxgAxhDuwnO457cD
+3+owHwYDVR0jBBgwFoAU/vXb6Hy1AxgAxhDuwnO457cD3+owDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEARVpJBLitmnJXL/suxt+IsszEBz/pj5g1
+uwor1L3Zvb8j614BhqrKFlPia3PKlHJHotNugjs35CrQ6S4zC3Dx3R2Wb/hBOhtk
+bfpjKZuWaPvqHx1nlBsRa6H7tOKOW/6DHkkb/L5oJo7FPZT0Y0XNandFAmveBL69
+CLZS5dFnhkbVHi7PuvSwcFEXSr/fozcIMnCsQAds42cWqlWlDDVq90vYzOM+jQxS
+cctJ3cZiL0heWEyiZmG0J95Z6kB28gEmaDw8LNUwaUsyaO7U6GwXIe/KQvI2cT/F
+yjpkBmKqDr89Xvyd9DYtZv8GbndTQLwyrPhlKLNOoly3jqjbxqAZGBpyxwVDU+Mo
+/NwkCheQeEYLrGXBgv9fLfyOLSZA7yihPTc0IQcm27DnpkZmJ/lWJ5jDG0VEkNp+
+60O5GYCs2/r3tO+YoiDSFNjsFgCoTcnOQwYhbBZC7YJLOKV0lYDjfsohE6tcCUuS
+H8Ln6Em9HhFAXZBVQU0N+OyC0bAuDTD72ClvbMQikyeWwhdvY3F0x5dDima0liqe
+0jMTJxlizLoa2YKOiLqLomLt6+sJawF0+bGSKSHpcy0NoopXTb3UBlkFpxRp9UnN
+vrnN6KyRzj7OssDEHfXSZgSR0ZAVrAsgP3vc+lBpze9jtNbITDV1gOxUBX771hdU
+UIxewtyODcY=
+-----END CERTIFICATE-----
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
new file mode 100644
index 0000000..12c2756
--- /dev/null
+++ b/apex/testing/Android.bp
@@ -0,0 +1,22 @@
+// Copyright (C) 2019 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.
+
+apex {
+    name: "test_com.android.conscrypt",
+    defaults: ["com.android.conscrypt-defaults"],
+    manifest: "test_apex_manifest.json",
+    file_contexts: "com.android.conscrypt",
+    // Test APEX, should never be installed
+    installable: false,
+}
diff --git a/apex/testing/test_apex_manifest.json b/apex/testing/test_apex_manifest.json
new file mode 100644
index 0000000..97d7cf5
--- /dev/null
+++ b/apex/testing/test_apex_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.conscrypt",
+  "version": 2147483647
+}
diff --git a/constants/src/gen/cpp/generate_constants.cc b/constants/src/gen/cpp/generate_constants.cc
index 894a1fa..bd1e995 100644
--- a/constants/src/gen/cpp/generate_constants.cc
+++ b/constants/src/gen/cpp/generate_constants.cc
@@ -40,10 +40,16 @@
     " * See the License for the specific language governing permissions and\n"
     " * limitations under the License. */\n";
 
-int main(int /* argc */, char ** /* argv */) {
+int main(int argc, char **argv) {
+  const char *package;
+  if (argc == 1) {
+    package = "org.conscrypt";
+  } else {
+    package = argv[1];
+  }
   printf("%s\n", kCopyright);
   printf("/* This file was generated by generate_constants.cc. */\n\n");
-  printf("package org.conscrypt;\n\n");
+  printf("package %s;\n\n", package);
   printf("final class NativeConstants {\n");
 
 #define CONST(x) \
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestAES.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestAES.java
index 49b9d23..d79dacb 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestAES.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestAES.java
@@ -18,18 +18,38 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
+import dalvik.system.VMRuntime;
 import java.security.AlgorithmParameters;
 import java.security.Provider;
 import javax.crypto.spec.IvParameterSpec;
 import org.conscrypt.TestUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class AlgorithmParametersTestAES extends AbstractAlgorithmParametersTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     private static final byte[] parameterData = new byte[] {
         (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
         (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestDESede.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestDESede.java
index a0e8581..8af454b 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestDESede.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestDESede.java
@@ -18,18 +18,38 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
+import dalvik.system.VMRuntime;
 import java.security.AlgorithmParameters;
 import java.security.Provider;
 import javax.crypto.spec.IvParameterSpec;
 import org.conscrypt.TestUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class AlgorithmParametersTestDESede extends AbstractAlgorithmParametersTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     private static final byte[] parameterData = new byte[] {
         (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
         (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestGCM.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestGCM.java
index 1c435d3..72b1d23 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestGCM.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestGCM.java
@@ -19,18 +19,38 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import dalvik.system.VMRuntime;
 import java.security.AlgorithmParameters;
 import java.security.Provider;
 import javax.crypto.spec.GCMParameterSpec;
 import org.conscrypt.TestUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class AlgorithmParametersTestGCM extends AbstractAlgorithmParametersTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     private static final byte[] IV = new byte[] {
         (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
         (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java
index fb97173..4a847bd 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
+import dalvik.system.VMRuntime;
 import java.security.AlgorithmParameters;
 import java.security.Provider;
 import java.security.spec.MGF1ParameterSpec;
@@ -25,14 +26,33 @@
 import javax.crypto.spec.PSource;
 import javax.crypto.spec.PSource.PSpecified;
 import org.conscrypt.TestUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class AlgorithmParametersTestOAEP extends AbstractAlgorithmParametersTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+            Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     // The ASN.1 encoding for OAEP params (specified in RFC 4055 section 4.1) specifies
     // default values for all parameters, so we need to consider encodings with those
     // values both explicitly specified and unspecified.  When encoding values, it is required
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java
index b2ccc51..f8df5ad 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java
@@ -54,14 +54,37 @@
 import javax.crypto.interfaces.DHPublicKey;
 import javax.crypto.spec.DHParameterSpec;
 import org.conscrypt.TestUtils;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import dalvik.system.VMRuntime;
+import sun.security.jca.Providers;
+import org.junit.Test;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class KeyPairGeneratorTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     @Test
     public void test_getInstance() throws Exception {
         ServiceTester.test("KeyPairGenerator")
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/MessageDigestTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/MessageDigestTest.java
index 599b3f4..880fc38 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/MessageDigestTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/MessageDigestTest.java
@@ -24,15 +24,36 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+import dalvik.system.VMRuntime;
 import org.conscrypt.TestUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public final class MessageDigestTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     private final byte[] sha_456 = {
             -24,   9, -59, -47,  -50,  -92, 123, 69, -29,  71,
               1, -46,  63,  96, -118, -102,  88,  3,  77, -55
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/SignatureTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/SignatureTest.java
index 7d4584b..ecb51ed 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/SignatureTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/SignatureTest.java
@@ -68,16 +68,37 @@
 import java.util.concurrent.TimeUnit;
 import org.conscrypt.Conscrypt;
 import org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
 import org.conscrypt.testing.BrokenProvider;
 import org.conscrypt.testing.OpaqueProvider;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class SignatureTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     // 20 bytes for DSA
     private final byte[] DATA = new byte[20];
 
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java
index 82b8a45..40e88fe 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java
@@ -63,14 +63,34 @@
 import org.conscrypt.Conscrypt;
 import org.conscrypt.TestUtils;
 import org.conscrypt.java.security.StandardNames;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import dalvik.system.VMRuntime;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class CertificateFactoryTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     private static final String VALID_CERTIFICATE_PEM =
             "-----BEGIN CERTIFICATE-----\n"
             + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\n"
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java
index 6fb84f5..a0068cf 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java
@@ -27,15 +27,35 @@
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertificateParsingException;
+import org.junit.AfterClass;
+import dalvik.system.VMRuntime;
 import java.security.cert.X509Certificate;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class X509CertificateTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     private static final String VALID_CERT =
             "-----BEGIN CERTIFICATE-----\n"
             + "MIIFMjCCAxqgAwIBAgIJAL0mG5fOeJ7xMA0GCSqGSIb3DQEBCwUAMC0xCzAJBgNV\n"
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/CipherTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
index 14af965..983ba06 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
@@ -74,15 +74,34 @@
 import org.conscrypt.TestUtils;
 import org.conscrypt.java.security.StandardNames;
 import org.conscrypt.java.security.TestKeyStore;
+import org.junit.AfterClass;
 import org.junit.Assume;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import dalvik.system.VMRuntime;
+import sun.security.jca.Providers;
 
 @RunWith(JUnit4.class)
 public final class CipherTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     @BeforeClass
     public static void setUp() {
         TestUtils.assumeAllowsUnsignedCrypto();
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java
index 94ddbc5..5699461 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java
@@ -52,10 +52,13 @@
 import junit.framework.AssertionFailedError;
 import org.conscrypt.Conscrypt;
 import org.conscrypt.TestUtils;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import dalvik.system.VMRuntime;
+import sun.security.jca.Providers;
 
 /**
  * Tests for all registered Elliptic Curve Diffie-Hellman {@link KeyAgreement} providers.
@@ -63,6 +66,22 @@
 @RunWith(JUnit4.class)
 public class ECDHKeyAgreementTest {
 
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
     // Two key pairs and the resulting shared secret for the Known Answer Test
     private static final byte[] KAT_PUBLIC_KEY1_X509 = TestUtils.decodeHex(
             "3059301306072a8648ce3d020106082a8648ce3d030107034200049fc2f71f85446b1371244491d83"
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/KeyGeneratorTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/KeyGeneratorTest.java
index 4ebafb7..2685cef 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/KeyGeneratorTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/crypto/KeyGeneratorTest.java
@@ -29,14 +29,33 @@
 import javax.crypto.SecretKey;
 import org.conscrypt.TestUtils;
 import org.conscrypt.java.security.StandardNames;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
+import dalvik.system.VMRuntime;
+import sun.security.jca.Providers;
 import tests.util.ServiceTester;
 
 @RunWith(JUnit4.class)
 public class KeyGeneratorTest {
+    
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
 
     private static boolean isUnsupported(KeyGenerator kg) {
         // Don't bother testing "Sun..." KeyGenerators or BC outside of Android
diff --git a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/net/ssl/SSLEngineTest.java b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/net/ssl/SSLEngineTest.java
index 63fc3f5..4b02e0a 100644
--- a/openjdk-integ-tests/src/test/java/org/conscrypt/javax/net/ssl/SSLEngineTest.java
+++ b/openjdk-integ-tests/src/test/java/org/conscrypt/javax/net/ssl/SSLEngineTest.java
@@ -31,6 +31,7 @@
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 import javax.net.ssl.KeyManager;
@@ -583,8 +584,14 @@
                         // By the point of the handshake where we're validating certificates,
                         // the hostname is known and the cipher suite should be agreed
                         assertEquals(referenceContext.host.getHostName(), session.getPeerHost());
-                        assertEquals(referenceEngine.getEnabledCipherSuites()[0],
-                            session.getCipherSuite());
+                        String sessionSuite = session.getCipherSuite();
+                        List<String> enabledSuites =
+                                Arrays.asList(referenceEngine.getEnabledCipherSuites());
+                        String message = "Handshake session has invalid cipher suite: "
+                                + (sessionSuite == null ? "(null)" : sessionSuite);
+                        assertTrue("Expected enabled suites to contain " + sessionSuite
+                                        + ", got: " + enabledSuites,
+                                enabledSuites.contains(sessionSuite));
                         wasCalled[0] = true;
                     } catch (Exception e) {
                         throw new CertificateException("Something broke", e);
diff --git a/openjdk/src/test/java/org/conscrypt/OpenSSLServerSocketImplTest.java b/openjdk/src/test/java/org/conscrypt/OpenSSLServerSocketImplTest.java
new file mode 100644
index 0000000..1618e8a
--- /dev/null
+++ b/openjdk/src/test/java/org/conscrypt/OpenSSLServerSocketImplTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2017 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.conscrypt;
+
+import static org.conscrypt.TestUtils.LOCALHOST;
+import static org.conscrypt.TestUtils.getConscryptServerSocketFactory;
+import static org.conscrypt.TestUtils.getJdkSocketFactory;
+import static org.conscrypt.TestUtils.getProtocols;
+import static org.conscrypt.TestUtils.newTextMessage;
+import static org.conscrypt.TestUtils.pickUnusedPort;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class OpenSSLServerSocketImplTest {
+    private static final String CIPHER = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+    private static final int MESSAGE_SIZE = 4096;
+
+    /**
+     * Various factories for SSL server sockets.
+     */
+    public enum SocketType {
+        DEFAULT(getConscryptServerSocketFactory(false)),
+        ENGINE(getConscryptServerSocketFactory(true));
+
+        @SuppressWarnings("ImmutableEnumChecker")
+        private final SSLServerSocketFactory serverSocketFactory;
+
+        SocketType(SSLServerSocketFactory serverSocketFactory) {
+            this.serverSocketFactory = serverSocketFactory;
+        }
+
+        final SSLServerSocket newServerSocket(String cipher) {
+            try {
+                int port = pickUnusedPort();
+                SSLServerSocket sslSocket =
+                        (SSLServerSocket) serverSocketFactory.createServerSocket(port);
+                sslSocket.setEnabledProtocols(getProtocols());
+                sslSocket.setEnabledCipherSuites(new String[] {cipher});
+                return sslSocket;
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Parameters(name = "{0}")
+    public static Iterable<SocketType> data() {
+        // Android-changed: Temporarily (2017 Q2) disable ENGINE tests. http://b/37271061#comment9
+        // This experimental (unused by default) implementation is unstable and causing test
+        // failures on Android.
+        // return Arrays.asList(SocketType.DEFAULT, SocketType.ENGINE);
+        return Arrays.asList(SocketType.DEFAULT);
+    }
+
+    @Parameter public SocketType socketType;
+
+    private TestClient client;
+    private TestServer server;
+
+    @Before
+    public void setup() throws Exception {
+        // Create and start the server.
+        server = new TestServer(socketType.newServerSocket(CIPHER), MESSAGE_SIZE);
+        Future<?> connectedFuture = server.start();
+
+        // Create and start the client.
+        SSLSocketFactory socketFactory = getJdkSocketFactory();
+        SSLSocket socket = (SSLSocket) socketFactory.createSocket(LOCALHOST, server.port());
+        socket.setEnabledProtocols(getProtocols());
+        socket.setEnabledCipherSuites(new String[] {CIPHER});
+        client = new TestClient(socket);
+        client.start();
+
+        // Wait for the initial connection to complete.
+        connectedFuture.get(5, TimeUnit.SECONDS);
+    }
+
+    @After
+    public void teardown() throws Exception {
+        client.stop();
+        server.stop();
+    }
+
+    @Test
+    public void pingPong() throws IOException {
+        byte[] request = newTextMessage(MESSAGE_SIZE);
+        byte[] responseBuffer = new byte[MESSAGE_SIZE];
+        client.sendMessage(request);
+        client.flush();
+        int numBytes = client.readMessage(responseBuffer);
+        byte[] response = Arrays.copyOfRange(responseBuffer, 0, numBytes);
+        assertArrayEquals(request, response);
+    }
+}
diff --git a/publicapi/src/main/java/android/net/ssl/SSLEngines.java b/publicapi/src/main/java/android/net/ssl/SSLEngines.java
new file mode 100644
index 0000000..13bd771
--- /dev/null
+++ b/publicapi/src/main/java/android/net/ssl/SSLEngines.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 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 android.net.ssl;
+
+import com.android.org.conscrypt.Conscrypt;
+import javax.net.ssl.SSLEngine;
+import libcore.util.NonNull;
+
+/**
+ * Static utility methods for accessing additional functionality of supported instances of
+ * {@link SSLEngine}.  Engines from the platform TLS provider will be compatible with all
+ * methods in this class.
+ */
+public class SSLEngines {
+    private SSLEngines() {}
+
+    /**
+     * Returns whether the given engine can be used with the methods in this class.  In general,
+     * only engines from the platform TLS provider are supported.
+     */
+    public static boolean isSupportedEngine(@NonNull SSLEngine engine) {
+        return Conscrypt.isConscrypt(engine);
+    }
+
+    private static void checkSupported(@NonNull SSLEngine e) {
+        if (!isSupportedEngine(e)) {
+            throw new IllegalArgumentException("Engine is not a supported engine.");
+        }
+    }
+
+    /**
+     * Enables or disables the use of session tickets.
+     *
+     * <p>This function must be called before the handshake is started or it will have no effect.
+     *
+     * @param engine the engine
+     * @param useSessionTickets whether to enable or disable the use of session tickets
+     * @throws IllegalArgumentException if the given engine is not a platform engine
+     */
+    public static void setUseSessionTickets(@NonNull SSLEngine engine, boolean useSessionTickets) {
+        checkSupported(engine);
+        Conscrypt.setUseSessionTickets(engine, useSessionTickets);
+    }
+}
diff --git a/publicapi/src/main/java/android/net/ssl/SSLSockets.java b/publicapi/src/main/java/android/net/ssl/SSLSockets.java
new file mode 100644
index 0000000..a669404
--- /dev/null
+++ b/publicapi/src/main/java/android/net/ssl/SSLSockets.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 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 android.net.ssl;
+
+import com.android.org.conscrypt.Conscrypt;
+import javax.net.ssl.SSLSocket;
+import libcore.util.NonNull;
+
+/**
+ * Static utility methods for accessing additional functionality of supported instances of
+ * {@link SSLSocket}.  Sockets from the platform TLS provider will be compatible with all
+ * methods in this class.
+ */
+public class SSLSockets {
+    private SSLSockets() {}
+
+    /**
+     * Returns whether the given socket can be used with the methods in this class.  In general,
+     * only sockets from the platform TLS provider are supported.
+     */
+    public static boolean isSupportedSocket(@NonNull SSLSocket socket) {
+        return Conscrypt.isConscrypt(socket);
+    }
+
+    private static void checkSupported(@NonNull SSLSocket s) {
+        if (!isSupportedSocket(s)) {
+            throw new IllegalArgumentException("Socket is not a supported socket.");
+        }
+    }
+
+    /**
+     * Enables or disables the use of session tickets.
+     *
+     * <p>This function must be called before the handshake is started or it will have no effect.
+     *
+     * @param socket the socket
+     * @param useSessionTickets whether to enable or disable the use of session tickets
+     * @throws IllegalArgumentException if the given socket is not a platform socket
+     */
+    public static void setUseSessionTickets(@NonNull SSLSocket socket, boolean useSessionTickets) {
+        checkSupported(socket);
+        Conscrypt.setUseSessionTickets(socket, useSessionTickets);
+    }
+}
diff --git a/publicapi/src/test/java/android/net/ssl/SSLEnginesTest.java b/publicapi/src/test/java/android/net/ssl/SSLEnginesTest.java
new file mode 100644
index 0000000..66abec6
--- /dev/null
+++ b/publicapi/src/test/java/android/net/ssl/SSLEnginesTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 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 android.net.ssl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.tlswire.TlsTester;
+import com.android.org.conscrypt.tlswire.handshake.ClientHello;
+import com.android.org.conscrypt.tlswire.handshake.HelloExtension;
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SSLEnginesTest {
+
+    private static class BrokenSSLEngine extends SSLEngine {
+        @Override public SSLEngineResult wrap(ByteBuffer[] byteBuffers, int i, int i1,
+                ByteBuffer byteBuffer) throws SSLException { throw new AssertionError(); }
+        @Override public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers,
+                int i, int i1) throws SSLException { throw new AssertionError(); }
+        @Override public Runnable getDelegatedTask() { throw new AssertionError(); }
+        @Override public void closeInbound() throws SSLException { throw new AssertionError(); }
+        @Override public boolean isInboundDone() { throw new AssertionError(); }
+        @Override public void closeOutbound() { throw new AssertionError(); }
+        @Override public boolean isOutboundDone() { throw new AssertionError(); }
+        @Override public String[] getSupportedCipherSuites() { throw new AssertionError(); }
+        @Override public String[] getEnabledCipherSuites() { throw new AssertionError(); }
+        @Override public void setEnabledCipherSuites(String[] strings) { throw new AssertionError(); }
+        @Override public String[] getSupportedProtocols() { throw new AssertionError(); }
+        @Override public String[] getEnabledProtocols() { throw new AssertionError(); }
+        @Override public void setEnabledProtocols(String[] strings) { throw new AssertionError(); }
+        @Override public SSLSession getSession() { throw new AssertionError(); }
+        @Override public void beginHandshake() throws SSLException { throw new AssertionError(); }
+        @Override public SSLEngineResult.HandshakeStatus getHandshakeStatus() { throw new AssertionError(); }
+        @Override public void setUseClientMode(boolean b) { throw new AssertionError(); }
+        @Override public boolean getUseClientMode() { throw new AssertionError(); }
+        @Override public void setNeedClientAuth(boolean b) { throw new AssertionError(); }
+        @Override public boolean getNeedClientAuth() { throw new AssertionError(); }
+        @Override public void setWantClientAuth(boolean b) { throw new AssertionError(); }
+        @Override public boolean getWantClientAuth() { throw new AssertionError(); }
+        @Override public void setEnableSessionCreation(boolean b) { throw new AssertionError(); }
+        @Override public boolean getEnableSessionCreation() { throw new AssertionError(); }
+    }
+
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
+
+    @Test
+    public void testIsSupported() throws Exception {
+        SSLEngine e = SSLContext.getDefault().createSSLEngine();
+        assertTrue(SSLEngines.isSupportedEngine(e));
+
+        e = new BrokenSSLEngine();
+        assertFalse(SSLEngines.isSupportedEngine(e));
+    }
+
+    @Test
+    public void testUseSessionTickets() throws Exception {
+        try {
+            SSLEngines.setUseSessionTickets(new BrokenSSLEngine(), true);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        SSLEngine e = SSLContext.getDefault().createSSLEngine();
+        e.setUseClientMode(true);
+        SSLEngines.setUseSessionTickets(e, true);
+
+        ClientHello hello = getClientHello(e);
+        assertNotNull(hello.findExtensionByType(HelloExtension.TYPE_SESSION_TICKET));
+
+        e = SSLContext.getDefault().createSSLEngine();
+        e.setUseClientMode(true);
+        SSLEngines.setUseSessionTickets(e, false);
+
+        hello = getClientHello(e);
+        assertNull(hello.findExtensionByType(HelloExtension.TYPE_SESSION_TICKET));
+    }
+
+    private static ClientHello getClientHello(SSLEngine e) throws Exception {
+        ByteBuffer out = ByteBuffer.allocate(64 * 1024);
+
+        e.wrap(EMPTY_BUFFER, out);
+        out.flip();
+        byte[] data = new byte[out.limit()];
+        out.get(data);
+
+        return TlsTester.parseClientHello(data);
+    }
+}
diff --git a/publicapi/src/test/java/android/net/ssl/SSLSocketsTest.java b/publicapi/src/test/java/android/net/ssl/SSLSocketsTest.java
new file mode 100644
index 0000000..02df047
--- /dev/null
+++ b/publicapi/src/test/java/android/net/ssl/SSLSocketsTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 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 android.net.ssl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.tlswire.TlsTester;
+import com.android.org.conscrypt.tlswire.handshake.ClientHello;
+import com.android.org.conscrypt.tlswire.handshake.HelloExtension;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import tests.net.DelegatingSSLSocketFactory;
+
+@RunWith(JUnit4.class)
+public class SSLSocketsTest {
+
+    private static class BrokenSSLSocket extends SSLSocket {
+        @Override public String[] getSupportedCipherSuites() { throw new AssertionError(); }
+        @Override public String[] getEnabledCipherSuites() { throw new AssertionError(); }
+        @Override public void setEnabledCipherSuites(String[] strings) { throw new AssertionError(); }
+        @Override public String[] getSupportedProtocols() { throw new AssertionError(); }
+        @Override public String[] getEnabledProtocols() { throw new AssertionError(); }
+        @Override public void setEnabledProtocols(String[] strings) { throw new AssertionError(); }
+        @Override public SSLSession getSession() { throw new AssertionError(); }
+        @Override public void addHandshakeCompletedListener(
+                HandshakeCompletedListener handshakeCompletedListener) { throw new AssertionError(); }
+        @Override public void removeHandshakeCompletedListener(
+                HandshakeCompletedListener handshakeCompletedListener) { throw new AssertionError(); }
+        @Override public void startHandshake() { throw new AssertionError(); }
+        @Override public void setUseClientMode(boolean b) { throw new AssertionError(); }
+        @Override public boolean getUseClientMode() { throw new AssertionError(); }
+        @Override public void setNeedClientAuth(boolean b) { throw new AssertionError(); }
+        @Override public boolean getNeedClientAuth() { throw new AssertionError(); }
+        @Override public void setWantClientAuth(boolean b) { throw new AssertionError(); }
+        @Override public boolean getWantClientAuth() { throw new AssertionError(); }
+        @Override public void setEnableSessionCreation(boolean b) { throw new AssertionError(); }
+        @Override public boolean getEnableSessionCreation() { throw new AssertionError(); }
+    }
+
+    private ExecutorService executor;
+
+    @Before
+    public void setUp() {
+        executor = Executors.newCachedThreadPool();
+    }
+
+    @After
+    public void tearDown() throws InterruptedException {
+        executor.shutdown();
+        executor.awaitTermination(1, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testIsSupported() throws Exception {
+        SSLSocket s = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
+        assertTrue(SSLSockets.isSupportedSocket(s));
+
+        s = new BrokenSSLSocket();
+        assertFalse(SSLSockets.isSupportedSocket(s));
+    }
+
+    @Test
+    public void testUseSessionTickets() throws Exception {
+        try {
+            SSLSockets.setUseSessionTickets(new BrokenSSLSocket(), true);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        SSLSocket s = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
+        SSLSockets.setUseSessionTickets(s, true);
+
+        ClientHello hello = TlsTester.captureTlsHandshakeClientHello(executor,
+                new DelegatingSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault()) {
+                    @Override public SSLSocket configureSocket(SSLSocket socket) {
+                        SSLSockets.setUseSessionTickets(socket, true);
+                        return socket;
+                    }
+                });
+        assertNotNull(hello.findExtensionByType(HelloExtension.TYPE_SESSION_TICKET));
+
+        hello = TlsTester.captureTlsHandshakeClientHello(executor,
+                new DelegatingSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault()) {
+                    @Override public SSLSocket configureSocket(SSLSocket socket) {
+                        SSLSockets.setUseSessionTickets(socket, false);
+                        return socket;
+                    }
+                });
+        assertNull(hello.findExtensionByType(HelloExtension.TYPE_SESSION_TICKET));
+    }
+}
diff --git a/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/AndroidEndpointFactory.java b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/AndroidEndpointFactory.java
new file mode 100644
index 0000000..321c908
--- /dev/null
+++ b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/AndroidEndpointFactory.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.security.Provider;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * Utility for creating test client and server instances.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("ImmutableEnumChecker")
+public enum AndroidEndpointFactory implements EndpointFactory {
+  @SuppressWarnings("unused")
+  CONSCRYPT(newConscryptFactories(false)),
+  CONSCRYPT_ENGINE(newConscryptFactories(true));
+
+  private final Factories factories;
+
+  AndroidEndpointFactory(Factories factories) {
+    this.factories = factories;
+  }
+
+  @Override
+  public ClientEndpoint newClient(ChannelType channelType, int port, String[] protocols,
+      String[] ciphers) throws IOException {
+    return new ClientEndpoint(
+        factories.clientFactory, channelType, port, protocols, ciphers);
+  }
+
+  @Override
+  public ServerEndpoint newServer(ChannelType channelType, int messageSize,
+      String[] protocols, String[] ciphers) throws IOException {
+    return new ServerEndpoint(factories.serverFactory, factories.serverSocketFactory,
+        channelType, messageSize, protocols, ciphers);
+  }
+
+  private static final class Factories {
+    final SSLSocketFactory clientFactory;
+    final SSLSocketFactory serverFactory;
+    final SSLServerSocketFactory serverSocketFactory;
+
+    private Factories(SSLSocketFactory clientFactory, SSLSocketFactory serverFactory,
+        SSLServerSocketFactory serverSocketFactory) {
+      this.clientFactory = clientFactory;
+      this.serverFactory = serverFactory;
+      this.serverSocketFactory = serverSocketFactory;
+    }
+  }
+
+  private static Factories newConscryptFactories(boolean useEngineSocket) {
+    Provider provider = TestUtils.getConscryptProvider();
+    SSLContext clientContext = TestUtils.newClientSslContext(provider);
+    SSLContext serverContext = TestUtils.newServerSslContext(provider);
+    final SSLSocketFactory clientFactory = clientContext.getSocketFactory();
+    final SSLSocketFactory serverFactory = serverContext.getSocketFactory();
+    final SSLServerSocketFactory serverSocketFactory = serverContext.getServerSocketFactory();
+    TestUtils.setUseEngineSocket(clientFactory, useEngineSocket);
+    TestUtils.setUseEngineSocket(serverFactory, useEngineSocket);
+    TestUtils.setUseEngineSocket(serverSocketFactory, useEngineSocket);
+    return new Factories(clientFactory, serverFactory, serverSocketFactory);
+  }
+}
diff --git a/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/AndroidEngineFactory.java b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/AndroidEngineFactory.java
new file mode 100644
index 0000000..4978114
--- /dev/null
+++ b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/AndroidEngineFactory.java
@@ -0,0 +1,103 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.security.Security;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Enumeration of various types of engines for use with engine-based benchmarks.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings({"ImmutableEnumChecker", "unused"})
+public enum AndroidEngineFactory implements EngineFactory {
+    CONSCRYPT_UNPOOLED {
+        private final SSLContext clientContext = newConscryptClientContext();
+        private final SSLContext serverContext = newConscryptServerContext();
+
+        @Override
+        public SSLEngine newClientEngine(String cipher, boolean useAlpn) {
+            SSLEngine engine = initEngine(clientContext.createSSLEngine(), cipher, true);
+            if (useAlpn) {
+                Conscrypt.setApplicationProtocols(engine, new String[] {"h2"});
+            }
+            return engine;
+        }
+
+        @Override
+        public SSLEngine newServerEngine(String cipher, boolean useAlpn) {
+            SSLEngine engine = initEngine(serverContext.createSSLEngine(), cipher, false);
+            if (useAlpn) {
+                Conscrypt.setApplicationProtocols(engine, new String[] {"h2"});
+            }
+            return engine;
+        }
+
+        @Override
+        public void dispose(SSLEngine engine) {
+            engine.closeOutbound();
+        }
+    },
+    PLATFORM {
+        private final SSLContext clientContext =
+                TestUtils.newClientSslContext(Security.getProvider("AndroidOpenSSL"));
+        private final SSLContext serverContext =
+                TestUtils.newServerSslContext(Security.getProvider("AndroidOpenSSL"));
+
+        @Override
+        public SSLEngine newClientEngine(String cipher, boolean useAlpn) {
+            SSLEngine engine = initEngine(clientContext.createSSLEngine(), cipher, true);
+            if (useAlpn) {
+                Conscrypt.setApplicationProtocols(engine, new String[] {"h2"});
+            }
+            return engine;
+        }
+
+        @Override
+        public SSLEngine newServerEngine(String cipher, boolean useAlpn) {
+            SSLEngine engine = initEngine(serverContext.createSSLEngine(), cipher, false);
+            if (useAlpn) {
+                Conscrypt.setApplicationProtocols(engine, new String[] {"h2"});
+            }
+            return engine;
+        }
+
+        @Override
+        public void dispose(SSLEngine engine) {
+            engine.closeOutbound();
+        }
+    };
+
+    @Override
+    public void dispose(SSLEngine engine) {}
+
+    private static SSLContext newConscryptClientContext() {
+        return TestUtils.newClientSslContext(TestUtils.getConscryptProvider());
+    }
+
+    private static SSLContext newConscryptServerContext() {
+        return TestUtils.newServerSslContext(TestUtils.getConscryptProvider());
+    }
+
+    static SSLEngine initEngine(SSLEngine engine, String cipher, boolean client) {
+        engine.setEnabledProtocols(new String[]{"TLSv1.2"});
+        engine.setEnabledCipherSuites(new String[] {cipher});
+        engine.setUseClientMode(client);
+        return engine;
+    }
+}
diff --git a/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperAlpnBenchmark.java b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperAlpnBenchmark.java
new file mode 100644
index 0000000..c181662
--- /dev/null
+++ b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperAlpnBenchmark.java
@@ -0,0 +1,87 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import com.android.org.conscrypt.EngineHandshakeBenchmark.Config;
+
+/**
+ * Cipher benchmarks. Only runs on AES currently because of the combinatorial
+ * explosion of the test as it stands.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("unused")
+public class CaliperAlpnBenchmark {
+    private final CaliperConfig config = new CaliperConfig();
+
+    @Param({TestUtils.TEST_CIPHER})
+    public String a_cipher;
+
+    @Param
+    public BufferType b_buffer;
+
+    @Param({"CONSCRYPT_UNPOOLED"}) public AndroidEngineFactory c_engine;
+
+    private EngineHandshakeBenchmark benchmark;
+
+    @BeforeExperiment
+    public void setUp() throws Exception {
+        benchmark = new EngineHandshakeBenchmark(config);
+    }
+
+    @Benchmark
+    public void timeHandshake(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            benchmark.handshake();
+        }
+    }
+
+    private final class CaliperConfig implements Config {
+        @Override
+        public BufferType bufferType() {
+            return b_buffer;
+        }
+
+        @Override
+        public EngineFactory engineFactory() {
+            return c_engine;
+        }
+
+        @Override
+        public String cipher() {
+            return a_cipher;
+        }
+
+        @Override
+        public boolean useAlpn() {
+            return true;
+        }
+
+        @Override
+        public BenchmarkProtocol protocol() {
+            return BenchmarkProtocol.TLSv12;
+        }
+
+        @Override
+        public int rttMillis() {
+            return 0;
+        }
+    }
+}
diff --git a/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperClientSocketBenchmark.java b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperClientSocketBenchmark.java
new file mode 100644
index 0000000..c444952
--- /dev/null
+++ b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperClientSocketBenchmark.java
@@ -0,0 +1,99 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import com.android.org.conscrypt.ClientSocketBenchmark.Config;
+
+/**
+ * Benchmark for comparing performance of client socket implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("unused")
+public class CaliperClientSocketBenchmark {
+
+  private final CaliperConfig config = new CaliperConfig();
+
+  @Param
+  public AndroidEndpointFactory socketType;
+
+  @Param({"64", "512", "4096"})
+  public int messageSize;
+
+  @Param({TestUtils.TEST_CIPHER})
+  public String cipher;
+
+  @Param
+  public BenchmarkProtocol protocol;
+
+  @Param
+  public ChannelType channelType;
+
+  private ClientSocketBenchmark benchmark;
+
+  @BeforeExperiment
+  public void setup() throws Exception {
+    benchmark = new ClientSocketBenchmark(config);
+  }
+
+  @AfterExperiment
+  public void teardown() throws Exception {
+    benchmark.close();
+  }
+
+  @Benchmark
+  public final void time(int numMessages) throws Exception {
+    benchmark.time(numMessages);
+  }
+
+  private final class CaliperConfig implements Config {
+    @Override
+    public EndpointFactory clientFactory() {
+      return socketType;
+    }
+
+    @Override
+    public EndpointFactory serverFactory() {
+      // Use the same server for all benchmarks, since we're looking at the perf of the client.
+      return AndroidEndpointFactory.CONSCRYPT_ENGINE;
+    }
+
+    @Override
+    public int messageSize() {
+      return messageSize;
+    }
+
+    @Override
+    public String cipher() {
+      return cipher;
+    }
+
+    @Override
+    public ChannelType channelType() {
+      return channelType;
+    }
+
+    @Override
+    public BenchmarkProtocol protocol() {
+      return protocol;
+    }
+  }
+}
diff --git a/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperEngineHandshakeBenchmark.java b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperEngineHandshakeBenchmark.java
new file mode 100644
index 0000000..a43c74e
--- /dev/null
+++ b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperEngineHandshakeBenchmark.java
@@ -0,0 +1,108 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import com.android.org.conscrypt.EngineHandshakeBenchmark.Config;
+
+/**
+ * Benchmark comparing handshake performance of various engine implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("unused")
+public class CaliperEngineHandshakeBenchmark {
+    private final CaliperConfig config = new CaliperConfig();
+
+    @Param({TestUtils.TEST_CIPHER})
+    public String a_cipher;
+
+    @Param
+    public BufferType b_buffer;
+
+    @Param({"CONSCRYPT_UNPOOLED"}) public AndroidEngineFactory c_engine;
+
+    @Param
+    public BenchmarkProtocol d_protocol;
+
+    @Param({"100"})
+    public int e_rtt;
+
+    private EngineHandshakeBenchmark benchmark;
+
+    @BeforeExperiment
+    public void setUp() throws Exception {
+        benchmark = new EngineHandshakeBenchmark(config);
+    }
+
+    @Benchmark
+    public void timeHandshake(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            benchmark.handshake();
+        }
+    }
+
+    private final class CaliperConfig implements Config {
+        @Override
+        public BufferType bufferType() {
+            return b_buffer;
+        }
+
+        @Override
+        public EngineFactory engineFactory() {
+            return c_engine;
+        }
+
+        @Override
+        public String cipher() {
+            return a_cipher;
+        }
+
+        @Override
+        public boolean useAlpn() {
+            return false;
+        }
+
+        @Override
+        public BenchmarkProtocol protocol() {
+            return d_protocol;
+        }
+
+        @Override
+        public int rttMillis() {
+            return e_rtt;
+        }
+    }
+}
diff --git a/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperEngineWrapBenchmark.java b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperEngineWrapBenchmark.java
new file mode 100644
index 0000000..4268c1e
--- /dev/null
+++ b/repackaged/benchmark-android/src/main/java/com/android/org/conscrypt/CaliperEngineWrapBenchmark.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import javax.net.ssl.SSLException;
+import com.android.org.conscrypt.EngineWrapBenchmark.Config;
+
+/**
+ * Benchmark comparing performance of various engine implementations to conscrypt.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("unused")
+public class CaliperEngineWrapBenchmark {
+    private final CaliperConfig config = new CaliperConfig();
+
+    @Param({TestUtils.TEST_CIPHER})
+    public String a_cipher;
+
+    @Param
+    public BufferType b_buffer;
+
+    @Param({"64", "512", "4096"})
+    public int c_message;
+
+    @Param({"CONSCRYPT_UNPOOLED"}) public AndroidEngineFactory d_engine;
+
+    private EngineWrapBenchmark benchmark;
+
+    @BeforeExperiment
+    public void setUp() throws Exception {
+        benchmark = new EngineWrapBenchmark(config);
+    }
+
+    @AfterExperiment
+    public void teardown() {
+        benchmark.teardown();
+    }
+
+    @Benchmark
+    public void timeWrap(int reps) throws SSLException {
+        for (int i = 0; i < reps; ++i) {
+            benchmark.wrap();
+        }
+    }
+
+    public void timeWrapAndUnwrap(int reps) throws SSLException {
+        for (int i = 0; i < reps; ++i) {
+            benchmark.wrapAndUnwrap();
+        }
+    }
+
+    private final class CaliperConfig implements Config {
+
+        @Override
+        public BufferType bufferType() {
+            return b_buffer;
+        }
+
+        @Override
+        public EngineFactory engineFactory() {
+            return d_engine;
+        }
+
+        @Override
+        public int messageSize() {
+            return c_message;
+        }
+
+        @Override
+        public String cipher() {
+            return a_cipher;
+        }
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/BenchmarkProtocol.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/BenchmarkProtocol.java
new file mode 100644
index 0000000..c31bb80
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/BenchmarkProtocol.java
@@ -0,0 +1,22 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("ImmutableEnumChecker")
+public enum BenchmarkProtocol {
+
+    TLSv13("TLSv1.3"),
+    TLSv12("TLSv1.2");
+
+    private final String[] protocols;
+
+    BenchmarkProtocol(String... protocols) {
+        this.protocols = protocols;
+    }
+
+    public String[] getProtocols() {
+        return protocols.clone();
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/BufferType.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/BufferType.java
new file mode 100644
index 0000000..a2a62d3
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/BufferType.java
@@ -0,0 +1,50 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Enumeration that provides allocation of direct or heap buffers.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("unused")
+public enum BufferType {
+    HEAP {
+        @Override
+        ByteBuffer newBuffer(int size) {
+            return ByteBuffer.allocate(size);
+        }
+    },
+    DIRECT {
+        @Override
+        ByteBuffer newBuffer(int size) {
+            return ByteBuffer.allocateDirect(size);
+        }
+    };
+
+    abstract ByteBuffer newBuffer(int size);
+
+    ByteBuffer newApplicationBuffer(SSLEngine engine) {
+        return newBuffer(engine.getSession().getApplicationBufferSize());
+    }
+
+    ByteBuffer newPacketBuffer(SSLEngine engine) {
+        return newBuffer(engine.getSession().getPacketBufferSize());
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/CipherEncryptBenchmark.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/CipherEncryptBenchmark.java
new file mode 100644
index 0000000..71fa3c4
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/CipherEncryptBenchmark.java
@@ -0,0 +1,162 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import java.security.Key;
+import javax.crypto.Cipher;
+
+/**
+ * Benchmark for comparing cipher encrypt performance.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class CipherEncryptBenchmark {
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum BufferType {
+        ARRAY,
+        HEAP_HEAP,
+        HEAP_DIRECT,
+        DIRECT_DIRECT,
+        DIRECT_HEAP
+    }
+
+    /**
+     * Provider for the benchmark configuration
+     */
+    interface Config {
+        BufferType bufferType();
+        CipherFactory cipherFactory();
+        Transformation transformation();
+    }
+
+    private final EncryptStrategy encryptStrategy;
+
+    CipherEncryptBenchmark(Config config) throws Exception {
+        switch (config.bufferType()) {
+            case ARRAY:
+                encryptStrategy = new ArrayStrategy(config);
+                break;
+            default:
+                encryptStrategy = new ByteBufferStrategy(config);
+                break;
+        }
+    }
+
+    int encrypt() throws Exception {
+        return encryptStrategy.encrypt();
+    }
+
+    private static abstract class EncryptStrategy {
+        private final Key key;
+        final Cipher cipher;
+        final int outputSize;
+
+        EncryptStrategy(Config config) throws Exception {
+            Transformation tx = config.transformation();
+            key = tx.newEncryptKey();
+            cipher = config.cipherFactory().newCipher(tx.toFormattedString());
+            initCipher();
+
+            int messageSize = messageSize(tx.toFormattedString());
+            outputSize = cipher.getOutputSize(messageSize);
+        }
+
+        final void initCipher() throws Exception {
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+        }
+
+        final int messageSize(String transformation) throws Exception {
+            Cipher conscryptCipher = Cipher.getInstance(transformation, TestUtils.getConscryptProvider());
+            conscryptCipher.init(Cipher.ENCRYPT_MODE, key);
+            return conscryptCipher.getBlockSize() > 0 ? conscryptCipher.getBlockSize() : 128;
+        }
+
+        final byte[] newMessage() {
+            return TestUtils.newTextMessage(cipher.getBlockSize());
+        }
+
+        abstract int encrypt() throws Exception;
+    }
+
+    private static final class ArrayStrategy extends EncryptStrategy {
+        private final byte[] plainBytes;
+        private final byte[] cipherBytes;
+
+        ArrayStrategy(Config config) throws Exception {
+            super(config);
+
+            plainBytes = newMessage();
+            cipherBytes = new byte[outputSize];
+        }
+
+        @Override
+        int encrypt() throws Exception {
+            initCipher();
+            return cipher.doFinal(plainBytes, 0, plainBytes.length, cipherBytes, 0);
+        }
+    }
+
+    private static final class ByteBufferStrategy extends EncryptStrategy {
+        private final ByteBuffer input;
+        private final ByteBuffer output;
+
+        ByteBufferStrategy(Config config) throws Exception {
+            super(config);
+
+            switch (config.bufferType()) {
+                case HEAP_HEAP:
+                    input = ByteBuffer.wrap(newMessage());
+                    output = ByteBuffer.allocate(outputSize);
+                    break;
+                case HEAP_DIRECT:
+                    input = ByteBuffer.wrap(newMessage());
+                    output = ByteBuffer.allocateDirect(outputSize);
+                    break;
+                case DIRECT_DIRECT:
+                    input = toDirect(newMessage());
+                    output = ByteBuffer.allocateDirect(outputSize);
+                    break;
+                case DIRECT_HEAP:
+                    input = toDirect(newMessage());
+                    output = ByteBuffer.allocate(outputSize);
+                    break;
+                default: {
+                    throw new IllegalStateException(
+                            "Unexpected buffertype: " + config.bufferType());
+                }
+            }
+        }
+
+        @Override
+        int encrypt() throws Exception {
+            initCipher();
+            input.position(0);
+            output.clear();
+            return cipher.doFinal(input, output);
+        }
+
+        private static ByteBuffer toDirect(byte[] data) {
+            ByteBuffer buffer = ByteBuffer.allocateDirect(data.length);
+            buffer.put(data);
+            buffer.flip();
+            return buffer;
+        }
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/CipherFactory.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/CipherFactory.java
new file mode 100644
index 0000000..f1ae323
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/CipherFactory.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * Factory for {@link Cipher} instances.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CipherFactory {
+  Cipher newCipher(String transformation) throws NoSuchPaddingException, NoSuchAlgorithmException;
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ClientEndpoint.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ClientEndpoint.java
new file mode 100644
index 0000000..fd38975
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ClientEndpoint.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.nio.channels.ClosedChannelException;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * Client-side endpoint. Provides basic services for sending/receiving messages from the client
+ * socket.
+ */
+final class ClientEndpoint {
+    private final SSLSocket socket;
+    private InputStream input;
+    private OutputStream output;
+
+    ClientEndpoint(SSLSocketFactory socketFactory, ChannelType channelType, int port,
+            String[] protocols, String[] ciphers) throws IOException {
+        socket = channelType.newClientSocket(socketFactory, InetAddress.getLoopbackAddress(), port);
+        socket.setEnabledProtocols(protocols);
+        socket.setEnabledCipherSuites(ciphers);
+    }
+
+    void start() {
+        try {
+            socket.startHandshake();
+            input = socket.getInputStream();
+            output = socket.getOutputStream();
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    void stop() {
+        try {
+            socket.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    int readMessage(byte[] buffer) {
+        try {
+            int totalBytesRead = 0;
+            while (totalBytesRead < buffer.length) {
+                int remaining = buffer.length - totalBytesRead;
+                int bytesRead = input.read(buffer, totalBytesRead, remaining);
+                if (bytesRead == -1) {
+                    break;
+                }
+                totalBytesRead += bytesRead;
+            }
+            return totalBytesRead;
+        } catch (SSLException e) {
+            if (e.getCause() instanceof EOFException) {
+                return -1;
+            }
+            throw new RuntimeException(e);
+        } catch (ClosedChannelException e) {
+            // Thrown for channel-based sockets. Just treat like EOF.
+            return -1;
+        }  catch (SocketException e) {
+            // The socket was broken. Just treat like EOF.
+            return -1;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    void sendMessage(byte[] data) {
+        try {
+            output.write(data);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    void flush() {
+        try {
+            output.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ClientSocketBenchmark.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ClientSocketBenchmark.java
new file mode 100644
index 0000000..1bb35b4
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ClientSocketBenchmark.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.newTextMessage;
+
+import java.io.OutputStream;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Benchmark for comparing performance of client socket implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ClientSocketBenchmark {
+    /**
+     * Provider for the benchmark configuration
+     */
+    interface Config {
+        EndpointFactory clientFactory();
+        EndpointFactory serverFactory();
+        int messageSize();
+        String cipher();
+        ChannelType channelType();
+        BenchmarkProtocol protocol();
+    }
+
+    private ClientEndpoint client;
+    private ServerEndpoint server;
+    private byte[] message;
+    private ExecutorService executor;
+    private Future<?> sendingFuture;
+    private volatile boolean stopping;
+
+    private static final AtomicLong bytesCounter = new AtomicLong();
+    private AtomicBoolean recording = new AtomicBoolean();
+
+    ClientSocketBenchmark(Config config) throws Exception {
+        recording.set(false);
+
+        message = newTextMessage(config.messageSize());
+
+        // Always use the same server for consistency across the benchmarks.
+        server = config.serverFactory().newServer(
+                ChannelType.CHANNEL, config.messageSize(), config.protocol().getProtocols(),
+                ciphers(config));
+
+        server.setMessageProcessor(new ServerEndpoint.MessageProcessor() {
+            @Override
+            public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
+                if (recording.get()) {
+                    // Server received a message, increment the count.
+                    bytesCounter.addAndGet(numBytes);
+                }
+            }
+        });
+        Future<?> connectedFuture = server.start();
+
+        client = config.clientFactory().newClient(
+            config.channelType(), server.port(), config.protocol().getProtocols(), ciphers(config));
+        client.start();
+
+        // Wait for the initial connection to complete.
+        connectedFuture.get(5, TimeUnit.SECONDS);
+
+        executor = Executors.newSingleThreadExecutor();
+        sendingFuture = executor.submit(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Thread thread = Thread.currentThread();
+                    while (!stopping && !thread.isInterrupted()) {
+                        client.sendMessage(message);
+                    }
+                } finally {
+                    client.flush();
+                }
+            }
+        });
+    }
+
+    void close() throws Exception {
+        stopping = true;
+
+        // Wait for the sending thread to stop.
+        sendingFuture.get(5, TimeUnit.SECONDS);
+
+        client.stop();
+        server.stop();
+        executor.shutdown();
+        executor.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Simple benchmark for the amount of time to send a given number of messages (used by
+     * Caliper).
+     */
+    void time(final int numMessages) throws Exception {
+        reset();
+        recording.set(true);
+
+        while (bytesCounter.get() < numMessages) {
+            Thread.sleep(50);
+        }
+
+        recording.set(false);
+    }
+
+    /**
+     * Simple benchmark for throughput (used by JMH).
+     */
+    void throughput() throws Exception {
+        recording.set(true);
+        // Send as many messages as we can in a second.
+        Thread.sleep(1001);
+        recording.set(false);
+    }
+
+    static void reset() {
+        bytesCounter.set(0);
+    }
+
+    static long bytesPerSecond() {
+        return bytesCounter.get();
+    }
+
+    private String[] ciphers(Config config) {
+        return new String[] {config.cipher()};
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EndpointFactory.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EndpointFactory.java
new file mode 100644
index 0000000..0b09579
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EndpointFactory.java
@@ -0,0 +1,15 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt;
+
+import java.io.IOException;
+
+/**
+ * Utility for creating test client and server endpoints.
+ */
+interface EndpointFactory {
+  ClientEndpoint newClient(ChannelType channelType, int port, String[] protocols,
+      String[] ciphers) throws IOException;
+
+  ServerEndpoint newServer(ChannelType channelType, int messageSize,
+      String[] protocols, String[] ciphers) throws IOException;
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineFactory.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineFactory.java
new file mode 100644
index 0000000..662b3e9
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineFactory.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Factory for {@link SSLEngine} instances.
+ */
+interface EngineFactory {
+
+    SSLEngine newClientEngine(String cipher, boolean useAlpn);
+
+    SSLEngine newServerEngine(String cipher, boolean useAlpn);
+
+    void dispose(SSLEngine engine);
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineHandshakeBenchmark.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineHandshakeBenchmark.java
new file mode 100644
index 0000000..84a48c8
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineHandshakeBenchmark.java
@@ -0,0 +1,172 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+
+/**
+ * Benchmark comparing handshake performance of various engine implementations to conscrypt.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class EngineHandshakeBenchmark {
+    /**
+     * Provider for the benchmark configuration
+     */
+    interface Config {
+        BufferType bufferType();
+        EngineFactory engineFactory();
+        String cipher();
+        boolean useAlpn();
+        BenchmarkProtocol protocol();
+        int rttMillis();
+    }
+
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocateDirect(0);
+
+    private final EngineFactory engineFactory;
+    private final String cipher;
+    private final boolean useAlpn;
+    private final String[] protocols;
+    private final int rttMillis;
+
+    private final ByteBuffer clientApplicationBuffer;
+    private final ByteBuffer clientPacketBuffer;
+    private final ByteBuffer serverApplicationBuffer;
+    private final ByteBuffer serverPacketBuffer;
+
+    EngineHandshakeBenchmark(Config config) throws Exception {
+        engineFactory = config.engineFactory();
+        cipher = config.cipher();
+        useAlpn = config.useAlpn();
+        protocols = config.protocol().getProtocols();
+        rttMillis = config.rttMillis();
+        BufferType bufferType = config.bufferType();
+
+        SSLEngine clientEngine = engineFactory.newClientEngine(cipher, useAlpn);
+        SSLEngine serverEngine = engineFactory.newServerEngine(cipher, useAlpn);
+
+        // Create the application and packet buffers for both endpoints.
+        clientApplicationBuffer = bufferType.newApplicationBuffer(clientEngine);
+        serverApplicationBuffer = bufferType.newApplicationBuffer(serverEngine);
+        clientPacketBuffer = bufferType.newPacketBuffer(clientEngine);
+        serverPacketBuffer = bufferType.newPacketBuffer(serverEngine);
+
+        engineFactory.dispose(clientEngine);
+        engineFactory.dispose(serverEngine);
+    }
+
+    void handshake() throws SSLException {
+        SSLEngine client = engineFactory.newClientEngine(cipher, useAlpn);
+        SSLEngine server = engineFactory.newServerEngine(cipher, useAlpn);
+        clientApplicationBuffer.clear();
+        clientPacketBuffer.clear();
+        serverApplicationBuffer.clear();
+        serverPacketBuffer.clear();
+
+        client.setEnabledProtocols(protocols);
+        server.setEnabledProtocols(protocols);
+
+        client.beginHandshake();
+        server.beginHandshake();
+
+        doHandshake(client, server);
+
+        engineFactory.dispose(client);
+        engineFactory.dispose(server);
+    }
+
+    private void doHandshake(SSLEngine client, SSLEngine server) throws SSLException {
+        while (true) {
+            // Send as many client-to-server messages as possible
+            doHalfHandshake(client, server, clientPacketBuffer, serverApplicationBuffer);
+
+            if (client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                    && server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
+                return;
+            }
+
+            // Do the same with server-to-client messages
+            doHalfHandshake(server, client, serverPacketBuffer, clientApplicationBuffer);
+
+            if (client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                    && server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
+                return;
+            }
+        }
+    }
+
+    private void doHalfHandshake(SSLEngine sender, SSLEngine receiver,
+            ByteBuffer senderPacketBuffer, ByteBuffer receiverApplicationBuffer)
+            throws SSLException {
+        SSLEngineResult senderResult;
+        SSLEngineResult receiverResult;
+
+        do {
+            senderResult = sender.wrap(EMPTY_BUFFER, senderPacketBuffer);
+            runDelegatedTasks(senderResult, sender);
+            senderPacketBuffer.flip();
+            receiverResult = receiver.unwrap(senderPacketBuffer, receiverApplicationBuffer);
+            runDelegatedTasks(receiverResult, receiver);
+            senderPacketBuffer.compact();
+        } while (senderResult.getHandshakeStatus() == HandshakeStatus.NEED_WRAP);
+
+        if (rttMillis > 0) {
+            try {
+                Thread.sleep(rttMillis / 2);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) {
+        if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
+            for (;;) {
+                Runnable task = engine.getDelegatedTask();
+                if (task == null) {
+                    break;
+                }
+                task.run();
+            }
+        }
+    }
+
+    private static boolean isHandshakeFinished(SSLEngineResult result) {
+        return result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED;
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineWrapBenchmark.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineWrapBenchmark.java
new file mode 100644
index 0000000..5595485
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/EngineWrapBenchmark.java
@@ -0,0 +1,161 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.doEngineHandshake;
+import static com.android.org.conscrypt.TestUtils.newTextMessage;
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+import java.util.Locale;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+
+/**
+ * Benchmark comparing performance of various engine implementations to conscrypt.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class EngineWrapBenchmark {
+    /**
+     * Provider for the benchmark configuration
+     */
+    interface Config {
+        BufferType bufferType();
+        EngineFactory engineFactory();
+        int messageSize();
+        String cipher();
+    }
+
+    private final EngineFactory engineFactory;
+    private final String cipher;
+    private final SSLEngine clientEngine;
+    private final SSLEngine serverEngine;
+
+    private final ByteBuffer messageBuffer;
+    private final ByteBuffer clientApplicationBuffer;
+    private final ByteBuffer clientPacketBuffer;
+    private final ByteBuffer serverApplicationBuffer;
+    private final ByteBuffer serverPacketBuffer;
+    private final ByteBuffer preEncryptedBuffer;
+
+    EngineWrapBenchmark(Config config) throws Exception {
+        engineFactory = config.engineFactory();
+        cipher = config.cipher();
+        BufferType bufferType = config.bufferType();
+
+        clientEngine = engineFactory.newClientEngine(cipher, false);
+        serverEngine = engineFactory.newServerEngine(cipher, false);
+
+        // Create the application and packet buffers for both endpoints.
+        clientApplicationBuffer = bufferType.newApplicationBuffer(clientEngine);
+        serverApplicationBuffer = bufferType.newApplicationBuffer(serverEngine);
+        clientPacketBuffer = bufferType.newPacketBuffer(clientEngine);
+        serverPacketBuffer = bufferType.newPacketBuffer(serverEngine);
+
+        // Generate the message to be sent from the client.
+        int messageSize = config.messageSize();
+        messageBuffer = bufferType.newBuffer(messageSize);
+        messageBuffer.put(newTextMessage(messageSize));
+        messageBuffer.flip();
+
+        // Complete the initial TLS handshake.
+        doEngineHandshake(clientEngine, serverEngine, clientApplicationBuffer, clientPacketBuffer,
+                serverApplicationBuffer, serverPacketBuffer, true);
+
+        // Populate the pre-encrypted buffer for use with the unwrap benchmark.
+        preEncryptedBuffer = bufferType.newBuffer(clientEngine.getSession().getPacketBufferSize());
+        doWrap(messageBuffer, preEncryptedBuffer);
+        doUnwrap(preEncryptedBuffer, serverApplicationBuffer);
+    }
+
+    void teardown() {
+        engineFactory.dispose(clientEngine);
+        engineFactory.dispose(serverEngine);
+    }
+
+    void wrap() throws SSLException {
+        // Reset the buffers.
+        messageBuffer.position(0);
+        clientPacketBuffer.clear();
+
+        // Wrap the original message and create the encrypted data.
+        doWrap(messageBuffer, clientPacketBuffer);
+
+        // Lightweight comparison - just make sure the data length is correct.
+        assertEquals(preEncryptedBuffer.limit(), clientPacketBuffer.limit());
+    }
+
+    /**
+     * Simple benchmark that sends a single message from client to server.
+     */
+    void wrapAndUnwrap() throws SSLException {
+        // Reset the buffers.
+        messageBuffer.position(0);
+        clientPacketBuffer.clear();
+        serverApplicationBuffer.clear();
+
+        // Wrap the original message and create the encrypted data.
+        doWrap(messageBuffer, clientPacketBuffer);
+
+        // Unwrap the encrypted data and get back the original result.
+        doUnwrap(clientPacketBuffer, serverApplicationBuffer);
+
+        // Lightweight comparison - just make sure the unencrypted data length is correct.
+        assertEquals(messageBuffer.limit(), serverApplicationBuffer.limit());
+    }
+
+    private void doWrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        // Wrap the original message and create the encrypted data.
+        verifyResult(src, clientEngine.wrap(src, dst));
+        dst.flip();
+    }
+
+    private void doUnwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        verifyResult(src, serverEngine.unwrap(src, dst));
+        dst.flip();
+    }
+
+    private void verifyResult(ByteBuffer src, SSLEngineResult result) {
+        if (result.getStatus() != SSLEngineResult.Status.OK) {
+            throw new RuntimeException("Operation returned unexpected result " + result);
+        }
+        if (result.bytesConsumed() != src.limit()) {
+            throw new RuntimeException(
+                    String.format(Locale.US,
+                            "Operation didn't consume all bytes. Expected %d, consumed %d.",
+                            src.limit(), result.bytesConsumed()));
+        }
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ServerEndpoint.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ServerEndpoint.java
new file mode 100644
index 0000000..b15cc79
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ServerEndpoint.java
@@ -0,0 +1,200 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.SocketException;
+import java.nio.channels.ClosedChannelException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * A simple socket-based test server.
+ */
+final class ServerEndpoint {
+    /**
+     * A processor for receipt of a single message.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public interface MessageProcessor {
+        void processMessage(byte[] message, int numBytes, OutputStream os);
+    }
+
+    /**
+     * A {@link MessageProcessor} that simply echos back the received message to the client.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static final class EchoProcessor implements MessageProcessor {
+        @Override
+        public void processMessage(byte[] message, int numBytes, OutputStream os) {
+            try {
+                os.write(message, 0, numBytes);
+                os.flush();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private final ServerSocket serverSocket;
+    private final ChannelType channelType;
+    private final SSLSocketFactory socketFactory;
+    private final int messageSize;
+    private final String[] protocols;
+    private final String[] cipherSuites;
+    private final byte[] buffer;
+    private SSLSocket socket;
+    private ExecutorService executor;
+    private InputStream inputStream;
+    private OutputStream outputStream;
+    private volatile boolean stopping;
+    private volatile MessageProcessor messageProcessor = new EchoProcessor();
+    private volatile Future<?> processFuture;
+
+    ServerEndpoint(SSLSocketFactory socketFactory, SSLServerSocketFactory serverSocketFactory,
+            ChannelType channelType, int messageSize, String[] protocols,
+            String[] cipherSuites) throws IOException {
+        this.serverSocket = channelType.newServerSocket(serverSocketFactory);
+        this.socketFactory = socketFactory;
+        this.channelType = channelType;
+        this.messageSize = messageSize;
+        this.protocols = protocols;
+        this.cipherSuites = cipherSuites;
+        buffer = new byte[messageSize];
+    }
+
+    void setMessageProcessor(MessageProcessor messageProcessor) {
+        this.messageProcessor = messageProcessor;
+    }
+
+    Future<?> start() throws IOException {
+        executor = Executors.newSingleThreadExecutor();
+        return executor.submit(new AcceptTask());
+    }
+
+    void stop() {
+        try {
+            stopping = true;
+
+            if (socket != null) {
+                socket.close();
+                socket = null;
+            }
+
+            if (processFuture != null) {
+                processFuture.get(5, TimeUnit.SECONDS);
+            }
+
+            serverSocket.close();
+
+            if (executor != null) {
+                executor.shutdown();
+                executor.awaitTermination(5, TimeUnit.SECONDS);
+                executor = null;
+            }
+        } catch (IOException | InterruptedException | ExecutionException | TimeoutException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public int port() {
+        return serverSocket.getLocalPort();
+    }
+
+    private final class AcceptTask implements Runnable {
+        @Override
+        public void run() {
+            try {
+                if (stopping) {
+                    return;
+                }
+                socket = channelType.accept(serverSocket, socketFactory);
+                socket.setEnabledProtocols(protocols);
+                socket.setEnabledCipherSuites(cipherSuites);
+
+                socket.startHandshake();
+
+                inputStream = socket.getInputStream();
+                outputStream = socket.getOutputStream();
+
+                if (stopping) {
+                    return;
+                }
+                processFuture = executor.submit(new ProcessTask());
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private final class ProcessTask implements Runnable {
+        @Override
+        public void run() {
+            try {
+                Thread thread = Thread.currentThread();
+                while (!stopping && !thread.isInterrupted()) {
+                    int bytesRead = readMessage();
+                    if (!stopping && !thread.isInterrupted()) {
+                        messageProcessor.processMessage(buffer, bytesRead, outputStream);
+                    }
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        private int readMessage() throws IOException {
+            int totalBytesRead = 0;
+            while (!stopping && totalBytesRead < messageSize) {
+                try {
+                    int remaining = messageSize - totalBytesRead;
+                    int bytesRead = inputStream.read(buffer, totalBytesRead, remaining);
+                    if (bytesRead == -1) {
+                        break;
+                    }
+                    totalBytesRead += bytesRead;
+                } catch (SSLException e) {
+                    if (e.getCause() instanceof EOFException) {
+                        break;
+                    }
+                    throw e;
+                } catch (ClosedChannelException e) {
+                    // Thrown for channel-based sockets. Just treat like EOF.
+                    break;
+                } catch (SocketException e) {
+                    // The socket was broken. Just treat like EOF.
+                    break;
+                }
+            }
+            return totalBytesRead;
+        }
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ServerSocketBenchmark.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ServerSocketBenchmark.java
new file mode 100644
index 0000000..f8a80bb
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/ServerSocketBenchmark.java
@@ -0,0 +1,151 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.getProtocols;
+import static com.android.org.conscrypt.TestUtils.newTextMessage;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.SocketException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import com.android.org.conscrypt.ServerEndpoint.MessageProcessor;
+
+/**
+ * Benchmark for comparing performance of server socket implementations.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ServerSocketBenchmark {
+    /**
+     * Provider for the benchmark configuration
+     */
+    interface Config {
+        EndpointFactory clientFactory();
+        EndpointFactory serverFactory();
+        int messageSize();
+        String cipher();
+        ChannelType channelType();
+    }
+
+    private ClientEndpoint client;
+    private ServerEndpoint server;
+    private ExecutorService executor;
+    private Future<?> receivingFuture;
+    private volatile boolean stopping;
+    private static final AtomicLong bytesCounter = new AtomicLong();
+    private AtomicBoolean recording = new AtomicBoolean();
+
+    ServerSocketBenchmark(final Config config) throws Exception {
+        recording.set(false);
+
+        byte[] message = newTextMessage(config.messageSize());
+
+        final ChannelType channelType = config.channelType();
+
+        server = config.serverFactory().newServer(
+            channelType, config.messageSize(), getProtocols(), ciphers(config));
+        server.setMessageProcessor(new MessageProcessor() {
+            @Override
+            public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
+                try {
+                    try {
+                        while (!stopping) {
+                            os.write(inMessage, 0, numBytes);
+                        }
+                    } finally {
+                        os.flush();
+                    }
+                } catch (SocketException e) {
+                    // Just ignore.
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+
+        Future<?> connectedFuture = server.start();
+
+        // Always use the same client for consistency across the benchmarks.
+        client = config.clientFactory().newClient(
+                ChannelType.CHANNEL, server.port(), getProtocols(), ciphers(config));
+        client.start();
+
+        // Wait for the initial connection to complete.
+        connectedFuture.get(5, TimeUnit.SECONDS);
+
+        // Start the server-side streaming by sending a message to the server.
+        client.sendMessage(message);
+        client.flush();
+
+        executor = Executors.newSingleThreadExecutor();
+        receivingFuture = executor.submit(new Runnable() {
+            @Override
+            public void run() {
+                Thread thread = Thread.currentThread();
+                byte[] buffer = new byte[config.messageSize()];
+                while (!stopping && !thread.isInterrupted()) {
+                    int numBytes = client.readMessage(buffer);
+                    if (numBytes < 0) {
+                        return;
+                    }
+                    assertEquals(config.messageSize(), numBytes);
+
+                    // Increment the message counter if we're recording.
+                    if (recording.get()) {
+                        bytesCounter.addAndGet(numBytes);
+                    }
+                }
+            }
+        });
+    }
+
+    void close() throws Exception {
+        stopping = true;
+        // Stop and wait for sending to complete.
+        server.stop();
+        client.stop();
+        executor.shutdown();
+        receivingFuture.get(5, TimeUnit.SECONDS);
+        executor.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    void throughput() throws Exception {
+        recording.set(true);
+        // Send as many messages as we can in a second.
+        Thread.sleep(1001);
+        recording.set(false);
+    }
+
+    static void reset() {
+        bytesCounter.set(0);
+    }
+
+    static long bytesPerSecond() {
+        return bytesCounter.get();
+    }
+
+    private String[] ciphers(Config config) {
+        return new String[] {config.cipher()};
+    }
+}
diff --git a/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/Transformation.java b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/Transformation.java
new file mode 100644
index 0000000..f50cad5
--- /dev/null
+++ b/repackaged/benchmark-base/src/main/java/com/android/org/conscrypt/Transformation.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.KeyGenerator;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+/**
+ * Supported cipher transformations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings({"ImmutableEnumChecker", "unused"})
+public enum Transformation {
+    AES_CBC_PKCS5("AES", "CBC", "PKCS5Padding", new AesKeyGen()),
+    AES_ECB_PKCS5("AES", "ECB", "PKCS5Padding", new AesKeyGen()),
+    AES_GCM_NO("AES", "GCM", "NoPadding", new AesKeyGen()),
+    RSA_ECB_PKCS1("RSA", "ECB", "PKCS1Padding", new RsaKeyGen());
+
+    Transformation(String algorithm, String mode, String padding, KeyGen keyGen) {
+        this.algorithm = algorithm;
+        this.mode = mode;
+        this.padding = padding;
+        this.keyGen = keyGen;
+    }
+
+    final String algorithm;
+    final String mode;
+    final String padding;
+    final KeyGen keyGen;
+
+    String toFormattedString() {
+        return algorithm + "/" + mode + "/" + padding;
+    }
+
+    Key newEncryptKey() {
+        return keyGen.newEncryptKey();
+    }
+
+    private interface KeyGen { Key newEncryptKey(); }
+
+    private static final class RsaKeyGen implements KeyGen {
+        @Override
+        public Key newEncryptKey() {
+            try {
+                // Use Bouncy castle
+                KeyPairGenerator generator =
+                        KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
+                generator.initialize(2048);
+                KeyPair pair = generator.generateKeyPair();
+                return pair.getPublic();
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private static final class AesKeyGen implements KeyGen {
+        @Override
+        public Key newEncryptKey() {
+            try {
+                // Just use the JDK's provider.
+                KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+                keyGen.init(256);
+                return keyGen.generateKey();
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptEngine.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptEngine.java
new file mode 100644
index 0000000..a79178d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptEngine.java
@@ -0,0 +1,184 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import java.security.PrivateKey;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * Abstract base class for all Conscrypt {@link SSLEngine} classes.
+ */
+abstract class AbstractConscryptEngine extends SSLEngine {
+    abstract void setBufferAllocator(BufferAllocator bufferAllocator);
+
+    /**
+     * Returns the maximum overhead, in bytes, of sealing a record with SSL.
+     */
+    abstract int maxSealOverhead();
+
+    /**
+     * Enables/disables TLS Channel ID for this server engine.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @throws IllegalStateException if this is a client engine or if the handshake has already
+     *         started.
+     */
+    abstract void setChannelIdEnabled(boolean enabled);
+
+    /**
+     * Gets the TLS Channel ID for this server engine. Channel ID is only available once the
+     * handshake completes.
+     *
+     * @return channel ID or {@code null} if not available.
+     *
+     * @throws IllegalStateException if this is a client engine or if the handshake has not yet
+     * completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    abstract byte[] getChannelId() throws SSLException;
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client engine.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
+     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
+     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
+     *
+     * @throws IllegalStateException if this is a server engine or if the handshake has already
+     *         started.
+     */
+    abstract void setChannelIdPrivateKey(PrivateKey privateKey);
+
+    /**
+     * Sets the listener for the completion of the TLS handshake.
+     */
+    abstract void setHandshakeListener(HandshakeListener handshakeListener);
+
+    /**
+     * This method enables Server Name Indication (SNI) and overrides the {@link PeerInfoProvider}
+     * supplied during engine creation.
+     */
+    abstract void setHostname(String hostname);
+
+    /**
+     * Returns the hostname from {@link #setHostname(String)} or supplied by the
+     * {@link PeerInfoProvider} upon creation. No DNS resolution is attempted before
+     * returning the hostname.
+     */
+    abstract String getHostname();
+
+    @Override public abstract String getPeerHost();
+
+    @Override public abstract int getPeerPort();
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java 6.
+    public final SSLSession getHandshakeSession() {
+        return handshakeSession();
+    }
+
+    /**
+     * Work-around to allow this method to be called on older versions of Android.
+     */
+    abstract SSLSession handshakeSession();
+
+    @Override
+    public abstract SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException;
+
+    @Override
+    public abstract SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException;
+
+    @Override
+    public abstract SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts,
+            final int offset, final int length) throws SSLException;
+
+    abstract SSLEngineResult unwrap(final ByteBuffer[] srcs, final ByteBuffer[] dsts)
+            throws SSLException;
+
+    abstract SSLEngineResult unwrap(final ByteBuffer[] srcs, int srcsOffset, final int srcsLength,
+            final ByteBuffer[] dsts, final int dstsOffset, final int dstsLength)
+            throws SSLException;
+
+    @Override
+    public abstract SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException;
+
+    @Override
+    public abstract SSLEngineResult wrap(
+            ByteBuffer[] srcs, int srcsOffset, int srcsLength, ByteBuffer dst) throws SSLException;
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param useSessionTickets True to enable session tickets
+     */
+    abstract void setUseSessionTickets(boolean useSessionTickets);
+
+    /**
+     * Sets the list of ALPN protocols.
+     *
+     * @param protocols the list of ALPN protocols
+     */
+    abstract void setApplicationProtocols(String[] protocols);
+
+    /**
+     * Returns the list of supported ALPN protocols.
+     */
+    abstract String[] getApplicationProtocols();
+
+    @SuppressWarnings("MissingOverride") // For compiling pre Java 9.
+    public abstract String getApplicationProtocol();
+
+    @SuppressWarnings("MissingOverride") // For compiling pre Java 9.
+    public abstract String getHandshakeApplicationProtocol();
+
+    /**
+     * Sets an application-provided ALPN protocol selector. If provided, this will override
+     * the list of protocols set by {@link #setApplicationProtocols(String[])}.
+     */
+    abstract void setApplicationProtocolSelector(ApplicationProtocolSelector selector);
+
+    /**
+     * Returns the tls-unique channel binding value for this connection, per RFC 5929.  This
+     * will return {@code null} if there is no such value available, such as if the handshake
+     * has not yet completed or this connection is closed.
+     */
+    abstract byte[] getTlsUnique();
+
+    /**
+     * Exports a value derived from the TLS master secret as described in RFC 5705.
+     *
+     * @param label the label to use in calculating the exported value.  This must be
+     * an ASCII-only string.
+     * @param context the application-specific context value to use in calculating the
+     * exported value.  This may be {@code null} to use no application context, which is
+     * treated differently than an empty byte array.
+     * @param length the number of bytes of keying material to return.
+     * @return a value of the specified length, or {@code null} if the handshake has not yet
+     * completed or the connection has been closed.
+     * @throws SSLException if the value could not be exported.
+     */
+    abstract byte[] exportKeyingMaterial(String label, byte[] context, int length)
+            throws SSLException;
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java
new file mode 100644
index 0000000..00aeb8b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractConscryptSocket.java
@@ -0,0 +1,774 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Preconditions.checkArgument;
+import static com.android.org.conscrypt.Preconditions.checkNotNull;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SocketChannel;
+import java.security.PrivateKey;
+import java.util.ArrayList;
+import java.util.List;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * Abstract base class for all Conscrypt {@link SSLSocket} classes.
+ */
+abstract class AbstractConscryptSocket extends SSLSocket {
+    final Socket socket;
+    private final boolean autoClose;
+
+    /**
+     * The peer's DNS hostname if it was supplied during creation. Note that
+     * this may be a raw IP address, so it should be checked before use with
+     * extensions that don't use it like Server Name Indication (SNI).
+     */
+    private String peerHostname;
+
+    /**
+     * The peer's port if it was supplied during creation. Should only be set if
+     * {@link #peerHostname} is also set.
+     */
+    private final int peerPort;
+
+    private final PeerInfoProvider peerInfoProvider = new PeerInfoProvider() {
+        @Override
+        String getHostname() {
+            return AbstractConscryptSocket.this.getHostname();
+        }
+
+        @Override
+        String getHostnameOrIP() {
+            return AbstractConscryptSocket.this.getHostnameOrIP();
+        }
+
+        @Override
+        int getPort() {
+            return AbstractConscryptSocket.this.getPort();
+        }
+    };
+
+    private final List<HandshakeCompletedListener> listeners =
+            new ArrayList<HandshakeCompletedListener>(2);
+
+    /**
+     * Local cache of timeout to avoid getsockopt on every read and
+     * write for non-wrapped sockets. Note that this is not used when delegating
+     * to another socket.
+     */
+    private int readTimeoutMilliseconds;
+
+    AbstractConscryptSocket() throws IOException {
+        this.socket = this;
+        this.peerHostname = null;
+        this.peerPort = -1;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(String hostname, int port) throws IOException {
+        super(hostname, port);
+        this.socket = this;
+        this.peerHostname = hostname;
+        this.peerPort = port;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(InetAddress address, int port) throws IOException {
+        super(address, port);
+        this.socket = this;
+        this.peerHostname = null;
+        this.peerPort = -1;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(String hostname, int port, InetAddress clientAddress, int clientPort)
+            throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+        this.socket = this;
+        this.peerHostname = hostname;
+        this.peerPort = port;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(InetAddress address, int port, InetAddress clientAddress,
+            int clientPort) throws IOException {
+        super(address, port, clientAddress, clientPort);
+        this.socket = this;
+        this.peerHostname = null;
+        this.peerPort = -1;
+        this.autoClose = false;
+    }
+
+    AbstractConscryptSocket(Socket socket, String hostname, int port, boolean autoClose)
+            throws IOException {
+        this.socket = checkNotNull(socket, "socket");
+        this.peerHostname = hostname;
+        this.peerPort = port;
+        this.autoClose = autoClose;
+    }
+
+    @Override
+    public final void connect(SocketAddress endpoint) throws IOException {
+        connect(endpoint, 0);
+    }
+
+    /**
+     * Try to extract the peer's hostname if it's available from the endpoint address.
+     */
+    @Override
+    public final void connect(SocketAddress endpoint, int timeout) throws IOException {
+        if (peerHostname == null && endpoint instanceof InetSocketAddress) {
+            peerHostname =
+                    Platform.getHostStringFromInetSocketAddress((InetSocketAddress) endpoint);
+        }
+
+        if (isDelegating()) {
+            socket.connect(endpoint, timeout);
+        } else {
+            super.connect(endpoint, timeout);
+        }
+    }
+
+    @Override
+    public void bind(SocketAddress bindpoint) throws IOException {
+        if (isDelegating()) {
+            socket.bind(bindpoint);
+        } else {
+            super.bind(bindpoint);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void close() throws IOException {
+        if (isDelegating()) {
+            if (autoClose && !socket.isClosed()) {
+                socket.close();
+            }
+        } else {
+            if (!super.isClosed()) {
+                super.close();
+            }
+        }
+    }
+
+    @Override
+    public InetAddress getInetAddress() {
+        if (isDelegating()) {
+            return socket.getInetAddress();
+        }
+        return super.getInetAddress();
+    }
+
+    @Override
+    public InetAddress getLocalAddress() {
+        if (isDelegating()) {
+            return socket.getLocalAddress();
+        }
+        return super.getLocalAddress();
+    }
+
+    @Override
+    public int getLocalPort() {
+        if (isDelegating()) {
+            return socket.getLocalPort();
+        }
+        return super.getLocalPort();
+    }
+
+    @Override
+    public SocketAddress getRemoteSocketAddress() {
+        if (isDelegating()) {
+            return socket.getRemoteSocketAddress();
+        }
+        return super.getRemoteSocketAddress();
+    }
+
+    @Override
+    public SocketAddress getLocalSocketAddress() {
+        if (isDelegating()) {
+            return socket.getLocalSocketAddress();
+        }
+        return super.getLocalSocketAddress();
+    }
+
+    @Override
+    public final int getPort() {
+        if (isDelegating()) {
+            return socket.getPort();
+        }
+
+        if (peerPort != -1) {
+            // Return the port that has been explicitly set in the constructor.
+            return peerPort;
+        }
+        return super.getPort();
+    }
+
+    @Override
+    public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
+        checkArgument(listener != null, "Provided listener is null");
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
+        checkArgument(listener != null, "Provided listener is null");
+        if (!listeners.remove(listener)) {
+            throw new IllegalArgumentException("Provided listener is not registered");
+        }
+    }
+
+    /* @Override */
+    public FileDescriptor getFileDescriptor$() {
+        if (isDelegating()) {
+            return Platform.getFileDescriptor(socket);
+        }
+        return Platform.getFileDescriptorFromSSLSocket(this);
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public final void setSoTimeout(int readTimeoutMilliseconds) throws SocketException {
+        if (isDelegating()) {
+            socket.setSoTimeout(readTimeoutMilliseconds);
+        } else {
+            super.setSoTimeout(readTimeoutMilliseconds);
+            this.readTimeoutMilliseconds = readTimeoutMilliseconds;
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public final int getSoTimeout() throws SocketException {
+        if (isDelegating()) {
+            return socket.getSoTimeout();
+        }
+        return readTimeoutMilliseconds;
+    }
+
+    @Override
+    public final void sendUrgentData(int data) throws IOException {
+        throw new SocketException("Method sendUrgentData() is not supported.");
+    }
+
+    @Override
+    public final void setOOBInline(boolean on) throws SocketException {
+        throw new SocketException("Method setOOBInline() is not supported.");
+    }
+
+    @Override
+    public boolean getOOBInline() throws SocketException {
+        return false;
+    }
+
+    @Override
+    public SocketChannel getChannel() {
+        // TODO(nmittler): Support channels?
+        return null;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        if (isDelegating()) {
+            return socket.getInputStream();
+        }
+        return super.getInputStream();
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        if (isDelegating()) {
+            return socket.getOutputStream();
+        }
+        return super.getOutputStream();
+    }
+
+    @Override
+    public void setTcpNoDelay(boolean on) throws SocketException {
+        if (isDelegating()) {
+            socket.setTcpNoDelay(on);
+        } else {
+            super.setTcpNoDelay(on);
+        }
+    }
+
+    @Override
+    public boolean getTcpNoDelay() throws SocketException {
+        if (isDelegating()) {
+            return socket.getTcpNoDelay();
+        }
+        return super.getTcpNoDelay();
+    }
+
+    @Override
+    public void setSoLinger(boolean on, int linger) throws SocketException {
+        if (isDelegating()) {
+            socket.setSoLinger(on, linger);
+        } else {
+            super.setSoLinger(on, linger);
+        }
+    }
+
+    @Override
+    public int getSoLinger() throws SocketException {
+        if (isDelegating()) {
+            return socket.getSoLinger();
+        }
+        return super.getSoLinger();
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void setSendBufferSize(int size) throws SocketException {
+        if (isDelegating()) {
+            socket.setSendBufferSize(size);
+        } else {
+            super.setSendBufferSize(size);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public int getSendBufferSize() throws SocketException {
+        if (isDelegating()) {
+            return socket.getSendBufferSize();
+        }
+        return super.getSendBufferSize();
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public void setReceiveBufferSize(int size) throws SocketException {
+        if (isDelegating()) {
+            socket.setReceiveBufferSize(size);
+        } else {
+            super.setReceiveBufferSize(size);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public int getReceiveBufferSize() throws SocketException {
+        if (isDelegating()) {
+            return socket.getReceiveBufferSize();
+        }
+        return super.getReceiveBufferSize();
+    }
+
+    @Override
+    public void setKeepAlive(boolean on) throws SocketException {
+        if (isDelegating()) {
+            socket.setKeepAlive(on);
+        } else {
+            super.setKeepAlive(on);
+        }
+    }
+
+    @Override
+    public boolean getKeepAlive() throws SocketException {
+        if (isDelegating()) {
+            return socket.getKeepAlive();
+        }
+        return super.getKeepAlive();
+    }
+
+    @Override
+    public void setTrafficClass(int tc) throws SocketException {
+        if (isDelegating()) {
+            socket.setTrafficClass(tc);
+        } else {
+            super.setTrafficClass(tc);
+        }
+    }
+
+    @Override
+    public int getTrafficClass() throws SocketException {
+        if (isDelegating()) {
+            return socket.getTrafficClass();
+        }
+        return super.getTrafficClass();
+    }
+
+    @Override
+    public void setReuseAddress(boolean on) throws SocketException {
+        if (isDelegating()) {
+            socket.setReuseAddress(on);
+        } else {
+            super.setReuseAddress(on);
+        }
+    }
+
+    @Override
+    public boolean getReuseAddress() throws SocketException {
+        if (isDelegating()) {
+            return socket.getReuseAddress();
+        }
+        return super.getReuseAddress();
+    }
+
+    @Override
+    public void shutdownInput() throws IOException {
+        if (isDelegating()) {
+            socket.shutdownInput();
+        } else {
+            super.shutdownInput();
+        }
+    }
+
+    @Override
+    public void shutdownOutput() throws IOException {
+        if (isDelegating()) {
+            socket.shutdownOutput();
+        } else {
+            super.shutdownOutput();
+        }
+    }
+
+    @Override
+    public boolean isConnected() {
+        if (isDelegating()) {
+            return socket.isConnected();
+        }
+        return super.isConnected();
+    }
+
+    @Override
+    public boolean isBound() {
+        if (isDelegating()) {
+            return socket.isBound();
+        }
+        return super.isBound();
+    }
+
+    @Override
+    public boolean isClosed() {
+        if (isDelegating()) {
+            return socket.isClosed();
+        }
+        return super.isClosed();
+    }
+
+    @Override
+    public boolean isInputShutdown() {
+        if (isDelegating()) {
+            return socket.isInputShutdown();
+        }
+        return super.isInputShutdown();
+    }
+
+    @Override
+    public boolean isOutputShutdown() {
+        if (isDelegating()) {
+            return socket.isOutputShutdown();
+        }
+        return super.isOutputShutdown();
+    }
+
+    @Override
+    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+        if (isDelegating()) {
+            socket.setPerformancePreferences(connectionTime, latency, bandwidth);
+        } else {
+            super.setPerformancePreferences(connectionTime, latency, bandwidth);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("SSL socket over ");
+        if (isDelegating()) {
+            builder.append(socket.toString());
+        } else {
+            builder.append(super.toString());
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Returns the hostname that was supplied during socket creation. No DNS resolution is
+     * attempted before returning the hostname.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    String getHostname() {
+        return peerHostname;
+    }
+
+    /**
+     * This method enables Server Name Indication
+     *
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    void setHostname(String hostname) {
+        peerHostname = hostname;
+    }
+
+    /**
+     * For the purposes of an SSLSession, we want a way to represent the supplied hostname
+     * or the IP address in a textual representation. We do not want to perform reverse DNS
+     * lookups on this address.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    String getHostnameOrIP() {
+        if (peerHostname != null) {
+            return peerHostname;
+        }
+
+        InetAddress peerAddress = getInetAddress();
+        if (peerAddress != null) {
+            return Platform.getOriginalHostNameFromInetAddress(peerAddress);
+        }
+
+        return null;
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+        throw new SocketException("Method setSoWriteTimeout() is not supported.");
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    int getSoWriteTimeout() throws SocketException {
+        return 0;
+    }
+
+    /**
+     * Set the handshake timeout on this socket.  This timeout is specified in
+     * milliseconds and will be used only during the handshake process.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+        throw new SocketException("Method setHandshakeTimeout() is not supported.");
+    }
+
+    final void checkOpen() throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+    }
+
+    final PeerInfoProvider peerInfoProvider() {
+        return peerInfoProvider;
+    }
+
+    /**
+     * Called by {@link #notifyHandshakeCompletedListeners()} to get the currently active session.
+     * Unlike {@link #getSession()}, this method must not block.
+     */
+    abstract SSLSession getActiveSession();
+
+    abstract void setApplicationProtocolSelector(ApplicationProtocolSelectorAdapter selector);
+
+    final void notifyHandshakeCompletedListeners() {
+        if (listeners != null && !listeners.isEmpty()) {
+            // notify the listeners
+            HandshakeCompletedEvent event = new HandshakeCompletedEvent(this, getActiveSession());
+            for (HandshakeCompletedListener listener : listeners) {
+                try {
+                    listener.handshakeCompleted(event);
+                } catch (RuntimeException e) {
+                    // The RI runs the handlers in a separate thread,
+                    // which we do not. But we try to preserve their
+                    // behavior of logging a problem and not killing
+                    // the handshaking thread just because a listener
+                    // has a problem.
+                    Thread thread = Thread.currentThread();
+                    thread.getUncaughtExceptionHandler().uncaughtException(thread, e);
+                }
+            }
+        }
+    }
+
+    private boolean isDelegating() {
+        // Checking for null to handle the case of calling virtual methods in the super class
+        // constructor.
+        return socket != null && socket != this;
+    }
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java 6.
+    public abstract SSLSession getHandshakeSession();
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param useSessionTickets True to enable session tickets
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    abstract void setUseSessionTickets(boolean useSessionTickets);
+
+    /**
+     * Enables/disables TLS Channel ID for this server socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has already
+     *         started.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    abstract void setChannelIdEnabled(boolean enabled);
+
+    /**
+     * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
+     * handshake completes.
+     *
+     * @return channel ID or {@code null} if not available.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has not yet
+     *         completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    abstract byte[] getChannelId() throws SSLException;
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
+     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
+     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
+     *
+     * @throws IllegalStateException if this is a server socket or if the handshake has already
+     *         started.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    abstract void setChannelIdPrivateKey(PrivateKey privateKey);
+
+    /**
+     * Returns null always for backward compatibility.
+     * @deprecated NPN is not supported
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Deprecated
+    byte[] getNpnSelectedProtocol() {
+        return null;
+    }
+
+    /**
+     * This method does nothing and is kept for backward compatibility.
+     * @deprecated NPN is not supported
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Deprecated
+    void setNpnProtocols(byte[] npnProtocols) {}
+
+    /**
+     * Returns the protocol agreed upon by client and server, or {@code null} if
+     * no protocol was agreed upon.
+     *
+     * @deprecated use {@link #getApplicationProtocol()} instead.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Deprecated
+    abstract byte[] getAlpnSelectedProtocol();
+
+    /**
+     * Sets the list of ALPN protocols. This method internally converts the protocols to their
+     * wire-format form.
+     *
+     * @param alpnProtocols the list of ALPN protocols
+     * @deprecated use {@link #setApplicationProtocols(String[])} instead.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Deprecated
+    abstract void setAlpnProtocols(String[] alpnProtocols);
+
+    /**
+     * Alternate version of {@link #setAlpnProtocols(String[])} that directly sets the list of
+     * ALPN in the wire-format form used by BoringSSL (length-prefixed 8-bit strings).
+     * Requires that all strings be encoded with US-ASCII.
+     *
+     * @param alpnProtocols the encoded form of the ALPN protocol list
+     * @deprecated Use {@link #setApplicationProtocols(String[])} instead.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Deprecated
+    abstract void setAlpnProtocols(byte[] alpnProtocols);
+
+    /**
+     * Sets the list of ALPN protocols.
+     *
+     * @param protocols the list of ALPN protocols
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @SuppressWarnings("MissingOverride") // For compiling pre Java 9.
+    abstract void setApplicationProtocols(String[] protocols);
+
+    /**
+     * Returns the list of supported ALPN protocols.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @SuppressWarnings("MissingOverride") // For compiling pre Java 9.
+    abstract String[] getApplicationProtocols();
+
+    @SuppressWarnings("MissingOverride") // For compiling pre Java 9.
+    public abstract String getApplicationProtocol();
+
+    @SuppressWarnings("MissingOverride") // For compiling pre Java 9.
+    public abstract String getHandshakeApplicationProtocol();
+
+    /**
+     * Sets an application-provided ALPN protocol selector. If provided, this will override
+     * the list of protocols set by {@link #setApplicationProtocols(String[])}.
+     */
+    abstract void setApplicationProtocolSelector(ApplicationProtocolSelector selector);
+
+    /**
+     * Returns the tls-unique channel binding value for this connection, per RFC 5929.  This
+     * will return {@code null} if there is no such value available, such as if the handshake
+     * has not yet completed or this connection is closed.
+     */
+    abstract byte[] getTlsUnique();
+
+    /**
+     * Exports a value derived from the TLS master secret as described in RFC 5705.
+     *
+     * @param label the label to use in calculating the exported value.  This must be
+     * an ASCII-only string.
+     * @param context the application-specific context value to use in calculating the
+     * exported value.  This may be {@code null} to use no application context, which is
+     * treated differently than an empty byte array.
+     * @param length the number of bytes of keying material to return.
+     * @return a value of the specified length, or {@code null} if the handshake has not yet
+     * completed or the connection has been closed.
+     * @throws SSLException if the value could not be exported.
+     */
+    abstract byte[] exportKeyingMaterial(String label, byte[] context, int length)
+            throws SSLException;
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractSessionContext.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractSessionContext.java
new file mode 100644
index 0000000..d777735
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AbstractSessionContext.java
@@ -0,0 +1,305 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * Supports SSL session caches.
+ */
+abstract class AbstractSessionContext implements SSLSessionContext {
+
+    /**
+     * Maximum lifetime of a session (in seconds) after which it's considered invalid and should not
+     * be used to for new connections.
+     */
+    private static final int DEFAULT_SESSION_TIMEOUT_SECONDS = 8 * 60 * 60;
+
+    private volatile int maximumSize;
+    private volatile int timeout = DEFAULT_SESSION_TIMEOUT_SECONDS;
+
+    final long sslCtxNativePointer = NativeCrypto.SSL_CTX_new();
+
+    @SuppressWarnings("serial")
+    private final Map<ByteArray, NativeSslSession> sessions =
+            new LinkedHashMap<ByteArray, NativeSslSession>() {
+                @Override
+                protected boolean removeEldestEntry(
+                        Map.Entry<ByteArray, NativeSslSession> eldest) {
+                    // NOTE: does not take into account any session that may have become
+                    // invalid.
+                    if (maximumSize > 0 && size() > maximumSize) {
+                        // Let the subclass know.
+                        onBeforeRemoveSession(eldest.getValue());
+                        return true;
+                    }
+                    return false;
+                }
+            };
+
+    /**
+     * Constructs a new session context.
+     *
+     * @param maximumSize of cache
+     */
+    AbstractSessionContext(int maximumSize) {
+        this.maximumSize = maximumSize;
+    }
+
+    /**
+     * This method is provided for API-compatibility only, not intended for use. No guarantees
+     * are made WRT performance.
+     */
+    @Override
+    public final Enumeration<byte[]> getIds() {
+        // Make a copy of the IDs.
+        final Iterator<NativeSslSession> iter;
+        synchronized (sessions) {
+            iter = Arrays.asList(sessions.values().toArray(new NativeSslSession[sessions.size()]))
+                    .iterator();
+        }
+        return new Enumeration<byte[]>() {
+            private NativeSslSession next;
+
+            @Override
+            public boolean hasMoreElements() {
+                if (next != null) {
+                    return true;
+                }
+                while (iter.hasNext()) {
+                    NativeSslSession session = iter.next();
+                    if (session.isValid()) {
+                        next = session;
+                        return true;
+                    }
+                }
+                next = null;
+                return false;
+            }
+
+            @Override
+            public byte[] nextElement() {
+                if (hasMoreElements()) {
+                    byte[] id = next.getId();
+                    next = null;
+                    return id;
+                }
+                throw new NoSuchElementException();
+            }
+        };
+    }
+
+    /**
+     * This is provided for API-compatibility only, not intended for use. No guarantees are
+     * made WRT performance or the validity of the returned session.
+     */
+    @Override
+    public final SSLSession getSession(byte[] sessionId) {
+        if (sessionId == null) {
+            throw new NullPointerException("sessionId");
+        }
+        ByteArray key = new ByteArray(sessionId);
+        NativeSslSession session;
+        synchronized (sessions) {
+            session = sessions.get(key);
+        }
+        if (session != null && session.isValid()) {
+            return session.toSSLSession();
+        }
+        return null;
+    }
+
+    @Override
+    public final int getSessionCacheSize() {
+        return maximumSize;
+    }
+
+    @Override
+    public final int getSessionTimeout() {
+        return timeout;
+    }
+
+    @Override
+    public final void setSessionTimeout(int seconds) throws IllegalArgumentException {
+        if (seconds < 0) {
+            throw new IllegalArgumentException("seconds < 0");
+        }
+
+        synchronized (sessions) {
+            // Set the timeout on this context.
+            timeout = seconds;
+            // setSessionTimeout(0) is defined to remove the timeout, but passing 0
+            // to SSL_CTX_set_timeout in BoringSSL sets it to the default timeout instead.
+            // Pass INT_MAX seconds (68 years), since that's equivalent for practical purposes.
+            if (seconds > 0) {
+                NativeCrypto.SSL_CTX_set_timeout(sslCtxNativePointer, this, seconds);
+            } else {
+                NativeCrypto.SSL_CTX_set_timeout(sslCtxNativePointer, this, Integer.MAX_VALUE);
+            }
+
+            Iterator<NativeSslSession> i = sessions.values().iterator();
+            while (i.hasNext()) {
+                NativeSslSession session = i.next();
+                // SSLSession's know their context and consult the
+                // timeout as part of their validity condition.
+                if (!session.isValid()) {
+                    // Let the subclass know.
+                    onBeforeRemoveSession(session);
+                    i.remove();
+                }
+            }
+        }
+    }
+
+    @Override
+    public final void setSessionCacheSize(int size) throws IllegalArgumentException {
+        if (size < 0) {
+            throw new IllegalArgumentException("size < 0");
+        }
+
+        int oldMaximum = maximumSize;
+        maximumSize = size;
+
+        // Trim cache to size if necessary.
+        if (size < oldMaximum) {
+            trimToSize();
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            NativeCrypto.SSL_CTX_free(sslCtxNativePointer, this);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Adds the given session to the cache.
+     */
+    final void cacheSession(NativeSslSession session) {
+        byte[] id = session.getId();
+        if (id == null || id.length == 0) {
+            return;
+        }
+
+        synchronized (sessions) {
+            ByteArray key = new ByteArray(id);
+            if (sessions.containsKey(key)) {
+                removeSession(sessions.get(key));
+            }
+            // Let the subclass know.
+            onBeforeAddSession(session);
+
+            sessions.put(key, session);
+        }
+    }
+
+    /**
+     * Removes the given session from the cache.
+     */
+    final void removeSession(NativeSslSession session) {
+        byte[] id = session.getId();
+        if (id == null || id.length == 0) {
+            return;
+        }
+
+        onBeforeRemoveSession(session);
+
+        ByteArray key = new ByteArray(id);
+        synchronized (sessions) {
+            sessions.remove(key);
+        }
+    }
+
+    /**
+     * Called for server sessions only. Retrieves the session by its ID. Overridden by
+     * {@link ServerSessionContext} to
+     */
+    final NativeSslSession getSessionFromCache(byte[] sessionId) {
+        if (sessionId == null) {
+            return null;
+        }
+
+        // First, look in the in-memory cache.
+        NativeSslSession session;
+        synchronized (sessions) {
+            session = sessions.get(new ByteArray(sessionId));
+        }
+        if (session != null && session.isValid()) {
+            if (session.isSingleUse()) {
+                removeSession(session);
+            }
+            return session;
+        }
+
+        // Look in persistent cache.  We don't currently delete sessions from the persistent
+        // cache, so we may find a multi-use (aka TLS 1.2) session after having received and
+        // then used up one or more single-use (aka TLS 1.3) sessions.
+        return getSessionFromPersistentCache(sessionId);
+    }
+
+    /**
+     * Called when the given session is about to be added. Used by {@link ClientSessionContext} to
+     * update its host-and-port based cache.
+     *
+     * <p>Visible for extension only, not intended to be called directly.
+     */
+    abstract void onBeforeAddSession(NativeSslSession session);
+
+    /**
+     * Called when a session is about to be removed. Used by {@link ClientSessionContext}
+     * to update its host-and-port based cache.
+     *
+     * <p>Visible for extension only, not intended to be called directly.
+     */
+    abstract void onBeforeRemoveSession(NativeSslSession session);
+
+    /**
+     * Called for server sessions only. Retrieves the session by ID from the persistent cache.
+     *
+     * <p>Visible for extension only, not intended to be called directly.
+     */
+    abstract NativeSslSession getSessionFromPersistentCache(byte[] sessionId);
+
+    /**
+     * Makes sure cache size is < maximumSize.
+     */
+    private void trimToSize() {
+        synchronized (sessions) {
+            int size = sessions.size();
+            if (size > maximumSize) {
+                int removals = size - maximumSize;
+                Iterator<NativeSslSession> i = sessions.values().iterator();
+                while (removals-- > 0) {
+                    NativeSslSession session = i.next();
+                    onBeforeRemoveSession(session);
+                    i.remove();
+                }
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ActiveSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ActiveSession.java
new file mode 100644
index 0000000..a6ac475
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ActiveSession.java
@@ -0,0 +1,326 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Preconditions.checkNotNull;
+
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * A session that is dedicated a single connection and operates directly on the underlying
+ * {@code SSL}.
+ */
+final class ActiveSession implements ConscryptSession {
+    private final NativeSsl ssl;
+    private AbstractSessionContext sessionContext;
+    private byte[] id;
+    private long creationTime;
+    private String protocol;
+    private String peerHost;
+    private int peerPort = -1;
+    private long lastAccessedTime = 0;
+    private volatile javax.security.cert.X509Certificate[] peerCertificateChain;
+    private X509Certificate[] localCertificates;
+    private X509Certificate[] peerCertificates;
+    private byte[] peerCertificateOcspData;
+    private byte[] peerTlsSctData;
+
+    ActiveSession(NativeSsl ssl, AbstractSessionContext sessionContext) {
+        this.ssl = checkNotNull(ssl, "ssl");
+        this.sessionContext = checkNotNull(sessionContext, "sessionContext");
+    }
+
+    @Override
+    public byte[] getId() {
+        if (id == null) {
+            synchronized (ssl) {
+                id = ssl.getSessionId();
+            }
+        }
+        return id != null ? id.clone() : EmptyArray.BYTE;
+    }
+
+    @Override
+    public SSLSessionContext getSessionContext() {
+        return isValid() ? sessionContext : null;
+    }
+
+    @Override
+    public long getCreationTime() {
+        if (creationTime == 0) {
+            synchronized (ssl) {
+                creationTime = ssl.getTime();
+            }
+        }
+        return creationTime;
+    }
+
+    /**
+     * Returns the last time this SSL session was accessed. Accessing
+     * here is to mean that a new connection with the same SSL context data was
+     * established.
+     *
+     * @return the session's last access time in milliseconds since the epoch
+     */
+    // TODO(nathanmittler): Does lastAccessedTime need to account for session reuse?
+    @Override
+    public long getLastAccessedTime() {
+        return lastAccessedTime == 0 ? getCreationTime() : lastAccessedTime;
+    }
+
+    void setLastAccessedTime(long accessTimeMillis) {
+        lastAccessedTime = accessTimeMillis;
+    }
+
+    /**
+     * Returns the OCSP stapled response. Returns a copy of the internal arrays.
+     *
+     * The method signature matches
+     * <a
+     * href="http://download.java.net/java/jdk9/docs/api/javax/net/ssl/ExtendedSSLSession.html#getStatusResponses--">Java
+     * 9</a>.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc6066">RFC 6066</a>
+     * @see <a href="https://tools.ietf.org/html/rfc6961">RFC 6961</a>
+     */
+    @Override
+    public List<byte[]> getStatusResponses() {
+        if (peerCertificateOcspData == null) {
+            return Collections.<byte[]>emptyList();
+        }
+
+        return Collections.singletonList(peerCertificateOcspData.clone());
+    }
+
+    /**
+     * Returns the signed certificate timestamp (SCT) received from the peer. Returns a
+     * copy of the internal array.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc6962">RFC 6962</a>
+     */
+    @Override
+    public byte[] getPeerSignedCertificateTimestamp() {
+        if (peerTlsSctData == null) {
+            return null;
+        }
+        return peerTlsSctData.clone();
+    }
+
+    @Override
+    public String getRequestedServerName() {
+        synchronized (ssl) {
+            return ssl.getRequestedServerName();
+        }
+    }
+
+    @Override
+    public void invalidate() {
+        synchronized (ssl) {
+            ssl.setTimeout(0L);
+        }
+    }
+
+    @Override
+    public boolean isValid() {
+        synchronized (ssl) {
+            long creationTimeMillis = ssl.getTime();
+            long timeoutMillis = ssl.getTimeout();
+            return (System.currentTimeMillis() - timeoutMillis) < creationTimeMillis;
+        }
+    }
+
+    @Override
+    public void putValue(String name, Object value) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public Object getValue(String name) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public void removeValue(String name) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public String[] getValueNames() {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public X509Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+        checkPeerCertificatesPresent();
+        return peerCertificates.clone();
+    }
+
+    @Override
+    public Certificate[] getLocalCertificates() {
+        // Local certificates never change, so set them locally as soon as they're available
+        if (localCertificates == null) {
+            synchronized (ssl) {
+                localCertificates = ssl.getLocalCertificates();
+            }
+        }
+        return localCertificates == null ? null : localCertificates.clone();
+    }
+
+    /**
+     * Returns the certificate(s) of the peer in this SSL session
+     * used in the handshaking phase of the connection.
+     * Please notice hat this method is superseded by
+     * <code>getPeerCertificates()</code>.
+     * @return an array of X509 certificates (the peer's one first and then
+     *         eventually that of the certification authority) or null if no
+     *         certificate were used during the SSL connection.
+     * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
+     *         was used (i.e. Kerberos certificates) or the peer could not
+     *         be verified.
+     */
+    @Override
+    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
+            throws SSLPeerUnverifiedException {
+        checkPeerCertificatesPresent();
+        // TODO(nathanmittler): Should we clone?
+        javax.security.cert.X509Certificate[] result = peerCertificateChain;
+        if (result == null) {
+            // single-check idiom
+            peerCertificateChain = result = SSLUtils.toCertificateChain(peerCertificates);
+        }
+        return result;
+    }
+
+    @Override
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        checkPeerCertificatesPresent();
+        return peerCertificates[0].getSubjectX500Principal();
+    }
+
+    @Override
+    public Principal getLocalPrincipal() {
+        X509Certificate[] certs = (X509Certificate[]) getLocalCertificates();
+        if (certs != null && certs.length > 0) {
+            return certs[0].getSubjectX500Principal();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public String getCipherSuite() {
+        // Always get the Cipher from the SSL directly since it may have changed during a
+        // renegotiation.
+        String cipher;
+        synchronized (ssl) {
+            cipher = ssl.getCipherSuite();
+        }
+        return cipher == null ? SSLNullSession.INVALID_CIPHER : cipher;
+    }
+
+    @Override
+    public String getProtocol() {
+        String protocol = this.protocol;
+        if (protocol == null) {
+            synchronized (ssl) {
+                protocol = ssl.getVersion();
+            }
+            this.protocol = protocol;
+        }
+        return protocol;
+    }
+
+    @Override
+    public String getPeerHost() {
+        return peerHost;
+    }
+
+    @Override
+    public int getPeerPort() {
+        return peerPort;
+    }
+
+    @Override
+    public int getPacketBufferSize() {
+        return NativeConstants.SSL3_RT_MAX_PACKET_SIZE;
+    }
+
+    @Override
+    public int getApplicationBufferSize() {
+        return NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH;
+    }
+
+    /**
+     * Configures the peer information once it has been received by the handshake.
+     */
+    void onPeerCertificatesReceived(
+            String peerHost, int peerPort, X509Certificate[] peerCertificates) {
+        configurePeer(peerHost, peerPort, peerCertificates);
+    }
+
+    private void configurePeer(String peerHost, int peerPort, X509Certificate[] peerCertificates) {
+        this.peerHost = peerHost;
+        this.peerPort = peerPort;
+        this.peerCertificates = peerCertificates;
+        synchronized (ssl) {
+            this.peerCertificateOcspData = ssl.getPeerCertificateOcspData();
+            this.peerTlsSctData = ssl.getPeerTlsSctData();
+        }
+    }
+
+    /**
+     * Updates the cached peer certificate after the handshake has completed
+     * (or entered False Start).
+     */
+    void onPeerCertificateAvailable(String peerHost, int peerPort) throws CertificateException {
+        synchronized (ssl) {
+            id = null;
+            if (localCertificates == null) {
+                this.localCertificates = ssl.getLocalCertificates();
+            }
+            if (this.peerCertificates == null) {
+                // When resuming a session, the cert_verify_callback (which calls
+                // onPeerCertificatesReceived) isn't called by BoringSSL during the handshake
+                // because it presumes the certs were verified in the previous connection on that
+                // session, leaving us without the peer certificates.  If that happens, fetch them
+                // explicitly.
+                configurePeer(peerHost, peerPort, ssl.getPeerCertificates());
+            }
+        }
+    }
+
+    /**
+     * Throw SSLPeerUnverifiedException on null or empty peerCertificates array
+     */
+    private void checkPeerCertificatesPresent() throws SSLPeerUnverifiedException {
+        if (peerCertificates == null || peerCertificates.length == 0) {
+            throw new SSLPeerUnverifiedException("No peer certificates");
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java
new file mode 100644
index 0000000..bdd7c97
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AddressUtils.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import java.util.regex.Pattern;
+
+/**
+ * Utilities to check whether IP addresses meet some criteria.
+ */
+final class AddressUtils {
+    /*
+     * Regex that matches valid IPv4 and IPv6 addresses.
+     */
+    private static final String IP_PATTERN =
+            "^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]))|"
+            + "(?i:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(?:%.+)?$";
+
+    private static Pattern ipPattern;
+
+    private AddressUtils() {}
+
+    /**
+     * Returns true when the supplied hostname is valid for SNI purposes.
+     */
+    static boolean isValidSniHostname(String sniHostname) {
+        if (sniHostname == null) {
+            return false;
+        }
+
+        // Must be a FQDN that does not have a trailing dot.
+        return (sniHostname.equalsIgnoreCase("localhost") || sniHostname.indexOf('.') != -1)
+                && !isLiteralIpAddress(sniHostname) && !sniHostname.endsWith(".")
+                && sniHostname.indexOf('\0') == -1;
+    }
+
+    /**
+     * Returns true if the supplied hostname is an literal IP address.
+     */
+    static boolean isLiteralIpAddress(String hostname) {
+        /* This is here for backwards compatibility for pre-Honeycomb devices. */
+        Pattern ipPattern = AddressUtils.ipPattern;
+        if (ipPattern == null) {
+            AddressUtils.ipPattern = ipPattern = Pattern.compile(IP_PATTERN);
+        }
+        return ipPattern.matcher(hostname).matches();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/AllocatedBuffer.java b/repackaged/common/src/main/java/com/android/org/conscrypt/AllocatedBuffer.java
new file mode 100644
index 0000000..cc1bc07
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/AllocatedBuffer.java
@@ -0,0 +1,88 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*
+ * Copyright 2013 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Preconditions.checkNotNull;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A buffer that was allocated by a {@link BufferAllocator}.
+ * @hide This class is not part of the Android public SDK API
+ */
+@ExperimentalApi
+public abstract class AllocatedBuffer {
+    /**
+     * Returns the {@link ByteBuffer} that backs this buffer.
+     */
+    public abstract ByteBuffer nioBuffer();
+
+    /**
+     * Returns the current instance for backward compatibility.
+     *
+     * @deprecated this method is not used
+     */
+    @Deprecated
+    public AllocatedBuffer retain() {
+        // Do nothing.
+        return this;
+    }
+
+    /**
+     * Returns the delegate {@link ByteBuffer} for reuse or garbage collection.
+     *
+     * @return this {@link AllocatedBuffer} instance
+     */
+    public abstract AllocatedBuffer release();
+
+    /**
+     * Creates a new {@link AllocatedBuffer} that is backed by the given {@link ByteBuffer}.
+     */
+    public static AllocatedBuffer wrap(final ByteBuffer buffer) {
+        checkNotNull(buffer, "buffer");
+
+        return new AllocatedBuffer() {
+
+            @Override
+            public ByteBuffer nioBuffer() {
+                return buffer;
+            }
+
+            @Override
+            public AllocatedBuffer release() {
+                // Do nothing.
+                return this;
+            }
+        };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ApplicationProtocolSelector.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ApplicationProtocolSelector.java
new file mode 100644
index 0000000..6ac4713
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ApplicationProtocolSelector.java
@@ -0,0 +1,58 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.util.List;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * Server-side selector for the ALPN protocol. This is a backward-compatibility shim for Java 9's
+ * new {@code setHandshakeApplicationProtocolSelector} API, which takes a {@code BiFunction}
+ * (available in Java 8+). This interface is provided to support protocol selection in Java < 8.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ApplicationProtocolSelector {
+    /**
+     * Selects the appropriate ALPN protocol.
+     *
+     * @param engine the server-side engine
+     * @param protocols The list of client-supplied protocols
+     * @return The function's result is an application protocol name, or {@code null} to indicate
+     * that none of the advertised names are acceptable. If the return value is an empty
+     * {@link String} then application protocol indications will not be used. If the return value
+     * is {@code null} (no value chosen) or is a value that was not advertised by the peer, a
+     * "no_application_protocol" alert will be sent to the peer and the connection will be
+     * terminated.
+     */
+    public abstract String selectApplicationProtocol(SSLEngine engine, List<String> protocols);
+
+    /**
+     * Selects the appropriate ALPN protocol.
+     *
+     * @param socket the server-side socket
+     * @param protocols The list of client-supplied protocols
+     * @return The function's result is an application protocol name, or {@code null} to indicate
+     * that none of the advertised names are acceptable. If the return value is an empty
+     * {@link String} then application protocol indications will not be used. If the return value
+     * is {@code null} (no value chosen) or is a value that was not advertised by the peer, a
+     * "no_application_protocol" alert will be sent to the peer and the connection will be
+     * terminated.
+     */
+    public abstract String selectApplicationProtocol(SSLSocket socket, List<String> protocols);
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ApplicationProtocolSelectorAdapter.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ApplicationProtocolSelectorAdapter.java
new file mode 100644
index 0000000..64f5dce
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ApplicationProtocolSelectorAdapter.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Preconditions.checkNotNull;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * An adapter to bridge between the native code and the {@link ApplicationProtocolSelector} API.
+ */
+final class ApplicationProtocolSelectorAdapter {
+    private static final int NO_PROTOCOL_SELECTED = -1;
+
+    private final SSLEngine engine;
+    private final SSLSocket socket;
+    private final ApplicationProtocolSelector selector;
+
+    ApplicationProtocolSelectorAdapter(SSLEngine engine, ApplicationProtocolSelector selector) {
+        this.engine = checkNotNull(engine, "engine");
+        this.socket = null;
+        this.selector = checkNotNull(selector, "selector");
+    }
+
+    ApplicationProtocolSelectorAdapter(SSLSocket socket, ApplicationProtocolSelector selector) {
+        this.engine = null;
+        this.socket = checkNotNull(socket, "socket");
+        this.selector = checkNotNull(selector, "selector");
+    }
+
+    /**
+     * Performs the ALPN protocol selection from the given list of length-delimited peer protocols.
+     * @param encodedProtocols the peer protocols in length-delimited form.
+     * @return If successful, returns the offset into the {@code lenghPrefixedList} array of the
+     * selected protocol (i.e. points to the length prefix). Otherwise, returns
+     * {@link #NO_PROTOCOL_SELECTED}.
+     */
+    int selectApplicationProtocol(byte[] encodedProtocols) {
+        if (encodedProtocols == null || encodedProtocols.length == 0) {
+            return NO_PROTOCOL_SELECTED;
+        }
+
+        // Decode the protocols.
+        List<String> protocols = Arrays.asList(SSLUtils.decodeProtocols(encodedProtocols));
+
+        // Select the protocol.
+        final String selected;
+        if (engine != null ) {
+            selected = selector.selectApplicationProtocol(engine, protocols);
+        } else {
+            selected = selector.selectApplicationProtocol(socket, protocols);
+        }
+        if (selected == null || selected.isEmpty()) {
+            return NO_PROTOCOL_SELECTED;
+        }
+
+        int offset = 0;
+        for (String protocol : protocols) {
+            if (selected.equals(protocol)) {
+                // Found the selected protocol. Return the index position of the beginning of
+                // the protocol.
+                return offset;
+            }
+
+            // Add 1 byte for the length prefix.
+            offset += 1 + protocol.length();
+        }
+
+        return NO_PROTOCOL_SELECTED;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java
new file mode 100644
index 0000000..49a06c0
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ArrayUtils.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+/**
+ * Compatibility utility for Arrays.
+ */
+final class ArrayUtils {
+    private ArrayUtils() {}
+
+    /**
+     * Checks that the range described by {@code offset} and {@code count}
+     * doesn't exceed {@code arrayLength}.
+     */
+    static void checkOffsetAndCount(int arrayLength, int offset, int count) {
+        if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
+            throw new ArrayIndexOutOfBoundsException("length=" + arrayLength + "; regionStart="
+                    + offset + "; regionLength=" + count);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/BufferAllocator.java b/repackaged/common/src/main/java/com/android/org/conscrypt/BufferAllocator.java
new file mode 100644
index 0000000..6dc1e75
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/BufferAllocator.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+
+/**
+ * An object responsible for allocation of buffers. This is an extension point to enable buffer
+ * pooling within an application.
+ * @hide This class is not part of the Android public SDK API
+ */
+@ExperimentalApi
+public abstract class BufferAllocator {
+    private static final BufferAllocator UNPOOLED = new BufferAllocator() {
+        @Override
+        public AllocatedBuffer allocateDirectBuffer(int capacity) {
+            return AllocatedBuffer.wrap(ByteBuffer.allocateDirect(capacity));
+        }
+    };
+
+    /**
+     * Returns an unpooled buffer allocator, which will create a new buffer for each request.
+     */
+    public static BufferAllocator unpooled() {
+        return UNPOOLED;
+    }
+
+    /**
+     * Allocates a direct (i.e. non-heap) buffer with the given capacity.
+     */
+    public abstract AllocatedBuffer allocateDirectBuffer(int capacity);
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java
new file mode 100644
index 0000000..c4f7da3
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ByteArray.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt;
+
+import java.util.Arrays;
+
+/**
+ * Byte array wrapper for hashtable use. Implements equals() and hashCode().
+ */
+final class ByteArray {
+    private final byte[] bytes;
+    private final int hashCode;
+
+    ByteArray(byte[] bytes) {
+        this.bytes = bytes;
+        this.hashCode = Arrays.hashCode(bytes);
+    }
+
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof ByteArray)) {
+            return false;
+        }
+        ByteArray lhs = (ByteArray) o;
+        return Arrays.equals(bytes, lhs.bytes);
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/CertBlacklist.java b/repackaged/common/src/main/java/com/android/org/conscrypt/CertBlacklist.java
new file mode 100644
index 0000000..cecc8ba
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/CertBlacklist.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2018 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 com.android.org.conscrypt;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+
+/**
+ * A set of certificates that are blacklisted from trust.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CertBlacklist {
+
+    /**
+     * Returns whether the given public key is in the blacklist.
+     */
+    boolean isPublicKeyBlackListed(PublicKey publicKey);
+
+    /**
+     * Returns whether the given serial number is in the blacklist.
+     */
+    boolean isSerialNumberBlackListed(BigInteger serial);
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/CertPinManager.java b/repackaged/common/src/main/java/com/android/org/conscrypt/CertPinManager.java
new file mode 100644
index 0000000..ff3bda2
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/CertPinManager.java
@@ -0,0 +1,38 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+/**
+ * Interface for classes that implement certificate pinning for use in {@link TrustManagerImpl}.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public interface CertPinManager {
+    /**
+     * Given a {@code hostname} and a {@code chain} this verifies that the
+     * certificate chain includes pinned certificates if pinning is requested
+     * for {@code hostname}.
+     */
+    void checkChainPinning(String hostname, List<X509Certificate> chain)
+            throws CertificateException;
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/CertificatePriorityComparator.java b/repackaged/common/src/main/java/com/android/org/conscrypt/CertificatePriorityComparator.java
new file mode 100644
index 0000000..34d6222
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/CertificatePriorityComparator.java
@@ -0,0 +1,170 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.org.conscrypt;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * {@link Comparator} for prioritizing certificates in path building.
+ *
+ * <p>
+ * The sort order is as follows:
+ * <ol>
+ * <li>Self-issued certificates first.</li>
+ * <li>Strength of certificates descending (EC before RSA, key size descending, signature
+ * algorithm strength descending).</li>
+ * <li>notAfter date descending.</li>
+ * <li>notBefore date descending.</li>
+ * </ol>
+ * </p>
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class CertificatePriorityComparator implements Comparator<X509Certificate> {
+
+    /**
+     * Map of signature algorithm OIDs to priorities. OIDs with a lower priority will be sorted
+     * before those with higher.
+     */
+    private static final Map<String, Integer> ALGORITHM_OID_PRIORITY_MAP;
+
+    /*
+     * Priorities of digest algorithms. Lower is better.
+     */
+    private static final Integer PRIORITY_MD5 = 6;
+    private static final Integer PRIORITY_SHA1 = 5;
+    private static final Integer PRIORITY_SHA224 = 4;
+    private static final Integer PRIORITY_SHA256 = 3;
+    private static final Integer PRIORITY_SHA384 = 2;
+    private static final Integer PRIORITY_SHA512 = 1;
+    private static final Integer PRIORITY_UNKNOWN = -1;
+    static {
+        ALGORITHM_OID_PRIORITY_MAP = new HashMap<String, Integer>();
+        // RSA oids
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.113549.1.1.13", PRIORITY_SHA512);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.113549.1.1.12", PRIORITY_SHA384);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.113549.1.1.11", PRIORITY_SHA256);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.113549.1.1.14", PRIORITY_SHA224);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.113549.1.1.5", PRIORITY_SHA1);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.113549.1.1.4", PRIORITY_MD5);
+        // ECDSA oids
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.10045.4.3.4", PRIORITY_SHA512);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.10045.4.3.3", PRIORITY_SHA384);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.10045.4.3.2", PRIORITY_SHA256);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.10045.4.3.1", PRIORITY_SHA224);
+        ALGORITHM_OID_PRIORITY_MAP.put("1.2.840.10045.4.1", PRIORITY_SHA1);
+    }
+
+    @Override
+    public int compare(X509Certificate lhs, X509Certificate rhs) {
+        int result;
+        boolean lhsSelfSigned = lhs.getSubjectDN().equals(lhs.getIssuerDN());
+        boolean rhsSelfSigned = rhs.getSubjectDN().equals(rhs.getIssuerDN());
+        // Self-issued before not self-issued to avoid trying bridge certs first.
+        if (lhsSelfSigned != rhsSelfSigned) {
+            return rhsSelfSigned ? 1 : -1;
+        }
+        // Strength descending.
+        result = compareStrength(rhs, lhs);
+        if (result != 0) {
+            return result;
+        }
+        // notAfter descending.
+        Date lhsNotAfter = lhs.getNotAfter();
+        Date rhsNotAfter = rhs.getNotAfter();
+        result = rhsNotAfter.compareTo(lhsNotAfter);
+        if (result != 0) {
+            return result;
+        }
+        // notBefore descending.
+        Date lhsNotBefore = lhs.getNotBefore();
+        Date rhsNotBefore = rhs.getNotBefore();
+        return rhsNotBefore.compareTo(lhsNotBefore);
+    }
+
+    private int compareStrength(X509Certificate lhs, X509Certificate rhs) {
+        int result;
+        PublicKey lhsPublicKey = lhs.getPublicKey();
+        PublicKey rhsPublicKey = rhs.getPublicKey();
+        result = compareKeyAlgorithm(lhsPublicKey, rhsPublicKey);
+        if (result != 0) {
+            return result;
+        }
+        result = compareKeySize(lhsPublicKey, rhsPublicKey);
+        if (result != 0) {
+            return result;
+        }
+        return compareSignatureAlgorithm(lhs, rhs);
+    }
+
+    private int compareKeyAlgorithm(PublicKey lhs, PublicKey rhs) {
+        String lhsAlgorithm = lhs.getAlgorithm();
+        String rhsAlgorithm = rhs.getAlgorithm();
+
+        if (lhsAlgorithm.equalsIgnoreCase(rhsAlgorithm)) {
+            return 0;
+        }
+
+        // Prefer EC to RSA.
+        if ("EC".equalsIgnoreCase(lhsAlgorithm)) {
+            return 1;
+        } else {
+            return -1;
+        }
+    }
+
+    private int compareKeySize(PublicKey lhs, PublicKey rhs) {
+        String lhsAlgorithm = lhs.getAlgorithm();
+        String rhsAlgorithm = rhs.getAlgorithm();
+        if (!lhsAlgorithm.equalsIgnoreCase(rhsAlgorithm)) {
+            throw new IllegalArgumentException("Keys are not of the same type");
+        }
+        int lhsSize = getKeySize(lhs);
+        int rhsSize = getKeySize(rhs);
+        return lhsSize - rhsSize;
+    }
+
+    private int getKeySize(PublicKey pkey) {
+        if (pkey instanceof ECPublicKey) {
+            return ((ECPublicKey) pkey).getParams().getCurve().getField().getFieldSize();
+        } else if (pkey instanceof RSAPublicKey) {
+            return ((RSAPublicKey) pkey).getModulus().bitLength();
+        } else {
+            throw new IllegalArgumentException(
+                    "Unsupported public key type: " + pkey.getClass().getName());
+        }
+    }
+
+    private int compareSignatureAlgorithm(X509Certificate lhs, X509Certificate rhs) {
+        Integer lhsPriority = ALGORITHM_OID_PRIORITY_MAP.get(lhs.getSigAlgOID());
+        Integer rhsPriority = ALGORITHM_OID_PRIORITY_MAP.get(rhs.getSigAlgOID());
+        if (lhsPriority == null) {
+            lhsPriority = PRIORITY_UNKNOWN;
+        }
+        if (rhsPriority == null) {
+            rhsPriority = PRIORITY_UNKNOWN;
+        }
+        return rhsPriority - lhsPriority;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ChainStrengthAnalyzer.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ChainStrengthAnalyzer.java
new file mode 100644
index 0000000..e34f8c5
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ChainStrengthAnalyzer.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.List;
+
+/**
+ * Analyzes the cryptographic strength of a chain of X.509 certificates.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class ChainStrengthAnalyzer {
+
+    private static final int MIN_RSA_MODULUS_LEN_BITS = 1024;
+
+    private static final int MIN_EC_FIELD_SIZE_BITS = 160;
+
+    private static final int MIN_DSA_P_LEN_BITS = 1024;
+    private static final int MIN_DSA_Q_LEN_BITS = 160;
+
+    private static final String[] SIGNATURE_ALGORITHM_OID_BLACKLIST = {
+        "1.2.840.113549.1.1.2", // md2WithRSAEncryption
+        "1.2.840.113549.1.1.3", // md4WithRSAEncryption
+        "1.2.840.113549.1.1.4", // md5WithRSAEncryption
+        "1.2.840.113549.1.1.5", // sha1WithRSAEncryption
+        "1.2.840.10040.4.3", //dsa-with-sha1
+        "1.2.840.10045.4.1", //ecdsa-with-sha1
+    };
+
+    public static final void check(X509Certificate[] chain) throws CertificateException {
+        for (X509Certificate cert : chain) {
+            try {
+                checkCert(cert);
+            } catch (CertificateException e) {
+                throw new CertificateException("Unacceptable certificate: "
+                        + cert.getSubjectX500Principal(), e);
+            }
+        }
+    }
+
+    public static final void check(List<X509Certificate> chain) throws CertificateException {
+        for (X509Certificate cert : chain) {
+            try {
+                checkCert(cert);
+            } catch (CertificateException e) {
+                throw new CertificateException("Unacceptable certificate: "
+                        + cert.getSubjectX500Principal(), e);
+            }
+        }
+    }
+
+    public static final void checkCert(X509Certificate cert) throws CertificateException {
+        checkKeyLength(cert);
+        checkSignatureAlgorithm(cert);
+    }
+
+    private static void checkKeyLength(X509Certificate cert) throws CertificateException {
+        Object pubkey = cert.getPublicKey();
+        if (pubkey instanceof RSAPublicKey) {
+            int modulusLength = ((RSAPublicKey) pubkey).getModulus().bitLength();
+            if (modulusLength < MIN_RSA_MODULUS_LEN_BITS) {
+                throw new CertificateException(
+                        "RSA modulus is < " + MIN_RSA_MODULUS_LEN_BITS + " bits");
+            }
+        } else if (pubkey instanceof ECPublicKey) {
+            int fieldSizeBits =
+                    ((ECPublicKey) pubkey).getParams().getCurve().getField().getFieldSize();
+            if (fieldSizeBits < MIN_EC_FIELD_SIZE_BITS) {
+                throw new CertificateException(
+                        "EC key field size is < " + MIN_EC_FIELD_SIZE_BITS + " bits");
+            }
+        } else if (pubkey instanceof DSAPublicKey) {
+            int pLength = ((DSAPublicKey) pubkey).getParams().getP().bitLength();
+            int qLength = ((DSAPublicKey) pubkey).getParams().getQ().bitLength();
+            if ((pLength < MIN_DSA_P_LEN_BITS) || (qLength < MIN_DSA_Q_LEN_BITS)) {
+                throw new CertificateException(
+                        "DSA key length is < (" + MIN_DSA_P_LEN_BITS + ", " + MIN_DSA_Q_LEN_BITS
+                        + ") bits");
+            }
+        } else {
+            // Unknown keys will be of type X509PublicKey.
+            throw new CertificateException("Rejecting unknown key class " + pubkey.getClass().getName());
+        }
+    }
+
+    private static void checkSignatureAlgorithm(
+            X509Certificate cert) throws CertificateException {
+        String oid = cert.getSigAlgOID();
+        for (String blacklisted : SIGNATURE_ALGORITHM_OID_BLACKLIST) {
+            if (oid.equals(blacklisted)) {
+                throw new CertificateException("Signature uses an insecure hash function: " + oid);
+            }
+        }
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ClientSessionContext.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ClientSessionContext.java
new file mode 100644
index 0000000..789e716
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ClientSessionContext.java
@@ -0,0 +1,251 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.SSLContext;
+
+/**
+ * Caches client sessions. Indexes by host and port. Users are typically
+ * looking to reuse any session for a given host and port.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public final class ClientSessionContext extends AbstractSessionContext {
+    /**
+     * Sessions indexed by host and port. Protect from concurrent
+     * access by holding a lock on sessionsByHostAndPort.
+     *
+     * Invariant: Each list includes either exactly one multi-use session or one
+     * or more single-use sessions.  The types of sessions are never mixed, and adding
+     * a session of one kind will remove all sessions of the other kind.
+     */
+    @SuppressWarnings("serial")
+    private final Map<HostAndPort, List<NativeSslSession>> sessionsByHostAndPort = new HashMap<HostAndPort, List<NativeSslSession>>();
+
+    private SSLClientSessionCache persistentCache;
+
+    ClientSessionContext() {
+        super(10);
+    }
+
+    /**
+     * Applications should not use this method. Instead use {@link
+     * Conscrypt#setClientSessionCache(SSLContext, SSLClientSessionCache)}.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public void setPersistentCache(SSLClientSessionCache persistentCache) {
+        this.persistentCache = persistentCache;
+    }
+
+    /**
+     * Gets the suitable session reference from the session cache container.
+     */
+    synchronized NativeSslSession getCachedSession(String hostName, int port,
+            SSLParametersImpl sslParameters) {
+        if (hostName == null) {
+            return null;
+        }
+
+        NativeSslSession session = getSession(hostName, port);
+        if (session == null) {
+            return null;
+        }
+
+        String protocol = session.getProtocol();
+        boolean protocolFound = false;
+        for (String enabledProtocol : sslParameters.enabledProtocols) {
+            if (protocol.equals(enabledProtocol)) {
+                protocolFound = true;
+                break;
+            }
+        }
+        if (!protocolFound) {
+            return null;
+        }
+
+        String cipherSuite = session.getCipherSuite();
+        boolean cipherSuiteFound = false;
+        for (String enabledCipherSuite : sslParameters.getEnabledCipherSuites()) {
+            if (cipherSuite.equals(enabledCipherSuite)) {
+                cipherSuiteFound = true;
+                break;
+            }
+        }
+        if (!cipherSuiteFound) {
+            return null;
+        }
+
+        if (session.isSingleUse()) {
+            removeSession(session);
+        }
+        return session;
+    }
+
+    int size() {
+        int size = 0;
+        synchronized (sessionsByHostAndPort) {
+            for (List<NativeSslSession> sessions : sessionsByHostAndPort.values()) {
+                size += sessions.size();
+            }
+        }
+        return size;
+    }
+
+    /**
+     * Finds a cached session for the given host name and port.
+     *
+     * @param host of server
+     * @param port of server
+     * @return cached session or null if none found
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private NativeSslSession getSession(String host, int port) {
+        if (host == null) {
+            return null;
+        }
+
+        HostAndPort key = new HostAndPort(host, port);
+        NativeSslSession session = null;
+        synchronized (sessionsByHostAndPort) {
+            List<NativeSslSession> sessions = sessionsByHostAndPort.get(key);
+            if (sessions != null && sessions.size() > 0) {
+                session = sessions.get(0);
+            }
+        }
+        if (session != null && session.isValid()) {
+            return session;
+        }
+
+        // Look in persistent cache.  We don't currently delete sessions from the persistent
+        // cache, so we may find a multi-use (aka TLS 1.2) session after having received and
+        // then used up one or more single-use (aka TLS 1.3) sessions.
+        if (persistentCache != null) {
+            byte[] data = persistentCache.getSessionData(host, port);
+            if (data != null) {
+                session = NativeSslSession.newInstance(this, data, host, port);
+                if (session != null && session.isValid()) {
+                    putSession(key, session);
+                    return session;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private void putSession(HostAndPort key, NativeSslSession session) {
+        synchronized (sessionsByHostAndPort) {
+            List<NativeSslSession> sessions = sessionsByHostAndPort.get(key);
+            if (sessions == null) {
+                sessions = new ArrayList<NativeSslSession>();
+                sessionsByHostAndPort.put(key, sessions);
+            }
+            // To maintain the invariant that single- and multi-use sessions aren't
+            // mixed, check what the current list contains and remove those sessions if
+            // they're of the other type.
+            if (sessions.size() > 0 && sessions.get(0).isSingleUse() != session.isSingleUse()) {
+                while (!sessions.isEmpty()) {
+                    removeSession(sessions.get(0));
+                }
+                // The last removeSession() call will have removed the list from
+                // the map, so put it back.
+                sessionsByHostAndPort.put(key, sessions);
+            }
+            sessions.add(session);
+        }
+    }
+
+    private void removeSession(HostAndPort key, NativeSslSession session) {
+        synchronized (sessionsByHostAndPort) {
+            List<NativeSslSession> sessions = sessionsByHostAndPort.get(key);
+            if (sessions != null) {
+                sessions.remove(session);
+                if (sessions.isEmpty()) {
+                    sessionsByHostAndPort.remove(key);
+                }
+            }
+        }
+    }
+
+    @Override
+    void onBeforeAddSession(NativeSslSession session) {
+        String host = session.getPeerHost();
+        int port = session.getPeerPort();
+        if (host == null) {
+            return;
+        }
+
+        HostAndPort key = new HostAndPort(host, port);
+        putSession(key, session);
+
+        // TODO: Do this in a background thread.
+        if (persistentCache != null && !session.isSingleUse()) {
+            byte[] data = session.toBytes();
+            if (data != null) {
+                persistentCache.putSessionData(session.toSSLSession(), data);
+            }
+        }
+    }
+
+    @Override
+    void onBeforeRemoveSession(NativeSslSession session) {
+        String host = session.getPeerHost();
+        if (host == null) {
+            return;
+        }
+        int port = session.getPeerPort();
+        HostAndPort hostAndPortKey = new HostAndPort(host, port);
+        removeSession(hostAndPortKey, session);
+    }
+
+    @Override
+    NativeSslSession getSessionFromPersistentCache(byte[] sessionId) {
+        // Not implemented for clients.
+        return null;
+    }
+
+    private static final class HostAndPort {
+        final String host;
+        final int port;
+
+        HostAndPort(String host, int port) {
+            this.host = host;
+            this.port = port;
+        }
+
+        @Override
+        public int hashCode() {
+            return host.hashCode() * 31 + port;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof HostAndPort)) {
+                return false;
+            }
+            HostAndPort lhs = (HostAndPort) o;
+            return host.equals(lhs.host) && port == lhs.port;
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Conscrypt.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Conscrypt.java
new file mode 100644
index 0000000..7184dc9
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Conscrypt.java
@@ -0,0 +1,782 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.security.KeyManagementException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.util.Properties;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Core API for creating and configuring all Conscrypt types.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@SuppressWarnings("unused")
+public final class Conscrypt {
+    private Conscrypt() {}
+
+    /**
+     * Returns {@code true} if the Conscrypt native library has been successfully loaded.
+     */
+    public static boolean isAvailable() {
+        try {
+            checkAvailability();
+            return true;
+        } catch (Throwable e) {
+            return false;
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class Version {
+        private final int major;
+        private final int minor;
+        private final int patch;
+
+        private Version(int major, int minor, int patch) {
+            this.major = major;
+            this.minor = minor;
+            this.patch = patch;
+        }
+
+        public int major() { return major; }
+        public int minor() { return minor; }
+        public int patch() { return patch; }
+    }
+
+    private static final Version VERSION;
+
+    static {
+        int major = -1;
+        int minor = -1;
+        int patch = -1;
+        try {
+            InputStream stream = Conscrypt.class.getResourceAsStream("conscrypt.properties");
+            if (stream != null) {
+                Properties props = new Properties();
+                props.load(stream);
+                major = Integer.parseInt(props.getProperty("com.android.org.conscrypt.version.major", "-1"));
+                minor = Integer.parseInt(props.getProperty("com.android.org.conscrypt.version.minor", "-1"));
+                patch = Integer.parseInt(props.getProperty("com.android.org.conscrypt.version.patch", "-1"));
+            }
+        } catch (IOException e) {
+        }
+        if ((major >= 0) && (minor >= 0) && (patch >= 0)) {
+            VERSION = new Version(major, minor, patch);
+        } else {
+            VERSION = null;
+        }
+    }
+
+    /**
+     * Returns the version of this distribution of Conscrypt.  If version information is
+     * unavailable, returns {@code null}.
+     */
+    public static Version version() {
+        return VERSION;
+    }
+
+    /**
+     * Checks that the Conscrypt support is available for the system.
+     *
+     * @throws UnsatisfiedLinkError if unavailable
+     */
+    public static void checkAvailability() {
+        NativeCrypto.checkAvailability();
+    }
+
+    /**
+     * Indicates whether the given {@link Provider} was created by this distribution of Conscrypt.
+     */
+    public static boolean isConscrypt(Provider provider) {
+        return provider instanceof OpenSSLProvider;
+    }
+
+    /**
+     * Constructs a new {@link Provider} with the default name.
+     */
+    public static Provider newProvider() {
+        checkAvailability();
+        return new OpenSSLProvider();
+    }
+
+    /**
+     * Constructs a new {@link Provider} with the given name.
+     *
+     * @deprecated Use {@link #newProviderBuilder()} instead.
+     */
+    @Deprecated
+    public static Provider newProvider(String providerName) {
+        checkAvailability();
+        return new OpenSSLProvider(providerName, Platform.provideTrustManagerByDefault());
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class ProviderBuilder {
+        private String name = Platform.getDefaultProviderName();
+        private boolean provideTrustManager = Platform.provideTrustManagerByDefault();
+
+        private ProviderBuilder() {}
+
+        /**
+         * Sets the name of the Provider to be built.
+         */
+        public ProviderBuilder setName(String name) {
+            this.name = name;
+            return this;
+        }
+
+        /**
+         * Causes the returned provider to provide an implementation of
+         * {@link javax.net.ssl.TrustManagerFactory}.
+         * @deprecated Use provideTrustManager(true)
+         */
+        @Deprecated
+        public ProviderBuilder provideTrustManager() {
+            return provideTrustManager(true);
+        }
+
+        /**
+         * Specifies whether the returned provider will provide an implementation of
+         * {@link javax.net.ssl.TrustManagerFactory}.
+         */
+        public ProviderBuilder provideTrustManager(boolean provide) {
+            this.provideTrustManager = provide;
+            return this;
+        }
+
+        public Provider build() {
+            return new OpenSSLProvider(name, provideTrustManager);
+        }
+    }
+
+    public static ProviderBuilder newProviderBuilder() {
+        return new ProviderBuilder();
+    }
+
+    /**
+     * Returns the maximum length (in bytes) of an encrypted packet.
+     */
+    public static int maxEncryptedPacketLength() {
+        return NativeConstants.SSL3_RT_MAX_PACKET_SIZE;
+    }
+
+    /**
+     * Gets the default X.509 trust manager.
+     */
+    @libcore.api.CorePlatformApi
+    @ExperimentalApi
+    public static X509TrustManager getDefaultX509TrustManager() throws KeyManagementException {
+        checkAvailability();
+        return SSLParametersImpl.getDefaultX509TrustManager();
+    }
+
+    /**
+     * Indicates whether the given {@link SSLContext} was created by this distribution of Conscrypt.
+     */
+    public static boolean isConscrypt(SSLContext context) {
+        return context.getProvider() instanceof OpenSSLProvider;
+    }
+
+    /**
+     * Constructs a new instance of the preferred {@link SSLContextSpi}.
+     */
+    public static SSLContextSpi newPreferredSSLContextSpi() {
+        checkAvailability();
+        return OpenSSLContextImpl.getPreferred();
+    }
+
+    /**
+     * Sets the client-side persistent cache to be used by the context.
+     */
+    public static void setClientSessionCache(SSLContext context, SSLClientSessionCache cache) {
+        SSLSessionContext clientContext = context.getClientSessionContext();
+        if (!(clientContext instanceof ClientSessionContext)) {
+            throw new IllegalArgumentException(
+                    "Not a conscrypt client context: " + clientContext.getClass().getName());
+        }
+        ((ClientSessionContext) clientContext).setPersistentCache(cache);
+    }
+
+    /**
+     * Sets the server-side persistent cache to be used by the context.
+     */
+    public static void setServerSessionCache(SSLContext context, SSLServerSessionCache cache) {
+        SSLSessionContext serverContext = context.getServerSessionContext();
+        if (!(serverContext instanceof ServerSessionContext)) {
+            throw new IllegalArgumentException(
+                    "Not a conscrypt client context: " + serverContext.getClass().getName());
+        }
+        ((ServerSessionContext) serverContext).setPersistentCache(cache);
+    }
+
+    /**
+     * Indicates whether the given {@link SSLSocketFactory} was created by this distribution of
+     * Conscrypt.
+     */
+    public static boolean isConscrypt(SSLSocketFactory factory) {
+        return factory instanceof OpenSSLSocketFactoryImpl;
+    }
+
+    private static OpenSSLSocketFactoryImpl toConscrypt(SSLSocketFactory factory) {
+        if (!isConscrypt(factory)) {
+            throw new IllegalArgumentException(
+                    "Not a conscrypt socket factory: " + factory.getClass().getName());
+        }
+        return (OpenSSLSocketFactoryImpl) factory;
+    }
+
+    /**
+     * Configures the default socket to be created for all socket factory instances.
+     */
+    @ExperimentalApi
+    public static void setUseEngineSocketByDefault(boolean useEngineSocket) {
+        OpenSSLSocketFactoryImpl.setUseEngineSocketByDefault(useEngineSocket);
+        OpenSSLServerSocketFactoryImpl.setUseEngineSocketByDefault(useEngineSocket);
+    }
+
+    /**
+     * Configures the socket to be created for the given socket factory instance.
+     */
+    @ExperimentalApi
+    public static void setUseEngineSocket(SSLSocketFactory factory, boolean useEngineSocket) {
+        toConscrypt(factory).setUseEngineSocket(useEngineSocket);
+    }
+
+    /**
+     * Indicates whether the given {@link SSLServerSocketFactory} was created by this distribution
+     * of Conscrypt.
+     */
+    public static boolean isConscrypt(SSLServerSocketFactory factory) {
+        return factory instanceof OpenSSLServerSocketFactoryImpl;
+    }
+
+    private static OpenSSLServerSocketFactoryImpl toConscrypt(SSLServerSocketFactory factory) {
+        if (!isConscrypt(factory)) {
+            throw new IllegalArgumentException(
+                    "Not a conscrypt server socket factory: " + factory.getClass().getName());
+        }
+        return (OpenSSLServerSocketFactoryImpl) factory;
+    }
+
+    /**
+     * Configures the socket to be created for the given server socket factory instance.
+     */
+    @ExperimentalApi
+    public static void setUseEngineSocket(SSLServerSocketFactory factory, boolean useEngineSocket) {
+        toConscrypt(factory).setUseEngineSocket(useEngineSocket);
+    }
+
+    /**
+     * Indicates whether the given {@link SSLSocket} was created by this distribution of Conscrypt.
+     */
+    public static boolean isConscrypt(SSLSocket socket) {
+        return socket instanceof AbstractConscryptSocket;
+    }
+
+    private static AbstractConscryptSocket toConscrypt(SSLSocket socket) {
+        if (!isConscrypt(socket)) {
+            throw new IllegalArgumentException(
+                    "Not a conscrypt socket: " + socket.getClass().getName());
+        }
+        return (AbstractConscryptSocket) socket;
+    }
+
+    /**
+     * This method enables Server Name Indication (SNI) and overrides the hostname supplied
+     * during socket creation.  If the hostname is not a valid SNI hostname, the SNI extension
+     * will be omitted from the handshake.
+     *
+     * @param socket the socket
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    public static void setHostname(SSLSocket socket, String hostname) {
+        toConscrypt(socket).setHostname(hostname);
+    }
+
+    /**
+     * Returns either the hostname supplied during socket creation or via
+     * {@link #setHostname(SSLSocket, String)}. No DNS resolution is attempted before
+     * returning the hostname.
+     */
+    public static String getHostname(SSLSocket socket) {
+        return toConscrypt(socket).getHostname();
+    }
+
+    /**
+     * This method attempts to create a textual representation of the peer host or IP. Does
+     * not perform a reverse DNS lookup. This is typically used during session creation.
+     */
+    public static String getHostnameOrIP(SSLSocket socket) {
+        return toConscrypt(socket).getHostnameOrIP();
+    }
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param socket the socket
+     * @param useSessionTickets True to enable session tickets
+     */
+    public static void setUseSessionTickets(SSLSocket socket, boolean useSessionTickets) {
+        toConscrypt(socket).setUseSessionTickets(useSessionTickets);
+    }
+
+    /**
+     * Enables/disables TLS Channel ID for the given server-side socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param socket the socket
+     * @param enabled Whether to enable channel ID.
+     * @throws IllegalStateException if this is a client socket or if the handshake has already
+     * started.
+     */
+    public static void setChannelIdEnabled(SSLSocket socket, boolean enabled) {
+        toConscrypt(socket).setChannelIdEnabled(enabled);
+    }
+
+    /**
+     * Gets the TLS Channel ID for the given server-side socket. Channel ID is only available
+     * once the handshake completes.
+     *
+     * @param socket the socket
+     * @return channel ID or {@code null} if not available.
+     * @throws IllegalStateException if this is a client socket or if the handshake has not yet
+     * completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    public static byte[] getChannelId(SSLSocket socket) throws SSLException {
+        return toConscrypt(socket).getChannelId();
+    }
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param socket the socket
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key
+     * (disables TLS Channel ID).
+     * The private key must be an Elliptic Curve (EC) key based on the NIST P-256 curve (aka
+     * SECG secp256r1 or ANSI
+     * X9.62 prime256v1).
+     * @throws IllegalStateException if this is a server socket or if the handshake has already
+     * started.
+     */
+    public static void setChannelIdPrivateKey(SSLSocket socket, PrivateKey privateKey) {
+        toConscrypt(socket).setChannelIdPrivateKey(privateKey);
+    }
+
+    /**
+     * Returns the ALPN protocol agreed upon by client and server.
+     *
+     * @param socket the socket
+     * @return the selected protocol or {@code null} if no protocol was agreed upon.
+     */
+    public static String getApplicationProtocol(SSLSocket socket) {
+        return toConscrypt(socket).getApplicationProtocol();
+    }
+
+    /**
+     * Sets an application-provided ALPN protocol selector. If provided, this will override
+     * the list of protocols set by {@link #setApplicationProtocols(SSLSocket, String[])}.
+     *
+     * @param socket the socket
+     * @param selector the ALPN protocol selector
+     */
+    public static void setApplicationProtocolSelector(SSLSocket socket,
+        ApplicationProtocolSelector selector) {
+        toConscrypt(socket).setApplicationProtocolSelector(selector);
+    }
+
+    /**
+     * Sets the application-layer protocols (ALPN) in prioritization order.
+     *
+     * @param socket the socket being configured
+     * @param protocols the protocols in descending order of preference. If empty, no protocol
+     * indications will be used. This array will be copied.
+     * @throws IllegalArgumentException - if protocols is null, or if any element in a non-empty
+     * array is null or an empty (zero-length) string
+     */
+    public static void setApplicationProtocols(SSLSocket socket, String[] protocols) {
+        toConscrypt(socket).setApplicationProtocols(protocols);
+    }
+
+    /**
+     * Gets the application-layer protocols (ALPN) in prioritization order.
+     *
+     * @param socket the socket
+     * @return the protocols in descending order of preference, or an empty array if protocol
+     * indications are not being used. Always returns a new array.
+     */
+    public static String[] getApplicationProtocols(SSLSocket socket) {
+        return toConscrypt(socket).getApplicationProtocols();
+    }
+
+    /**
+     * Returns the tls-unique channel binding value for this connection, per RFC 5929.  This
+     * will return {@code null} if there is no such value available, such as if the handshake
+     * has not yet completed or this connection is closed.
+     */
+    public static byte[] getTlsUnique(SSLSocket socket) {
+        return toConscrypt(socket).getTlsUnique();
+    }
+
+    /**
+     * Exports a value derived from the TLS master secret as described in RFC 5705.
+     *
+     * @param label the label to use in calculating the exported value.  This must be
+     * an ASCII-only string.
+     * @param context the application-specific context value to use in calculating the
+     * exported value.  This may be {@code null} to use no application context, which is
+     * treated differently than an empty byte array.
+     * @param length the number of bytes of keying material to return.
+     * @return a value of the specified length, or {@code null} if the handshake has not yet
+     * completed or the connection has been closed.
+     * @throws SSLException if the value could not be exported.
+     */
+    public static byte[] exportKeyingMaterial(SSLSocket socket, String label, byte[] context,
+            int length) throws SSLException {
+        return toConscrypt(socket).exportKeyingMaterial(label, context, length);
+    }
+
+    /**
+     * Indicates whether the given {@link SSLEngine} was created by this distribution of Conscrypt.
+     */
+    public static boolean isConscrypt(SSLEngine engine) {
+        return engine instanceof AbstractConscryptEngine;
+    }
+
+    private static AbstractConscryptEngine toConscrypt(SSLEngine engine) {
+        if (!isConscrypt(engine)) {
+            throw new IllegalArgumentException(
+                    "Not a conscrypt engine: " + engine.getClass().getName());
+        }
+        return (AbstractConscryptEngine) engine;
+    }
+
+    /**
+     * Provides the given engine with the provided bufferAllocator.
+     * @throws IllegalArgumentException if the provided engine is not a Conscrypt engine.
+     * @throws IllegalStateException if the provided engine has already begun its handshake.
+     */
+    @ExperimentalApi
+    public static void setBufferAllocator(SSLEngine engine, BufferAllocator bufferAllocator) {
+        toConscrypt(engine).setBufferAllocator(bufferAllocator);
+    }
+
+    /**
+     * Provides the given socket with the provided bufferAllocator.  If the given socket is a
+     * Conscrypt socket but does not use buffer allocators, this method does nothing.
+     * @throws IllegalArgumentException if the provided socket is not a Conscrypt socket.
+     * @throws IllegalStateException if the provided socket has already begun its handshake.
+     */
+    @ExperimentalApi
+    public static void setBufferAllocator(SSLSocket socket, BufferAllocator bufferAllocator) {
+        AbstractConscryptSocket s = toConscrypt(socket);
+        if (s instanceof ConscryptEngineSocket) {
+            ((ConscryptEngineSocket) s).setBufferAllocator(bufferAllocator);
+        }
+    }
+
+    /**
+     * Configures the default {@link BufferAllocator} to be used by all future
+     * {@link SSLEngine} instances from this provider.
+     */
+    @ExperimentalApi
+    public static void setDefaultBufferAllocator(BufferAllocator bufferAllocator) {
+        ConscryptEngine.setDefaultBufferAllocator(bufferAllocator);
+    }
+
+    /**
+     * This method enables Server Name Indication (SNI) and overrides the hostname supplied
+     * during engine creation.
+     *
+     * @param engine the engine
+     * @param hostname the desired SNI hostname, or {@code null} to disable
+     */
+    public static void setHostname(SSLEngine engine, String hostname) {
+        toConscrypt(engine).setHostname(hostname);
+    }
+
+    /**
+     * Returns either the hostname supplied during socket creation or via
+     * {@link #setHostname(SSLEngine, String)}. No DNS resolution is attempted before
+     * returning the hostname.
+     */
+    public static String getHostname(SSLEngine engine) {
+        return toConscrypt(engine).getHostname();
+    }
+
+    /**
+     * Returns the maximum overhead, in bytes, of sealing a record with SSL.
+     */
+    public static int maxSealOverhead(SSLEngine engine) {
+        return toConscrypt(engine).maxSealOverhead();
+    }
+
+    /**
+     * Sets a listener on the given engine for completion of the TLS handshake
+     */
+    public static void setHandshakeListener(SSLEngine engine, HandshakeListener handshakeListener) {
+        toConscrypt(engine).setHandshakeListener(handshakeListener);
+    }
+
+    /**
+     * Enables/disables TLS Channel ID for the given server-side engine.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param engine the engine
+     * @param enabled Whether to enable channel ID.
+     * @throws IllegalStateException if this is a client engine or if the handshake has already
+     * started.
+     */
+    public static void setChannelIdEnabled(SSLEngine engine, boolean enabled) {
+        toConscrypt(engine).setChannelIdEnabled(enabled);
+    }
+
+    /**
+     * Gets the TLS Channel ID for the given server-side engine. Channel ID is only available
+     * once the handshake completes.
+     *
+     * @param engine the engine
+     * @return channel ID or {@code null} if not available.
+     * @throws IllegalStateException if this is a client engine or if the handshake has not yet
+     * completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    public static byte[] getChannelId(SSLEngine engine) throws SSLException {
+        return toConscrypt(engine).getChannelId();
+    }
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client engine.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param engine the engine
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key
+     * (disables TLS Channel ID).
+     * The private key must be an Elliptic Curve (EC) key based on the NIST P-256 curve (aka
+     * SECG secp256r1 or ANSI X9.62 prime256v1).
+     * @throws IllegalStateException if this is a server engine or if the handshake has already
+     * started.
+     */
+    public static void setChannelIdPrivateKey(SSLEngine engine, PrivateKey privateKey) {
+        toConscrypt(engine).setChannelIdPrivateKey(privateKey);
+    }
+
+    /**
+     * Extended unwrap method for multiple source and destination buffers.
+     *
+     * @param engine the target engine for the unwrap
+     * @param srcs the source buffers
+     * @param dsts the destination buffers
+     * @return the result of the unwrap operation
+     * @throws SSLException thrown if an SSL error occurred
+     */
+    public static SSLEngineResult unwrap(SSLEngine engine, final ByteBuffer[] srcs,
+            final ByteBuffer[] dsts) throws SSLException {
+        return toConscrypt(engine).unwrap(srcs, dsts);
+    }
+
+    /**
+     * Exteneded unwrap method for multiple source and destination buffers.
+     *
+     * @param engine the target engine for the unwrap.
+     * @param srcs the source buffers
+     * @param srcsOffset the offset in the {@code srcs} array of the first source buffer
+     * @param srcsLength the number of source buffers starting at {@code srcsOffset}
+     * @param dsts the destination buffers
+     * @param dstsOffset the offset in the {@code dsts} array of the first destination buffer
+     * @param dstsLength the number of destination buffers starting at {@code dstsOffset}
+     * @return the result of the unwrap operation
+     * @throws SSLException thrown if an SSL error occurred
+     */
+    public static SSLEngineResult unwrap(SSLEngine engine, final ByteBuffer[] srcs, int srcsOffset,
+            final int srcsLength, final ByteBuffer[] dsts, final int dstsOffset,
+            final int dstsLength) throws SSLException {
+        return toConscrypt(engine).unwrap(
+                srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
+    }
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param engine the engine
+     * @param useSessionTickets True to enable session tickets
+     */
+    public static void setUseSessionTickets(SSLEngine engine, boolean useSessionTickets) {
+        toConscrypt(engine).setUseSessionTickets(useSessionTickets);
+    }
+
+    /**
+     * Sets the application-layer protocols (ALPN) in prioritization order.
+     *
+     * @param engine the engine being configured
+     * @param protocols the protocols in descending order of preference. If empty, no protocol
+     * indications will be used.  This array will be copied.
+     * @throws IllegalArgumentException - if protocols is null, or if any element in a non-empty
+     * array is null or an empty (zero-length) string
+     */
+    public static void setApplicationProtocols(SSLEngine engine, String[] protocols) {
+        toConscrypt(engine).setApplicationProtocols(protocols);
+    }
+
+    /**
+     * Gets the application-layer protocols (ALPN) in prioritization order.
+     *
+     * @param engine the engine
+     * @return the protocols in descending order of preference, or an empty array if protocol
+     * indications are not being used. Always returns a new array.
+     */
+    public static String[] getApplicationProtocols(SSLEngine engine) {
+        return toConscrypt(engine).getApplicationProtocols();
+    }
+
+    /**
+     * Sets an application-provided ALPN protocol selector. If provided, this will override
+     * the list of protocols set by {@link #setApplicationProtocols(SSLEngine, String[])}.
+     *
+     * @param engine the engine
+     * @param selector the ALPN protocol selector
+     */
+    public static void setApplicationProtocolSelector(SSLEngine engine,
+        ApplicationProtocolSelector selector) {
+        toConscrypt(engine).setApplicationProtocolSelector(selector);
+    }
+
+    /**
+     * Returns the ALPN protocol agreed upon by client and server.
+     *
+     * @param engine the engine
+     * @return the selected protocol or {@code null} if no protocol was agreed upon.
+     */
+    public static String getApplicationProtocol(SSLEngine engine) {
+        return toConscrypt(engine).getApplicationProtocol();
+    }
+
+    /**
+     * Returns the tls-unique channel binding value for this connection, per RFC 5929.  This
+     * will return {@code null} if there is no such value available, such as if the handshake
+     * has not yet completed or this connection is closed.
+     */
+    public static byte[] getTlsUnique(SSLEngine engine) {
+        return toConscrypt(engine).getTlsUnique();
+    }
+
+    /**
+     * Exports a value derived from the TLS master secret as described in RFC 5705.
+     *
+     * @param label the label to use in calculating the exported value.  This must be
+     * an ASCII-only string.
+     * @param context the application-specific context value to use in calculating the
+     * exported value.  This may be {@code null} to use no application context, which is
+     * treated differently than an empty byte array.
+     * @param length the number of bytes of keying material to return.
+     * @return a value of the specified length, or {@code null} if the handshake has not yet
+     * completed or the connection has been closed.
+     * @throws SSLException if the value could not be exported.
+     */
+    public static byte[] exportKeyingMaterial(SSLEngine engine, String label, byte[] context,
+            int length) throws SSLException {
+        return toConscrypt(engine).exportKeyingMaterial(label, context, length);
+    }
+
+    /**
+     * Indicates whether the given {@link TrustManager} was created by this distribution of
+     * Conscrypt.
+     */
+    public static boolean isConscrypt(TrustManager trustManager) {
+        return trustManager instanceof TrustManagerImpl;
+    }
+
+    private static TrustManagerImpl toConscrypt(TrustManager trustManager) {
+        if (!isConscrypt(trustManager)) {
+            throw new IllegalArgumentException(
+                    "Not a Conscrypt trust manager: " + trustManager.getClass().getName());
+        }
+        return (TrustManagerImpl) trustManager;
+    }
+
+    /**
+     * Set the default hostname verifier that will be used for HTTPS endpoint identification by
+     * Conscrypt trust managers.  If {@code null} (the default), endpoint identification will use
+     * the default hostname verifier set in
+     * {@link HttpsURLConnection#setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier)}.
+     */
+    public synchronized static void setDefaultHostnameVerifier(ConscryptHostnameVerifier verifier) {
+        TrustManagerImpl.setDefaultHostnameVerifier(verifier);
+    }
+
+    /**
+     * Returns the currently-set default hostname verifier for Conscrypt trust managers.
+     *
+     * @see #setDefaultHostnameVerifier(ConscryptHostnameVerifier)
+     */
+    public synchronized static ConscryptHostnameVerifier getDefaultHostnameVerifier(
+            TrustManager trustManager) {
+        return TrustManagerImpl.getDefaultHostnameVerifier();
+    }
+
+    /**
+     * Set the hostname verifier that will be used for HTTPS endpoint identification by the
+     * given trust manager.  If {@code null} (the default), endpoint identification will use the
+     * default hostname verifier set in {@link
+     * #setDefaultHostnameVerifier(ConscryptHostnameVerifier)}.
+     *
+     * @throws IllegalArgumentException if the provided trust manager is not a Conscrypt trust
+     * manager per {@link #isConscrypt(TrustManager)}
+     */
+    public static void setHostnameVerifier(
+            TrustManager trustManager, ConscryptHostnameVerifier verifier) {
+        toConscrypt(trustManager).setHostnameVerifier(verifier);
+    }
+
+    /**
+     * Returns the currently-set hostname verifier for the given trust manager.
+     *
+     * @throws IllegalArgumentException if the provided trust manager is not a Conscrypt trust
+     * manager per {@link #isConscrypt(TrustManager)}
+     *
+     * @see #setHostnameVerifier(TrustManager, ConscryptHostnameVerifier)
+     */
+    public static ConscryptHostnameVerifier getHostnameVerifier(TrustManager trustManager) {
+        return toConscrypt(trustManager).getHostnameVerifier();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptCertStore.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptCertStore.java
new file mode 100644
index 0000000..472e2da
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptCertStore.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2018 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 com.android.org.conscrypt;
+
+import java.security.cert.X509Certificate;
+import java.util.Set;
+
+/**
+ * A certificate store that supports additional operations that are used in
+ * TrustManagerImpl.  This is primarily implemented by the cert store on the
+ * Android platform.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public interface ConscryptCertStore {
+
+    /**
+     * Returns a stored CA certificate with the same name and public key as the
+     * provided {@link X509Certificate}.
+     */
+    X509Certificate getTrustAnchor(X509Certificate c);
+
+    /**
+     * Returns all CA certificates with the public key that was used to sign the
+     * provided {@link X509Certificate}.
+     */
+    Set<X509Certificate> findAllIssuers(X509Certificate c);
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java
new file mode 100644
index 0000000..646be02
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngine.java
@@ -0,0 +1,1824 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2013 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.
+ */
+
+/*
+ * Copyright 2016 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
+import static javax.net.ssl.SSLEngineResult.Status.BUFFER_OVERFLOW;
+import static javax.net.ssl.SSLEngineResult.Status.BUFFER_UNDERFLOW;
+import static javax.net.ssl.SSLEngineResult.Status.CLOSED;
+import static javax.net.ssl.SSLEngineResult.Status.OK;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_HEADER_LENGTH;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_MAX_PACKET_SIZE;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH;
+import static com.android.org.conscrypt.NativeConstants.SSL_CB_HANDSHAKE_DONE;
+import static com.android.org.conscrypt.NativeConstants.SSL_CB_HANDSHAKE_START;
+import static com.android.org.conscrypt.NativeConstants.SSL_ERROR_WANT_READ;
+import static com.android.org.conscrypt.NativeConstants.SSL_ERROR_WANT_WRITE;
+import static com.android.org.conscrypt.NativeConstants.SSL_ERROR_ZERO_RETURN;
+import static com.android.org.conscrypt.Preconditions.checkArgument;
+import static com.android.org.conscrypt.Preconditions.checkNotNull;
+import static com.android.org.conscrypt.Preconditions.checkPositionIndexes;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED_INBOUND;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED_OUTBOUND;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_COMPLETED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_STARTED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_MODE_SET;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_NEW;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_READY;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_READY_HANDSHAKE_CUT_THROUGH;
+import static com.android.org.conscrypt.SSLUtils.calculateOutNetBufSize;
+import static com.android.org.conscrypt.SSLUtils.toSSLHandshakeException;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECKey;
+import java.security.spec.ECParameterSpec;
+import javax.crypto.SecretKey;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.ExternalSession.Provider;
+import com.android.org.conscrypt.NativeRef.SSL_SESSION;
+import com.android.org.conscrypt.NativeSsl.BioWrapper;
+
+/**
+ * Implements the {@link SSLEngine} API using OpenSSL's non-blocking interfaces.
+ */
+final class ConscryptEngine extends AbstractConscryptEngine implements NativeCrypto.SSLHandshakeCallbacks,
+                                                         SSLParametersImpl.AliasChooser,
+                                                         SSLParametersImpl.PSKCallbacks {
+    private static final SSLEngineResult NEED_UNWRAP_OK =
+            new SSLEngineResult(OK, NEED_UNWRAP, 0, 0);
+    private static final SSLEngineResult NEED_UNWRAP_CLOSED =
+            new SSLEngineResult(CLOSED, NEED_UNWRAP, 0, 0);
+    private static final SSLEngineResult NEED_WRAP_OK = new SSLEngineResult(OK, NEED_WRAP, 0, 0);
+    private static final SSLEngineResult NEED_WRAP_CLOSED =
+            new SSLEngineResult(CLOSED, NEED_WRAP, 0, 0);
+    private static final SSLEngineResult CLOSED_NOT_HANDSHAKING =
+            new SSLEngineResult(CLOSED, NOT_HANDSHAKING, 0, 0);
+
+    private static BufferAllocator defaultBufferAllocator = null;
+
+    private final SSLParametersImpl sslParameters;
+    private BufferAllocator bufferAllocator = defaultBufferAllocator;
+
+    /**
+     * A lazy-created direct buffer used as a bridge between heap buffers provided by the
+     * application and JNI. This avoids the overhead of calling JNI with heap buffers.
+     * Used only when no {@link #bufferAllocator} has been provided.
+     */
+    private ByteBuffer lazyDirectBuffer;
+
+    /**
+     * Hostname used with the TLS extension SNI hostname.
+     */
+    private String peerHostname;
+
+    // @GuardedBy("ssl");
+    private int state = STATE_NEW;
+    private boolean handshakeFinished;
+
+    /**
+     * Wrapper around the underlying SSL object.
+     */
+    private final NativeSsl ssl;
+
+    /**
+     * The BIO used for reading/writing encrypted bytes.
+     */
+    // @GuardedBy("ssl");
+    private final BioWrapper networkBio;
+
+    /**
+     * Set during startHandshake.
+     */
+    private ActiveSession activeSession;
+
+    /**
+     * A snapshot of the active session when the engine was closed.
+     */
+    private SessionSnapshot closedSession;
+
+    /**
+     * The session object exposed externally from this class.
+     */
+    private final SSLSession externalSession =
+        Platform.wrapSSLSession(new ExternalSession(new Provider() {
+            @Override
+            public ConscryptSession provideSession() {
+                return ConscryptEngine.this.provideSession();
+            }
+        }));
+
+    /**
+     * Private key for the TLS Channel ID extension. This field is client-side only. Set during
+     * startHandshake.
+     */
+    private OpenSSLKey channelIdPrivateKey;
+
+    private int maxSealOverhead;
+
+    private HandshakeListener handshakeListener;
+
+    private final ByteBuffer[] singleSrcBuffer = new ByteBuffer[1];
+    private final ByteBuffer[] singleDstBuffer = new ByteBuffer[1];
+    private final PeerInfoProvider peerInfoProvider;
+
+    ConscryptEngine(SSLParametersImpl sslParameters) {
+        this.sslParameters = sslParameters;
+        peerInfoProvider = PeerInfoProvider.nullProvider();
+        this.ssl = newSsl(sslParameters, this);
+        this.networkBio = ssl.newBio();
+    }
+
+    ConscryptEngine(String host, int port, SSLParametersImpl sslParameters) {
+        this.sslParameters = sslParameters;
+        this.peerInfoProvider = PeerInfoProvider.forHostAndPort(host, port);
+        this.ssl = newSsl(sslParameters, this);
+        this.networkBio = ssl.newBio();
+    }
+
+    ConscryptEngine(SSLParametersImpl sslParameters, PeerInfoProvider peerInfoProvider) {
+        this.sslParameters = sslParameters;
+        this.peerInfoProvider = checkNotNull(peerInfoProvider, "peerInfoProvider");
+        this.ssl = newSsl(sslParameters, this);
+        this.networkBio = ssl.newBio();
+    }
+
+    private static NativeSsl newSsl(SSLParametersImpl sslParameters, ConscryptEngine engine) {
+        try {
+            return NativeSsl.newInstance(sslParameters, engine, engine, engine);
+        } catch (SSLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Configures the default {@link BufferAllocator} to be used by all future
+     * {@link SSLEngine} and {@link ConscryptEngineSocket} instances from this provider.
+     */
+    static void setDefaultBufferAllocator(BufferAllocator bufferAllocator) {
+        defaultBufferAllocator = bufferAllocator;
+    }
+
+    /**
+     * Returns the default {@link BufferAllocator}, which may be {@code null} if no default
+     * has been explicitly set.
+     */
+    static BufferAllocator getDefaultBufferAllocator() {
+        return defaultBufferAllocator;
+    }
+
+    @Override
+    void setBufferAllocator(BufferAllocator bufferAllocator) {
+        synchronized (ssl) {
+            if (isHandshakeStarted()) {
+                throw new IllegalStateException(
+                        "Could not set buffer allocator after the initial handshake has begun.");
+            }
+            this.bufferAllocator = bufferAllocator;
+        }
+    }
+
+    /**
+     * Returns the maximum overhead, in bytes, of sealing a record with SSL.
+     */
+    @Override
+    int maxSealOverhead() {
+        return maxSealOverhead;
+    }
+
+    /**
+     * Enables/disables TLS Channel ID for this server engine.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @throws IllegalStateException if this is a client engine or if the handshake has already
+     *         started.
+     */
+    @Override
+    void setChannelIdEnabled(boolean enabled) {
+        synchronized (ssl) {
+            if (getUseClientMode()) {
+                throw new IllegalStateException("Not allowed in client mode");
+            }
+            if (isHandshakeStarted()) {
+                throw new IllegalStateException(
+                        "Could not enable/disable Channel ID after the initial handshake has begun.");
+            }
+            sslParameters.channelIdEnabled = enabled;
+        }
+    }
+
+    /**
+     * Gets the TLS Channel ID for this server engine. Channel ID is only available once the
+     * handshake completes.
+     *
+     * @return channel ID or {@code null} if not available.
+     *
+     * @throws IllegalStateException if this is a client engine or if the handshake has not yet
+     * completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    @Override
+    byte[] getChannelId() throws SSLException {
+        synchronized (ssl) {
+            if (getUseClientMode()) {
+                throw new IllegalStateException("Not allowed in client mode");
+            }
+
+            if (isHandshakeStarted()) {
+                throw new IllegalStateException(
+                        "Channel ID is only available after handshake completes");
+            }
+            return ssl.getTlsChannelId();
+        }
+    }
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client engine.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
+     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
+     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
+     *
+     * @throws IllegalStateException if this is a server engine or if the handshake has already
+     *         started.
+     */
+    @Override
+    void setChannelIdPrivateKey(PrivateKey privateKey) {
+        if (!getUseClientMode()) {
+            throw new IllegalStateException("Not allowed in server mode");
+        }
+
+        synchronized (ssl) {
+            if (isHandshakeStarted()) {
+                throw new IllegalStateException("Could not change Channel ID private key "
+                        + "after the initial handshake has begun.");
+            }
+
+            if (privateKey == null) {
+                sslParameters.channelIdEnabled = false;
+                channelIdPrivateKey = null;
+                return;
+            }
+
+            sslParameters.channelIdEnabled = true;
+            try {
+                ECParameterSpec ecParams = null;
+                if (privateKey instanceof ECKey) {
+                    ecParams = ((ECKey) privateKey).getParams();
+                }
+                if (ecParams == null) {
+                    // Assume this is a P-256 key, as specified in the contract of this method.
+                    ecParams =
+                            OpenSSLECGroupContext.getCurveByName("prime256v1").getECParameterSpec();
+                }
+                channelIdPrivateKey =
+                        OpenSSLKey.fromECPrivateKeyForTLSStackOnly(privateKey, ecParams);
+            } catch (InvalidKeyException e) {
+                // Will have error in startHandshake
+            }
+        }
+    }
+
+    /**
+     * Sets the listener for the completion of the TLS handshake.
+     */
+    @Override
+    void setHandshakeListener(HandshakeListener handshakeListener) {
+        synchronized (ssl) {
+            if (isHandshakeStarted()) {
+                throw new IllegalStateException(
+                        "Handshake listener must be set before starting the handshake.");
+            }
+            this.handshakeListener = handshakeListener;
+        }
+    }
+
+    private boolean isHandshakeStarted() {
+        switch (state) {
+            case STATE_NEW:
+            case STATE_MODE_SET:
+                return false;
+            default:
+                return true;
+        }
+    }
+
+    /**
+     * This method enables Server Name Indication (SNI) and overrides the {@link PeerInfoProvider}
+     * supplied during engine creation.  If the hostname is not a valid SNI hostname, the SNI
+     * extension will be omitted from the handshake.
+     */
+    @Override
+    void setHostname(String hostname) {
+        sslParameters.setUseSni(hostname != null);
+        this.peerHostname = hostname;
+    }
+
+    /**
+     * Returns the hostname from {@link #setHostname(String)} or supplied by the
+     * {@link PeerInfoProvider} upon creation. No DNS resolution is attempted before
+     * returning the hostname.
+     */
+    @Override
+    String getHostname() {
+        return peerHostname != null ? peerHostname : peerInfoProvider.getHostname();
+    }
+
+    @Override
+    public String getPeerHost() {
+        return peerHostname != null ? peerHostname : peerInfoProvider.getHostnameOrIP();
+    }
+
+    @Override
+    public int getPeerPort() {
+        return peerInfoProvider.getPort();
+    }
+
+    @Override
+    public void beginHandshake() throws SSLException {
+        synchronized (ssl) {
+            beginHandshakeInternal();
+        }
+    }
+
+    private void beginHandshakeInternal() throws SSLException {
+        switch (state) {
+            case STATE_NEW: {
+                throw new IllegalStateException("Client/server mode must be set before handshake");
+            }
+            case STATE_MODE_SET: {
+                // We know what mode to handshake in but have not started the handshake, proceed
+                break;
+            }
+            case STATE_CLOSED_INBOUND:
+            case STATE_CLOSED_OUTBOUND:
+            case STATE_CLOSED:
+                throw new IllegalStateException("Engine has already been closed");
+            default:
+                // We've already started the handshake, just return
+                return;
+        }
+
+        transitionTo(STATE_HANDSHAKE_STARTED);
+
+        boolean releaseResources = true;
+        try {
+            // Prepare the SSL object for the handshake.
+            ssl.initialize(getHostname(), channelIdPrivateKey);
+
+            // For clients, offer to resume a previously cached session to avoid the
+            // full TLS handshake.
+            if (getUseClientMode()) {
+                NativeSslSession cachedSession = clientSessionContext().getCachedSession(
+                        getHostname(), getPeerPort(), sslParameters);
+                if (cachedSession != null) {
+                    cachedSession.offerToResume(ssl);
+                }
+            }
+
+            maxSealOverhead = ssl.getMaxSealOverhead();
+            handshake();
+            releaseResources = false;
+        } catch (IOException e) {
+            // Write CCS errors to EventLog
+            String message = e.getMessage();
+            // Must match error reason string of SSL_R_UNEXPECTED_CCS (in ssl/ssl_err.c)
+            if (message.contains("unexpected CCS")) {
+                String logMessage = String.format("ssl_unexpected_ccs: host=%s", getPeerHost());
+                Platform.logEvent(logMessage);
+            }
+            throw SSLUtils.toSSLHandshakeException(e);
+        } finally {
+            if (releaseResources) {
+                closeAndFreeResources();
+            }
+        }
+    }
+
+    @Override
+    public void closeInbound() {
+        synchronized (ssl) {
+            if (state == STATE_CLOSED || state == STATE_CLOSED_INBOUND) {
+                return;
+            }
+            if (isHandshakeStarted()) {
+                if (state == STATE_CLOSED_OUTBOUND) {
+                    transitionTo(STATE_CLOSED);
+                } else {
+                    transitionTo(STATE_CLOSED_INBOUND);
+                }
+                freeIfDone();
+            } else {
+                // Never started the handshake. Just close now.
+                closeAndFreeResources();
+            }
+        }
+    }
+
+    @Override
+    public void closeOutbound() {
+        synchronized (ssl) {
+            if (state == STATE_CLOSED || state == STATE_CLOSED_OUTBOUND) {
+                return;
+            }
+            if (isHandshakeStarted()) {
+                if (state == STATE_CLOSED_INBOUND) {
+                    transitionTo(STATE_CLOSED);
+                } else {
+                    transitionTo(STATE_CLOSED_OUTBOUND);
+                }
+                sendSSLShutdown();
+                freeIfDone();
+            } else {
+                // Never started the handshake. Just close now.
+                closeAndFreeResources();
+            }
+        }
+    }
+
+    @Override
+    public Runnable getDelegatedTask() {
+        // This implementation doesn't use any delegated tasks.
+        return null;
+    }
+
+    @Override
+    public String[] getEnabledCipherSuites() {
+        return sslParameters.getEnabledCipherSuites();
+    }
+
+    @Override
+    public String[] getEnabledProtocols() {
+        return sslParameters.getEnabledProtocols();
+    }
+
+    @Override
+    public boolean getEnableSessionCreation() {
+        return sslParameters.getEnableSessionCreation();
+    }
+
+    @Override
+    public SSLParameters getSSLParameters() {
+        SSLParameters params = super.getSSLParameters();
+        Platform.getSSLParameters(params, sslParameters, this);
+        return params;
+    }
+
+    @Override
+    public void setSSLParameters(SSLParameters p) {
+        super.setSSLParameters(p);
+        Platform.setSSLParameters(p, sslParameters, this);
+    }
+
+    @Override
+    public HandshakeStatus getHandshakeStatus() {
+        synchronized (ssl) {
+            return getHandshakeStatusInternal();
+        }
+    }
+
+    private HandshakeStatus getHandshakeStatusInternal() {
+        if (handshakeFinished) {
+            return HandshakeStatus.NOT_HANDSHAKING;
+        }
+        switch (state) {
+            case STATE_HANDSHAKE_STARTED:
+                return pendingStatus(pendingOutboundEncryptedBytes());
+            case STATE_HANDSHAKE_COMPLETED:
+                return HandshakeStatus.NEED_WRAP;
+            case STATE_NEW:
+            case STATE_MODE_SET:
+            case STATE_CLOSED:
+            case STATE_CLOSED_INBOUND:
+            case STATE_CLOSED_OUTBOUND:
+            case STATE_READY:
+            case STATE_READY_HANDSHAKE_CUT_THROUGH:
+                return HandshakeStatus.NOT_HANDSHAKING;
+            default:
+                break;
+        }
+        throw new IllegalStateException("Unexpected engine state: " + state);
+    }
+
+    int pendingOutboundEncryptedBytes() {
+        return networkBio.getPendingWrittenBytes();
+    }
+
+    private int pendingInboundCleartextBytes() {
+        return ssl.getPendingReadableBytes();
+    }
+
+    private static SSLEngineResult.HandshakeStatus pendingStatus(int pendingOutboundBytes) {
+        // Depending on if there is something left in the BIO we need to WRAP or UNWRAP
+        return pendingOutboundBytes > 0 ? NEED_WRAP : NEED_UNWRAP;
+    }
+
+    @Override
+    public boolean getNeedClientAuth() {
+        return sslParameters.getNeedClientAuth();
+    }
+
+    /**
+     * Work-around to allow this method to be called on older versions of Android.
+     */
+    @Override
+    SSLSession handshakeSession() {
+        synchronized (ssl) {
+            if (state == STATE_HANDSHAKE_STARTED) {
+                return Platform.wrapSSLSession(new ExternalSession(new Provider() {
+                    @Override
+                    public ConscryptSession provideSession() {
+                        return ConscryptEngine.this.provideHandshakeSession();
+                    }
+                }));
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public SSLSession getSession() {
+        return externalSession;
+    }
+
+    private ConscryptSession provideSession() {
+        synchronized (ssl) {
+            if (state == STATE_CLOSED) {
+                return closedSession != null ? closedSession : SSLNullSession.getNullSession();
+            }
+            if (state < STATE_HANDSHAKE_COMPLETED) {
+                // Return an invalid session with invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
+                return SSLNullSession.getNullSession();
+            }
+            return activeSession;
+        }
+    }
+
+    private ConscryptSession provideHandshakeSession() {
+        synchronized (ssl) {
+            return state == STATE_HANDSHAKE_STARTED ? activeSession
+                : SSLNullSession.getNullSession();
+        }
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return NativeCrypto.getSupportedCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedProtocols() {
+        return NativeCrypto.getSupportedProtocols();
+    }
+
+    @Override
+    public boolean getUseClientMode() {
+        return sslParameters.getUseClientMode();
+    }
+
+    @Override
+    public boolean getWantClientAuth() {
+        return sslParameters.getWantClientAuth();
+    }
+
+    @Override
+    public boolean isInboundDone() {
+        synchronized (ssl) {
+            return (state == STATE_CLOSED || state == STATE_CLOSED_INBOUND
+                           || ssl.wasShutdownReceived())
+                    && (pendingInboundCleartextBytes() == 0);
+        }
+    }
+
+    @Override
+    public boolean isOutboundDone() {
+        synchronized (ssl) {
+            return (state == STATE_CLOSED || state == STATE_CLOSED_OUTBOUND
+                           || ssl.wasShutdownSent())
+                    && (pendingOutboundEncryptedBytes() == 0);
+        }
+    }
+
+    @Override
+    public void setEnabledCipherSuites(String[] suites) {
+        sslParameters.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public void setEnabledProtocols(String[] protocols) {
+        sslParameters.setEnabledProtocols(protocols);
+    }
+
+    @Override
+    public void setEnableSessionCreation(boolean flag) {
+        sslParameters.setEnableSessionCreation(flag);
+    }
+
+    @Override
+    public void setNeedClientAuth(boolean need) {
+        sslParameters.setNeedClientAuth(need);
+    }
+
+    @Override
+    public void setUseClientMode(boolean mode) {
+        synchronized (ssl) {
+            if (isHandshakeStarted()) {
+                throw new IllegalArgumentException(
+                        "Can not change mode after handshake: state == " + state);
+            }
+            transitionTo(STATE_MODE_SET);
+            sslParameters.setUseClientMode(mode);
+        }
+    }
+
+    @Override
+    public void setWantClientAuth(boolean want) {
+        sslParameters.setWantClientAuth(want);
+    }
+
+    @Override
+    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        synchronized (ssl) {
+            try {
+                return unwrap(singleSrcBuffer(src), singleDstBuffer(dst));
+            } finally {
+                resetSingleSrcBuffer();
+                resetSingleDstBuffer();
+            }
+        }
+    }
+
+    @Override
+    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException {
+        synchronized (ssl) {
+            try {
+                return unwrap(singleSrcBuffer(src), dsts);
+            } finally {
+                resetSingleSrcBuffer();
+            }
+        }
+    }
+
+    @Override
+    public SSLEngineResult unwrap(final ByteBuffer src, final ByteBuffer[] dsts, final int offset,
+            final int length) throws SSLException {
+        synchronized (ssl) {
+            try {
+                return unwrap(singleSrcBuffer(src), 0, 1, dsts, offset, length);
+            } finally {
+                resetSingleSrcBuffer();
+            }
+        }
+    }
+
+    @Override
+    SSLEngineResult unwrap(final ByteBuffer[] srcs, final ByteBuffer[] dsts) throws SSLException {
+        checkArgument(srcs != null, "srcs is null");
+        checkArgument(dsts != null, "dsts is null");
+        return unwrap(srcs, 0, srcs.length, dsts, 0, dsts.length);
+    }
+
+    @Override
+    SSLEngineResult unwrap(final ByteBuffer[] srcs, int srcsOffset, final int srcsLength,
+            final ByteBuffer[] dsts, final int dstsOffset, final int dstsLength)
+            throws SSLException {
+        checkArgument(srcs != null, "srcs is null");
+        checkArgument(dsts != null, "dsts is null");
+        checkPositionIndexes(srcsOffset, srcsOffset + srcsLength, srcs.length);
+        checkPositionIndexes(dstsOffset, dstsOffset + dstsLength, dsts.length);
+
+        // Determine the output capacity.
+        final int dstLength = calcDstsLength(dsts, dstsOffset, dstsLength);
+        final int endOffset = dstsOffset + dstsLength;
+
+        final int srcsEndOffset = srcsOffset + srcsLength;
+        final long srcLength = calcSrcsLength(srcs, srcsOffset, srcsEndOffset);
+
+        synchronized (ssl) {
+            switch (state) {
+                case STATE_MODE_SET:
+                    // Begin the handshake implicitly.
+                    beginHandshakeInternal();
+                    break;
+                case STATE_CLOSED_INBOUND:
+                case STATE_CLOSED:
+                    freeIfDone();
+                    // If the inbound direction is closed. we can't send anymore.
+                    return new SSLEngineResult(Status.CLOSED, getHandshakeStatusInternal(), 0, 0);
+                case STATE_NEW:
+                    throw new IllegalStateException(
+                            "Client/server mode must be set before calling unwrap");
+                default:
+                    break;
+            }
+
+            HandshakeStatus handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
+            if (!handshakeFinished) {
+                handshakeStatus = handshake();
+                if (handshakeStatus == NEED_WRAP) {
+                    return NEED_WRAP_OK;
+                }
+                if (state == STATE_CLOSED) {
+                    return NEED_WRAP_CLOSED;
+                }
+                // NEED_UNWRAP - just fall through to perform the unwrap.
+            }
+
+            // Consume any source data. Skip this if there are unread cleartext data.
+            boolean noCleartextDataAvailable = pendingInboundCleartextBytes() <= 0;
+            int lenRemaining = 0;
+            if (srcLength > 0 && noCleartextDataAvailable) {
+                if (srcLength < SSL3_RT_HEADER_LENGTH) {
+                    // Need to be able to read a full TLS header.
+                    return new SSLEngineResult(BUFFER_UNDERFLOW, getHandshakeStatus(), 0, 0);
+                }
+
+                int packetLength = SSLUtils.getEncryptedPacketLength(srcs, srcsOffset);
+                if (packetLength < 0) {
+                    throw new SSLException("Unable to parse TLS packet header");
+                }
+
+                if (srcLength < packetLength) {
+                    // We either have not enough data to read the packet header or not enough for
+                    // reading the whole packet.
+                    return new SSLEngineResult(BUFFER_UNDERFLOW, getHandshakeStatus(), 0, 0);
+                }
+
+                // Limit the amount of data to be read to a single packet.
+                lenRemaining = packetLength;
+            } else if (noCleartextDataAvailable) {
+                // No pending data and nothing provided as input.  Need more data.
+                return new SSLEngineResult(BUFFER_UNDERFLOW, getHandshakeStatus(), 0, 0);
+            }
+
+            // Write all of the encrypted source data to the networkBio
+            int bytesConsumed = 0;
+            if (lenRemaining > 0 && srcsOffset < srcsEndOffset) {
+                do {
+                    ByteBuffer src = srcs[srcsOffset];
+                    int remaining = src.remaining();
+                    if (remaining == 0) {
+                        // We must skip empty buffers as BIO_write will return 0 if asked to
+                        // write something with length 0.
+                        srcsOffset++;
+                        continue;
+                    }
+                    // Write the source encrypted data to the networkBio.
+                    int written = writeEncryptedData(src, min(lenRemaining, remaining));
+                    if (written > 0) {
+                        bytesConsumed += written;
+                        lenRemaining -= written;
+                        if (lenRemaining == 0) {
+                            // A whole packet has been consumed.
+                            break;
+                        }
+
+                        if (written == remaining) {
+                            srcsOffset++;
+                        } else {
+                            // We were not able to write everything into the BIO so break the
+                            // write loop as otherwise we will produce an error on the next
+                            // write attempt, which will trigger a SSL.clearError() later.
+                            break;
+                        }
+                    } else {
+                        // BIO_write returned a negative or zero number, this means we could not
+                        // complete the write operation and should retry later.
+                        // We ignore BIO_* errors here as we use in memory BIO anyway and will
+                        // do another SSL_* call later on in which we will produce an exception
+                        // in case of an error
+                        NativeCrypto.SSL_clear_error();
+                        break;
+                    }
+                } while (srcsOffset < srcsEndOffset);
+            }
+
+            // Now read any available plaintext data.
+            int bytesProduced = 0;
+            try {
+                if (dstLength > 0) {
+                    // Write decrypted data to dsts buffers
+                    for (int idx = dstsOffset; idx < endOffset; ++idx) {
+                        ByteBuffer dst = dsts[idx];
+                        if (!dst.hasRemaining()) {
+                            continue;
+                        }
+
+                        int bytesRead = readPlaintextData(dst);
+                        if (bytesRead > 0) {
+                            bytesProduced += bytesRead;
+                            if (dst.hasRemaining()) {
+                                // We haven't filled this buffer fully, break out of the loop
+                                // and determine the correct response status below.
+                                break;
+                            }
+                        } else {
+                            switch (bytesRead) {
+                                case -SSL_ERROR_WANT_READ:
+                                case -SSL_ERROR_WANT_WRITE: {
+                                    return newResult(bytesConsumed, bytesProduced, handshakeStatus);
+                                }
+                                case -SSL_ERROR_ZERO_RETURN: {
+                                    // We received a close_notify from the peer, so mark the
+                                    // inbound direction as closed and shut down the SSL object
+                                    closeInbound();
+                                    sendSSLShutdown();
+                                    return new SSLEngineResult(Status.CLOSED,
+                                            pendingOutboundEncryptedBytes() > 0
+                                                    ? NEED_WRAP : NOT_HANDSHAKING,
+                                            bytesConsumed, bytesProduced);
+                                }
+                                default: {
+                                    // Should never get here.
+                                    sendSSLShutdown();
+                                    throw newSslExceptionWithMessage("SSL_read");
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    // If the capacity of all destination buffers is 0 we need to trigger a SSL_read
+                    // anyway to ensure everything is flushed in the BIO pair and so we can detect
+                    // it in the pendingInboundCleartextBytes() call.
+                    ssl.forceRead();
+                }
+            } catch (SSLException e) {
+                // Shut down the SSL and rethrow the exception.  Users will need to drain any alerts
+                // from the SSL before closing.
+                sendSSLShutdown();
+                throw convertException(e);
+            } catch (InterruptedIOException e) {
+                return newResult(bytesConsumed, bytesProduced, handshakeStatus);
+            } catch (EOFException e) {
+                closeAll();
+                throw convertException(e);
+            } catch (IOException e) {
+                sendSSLShutdown();
+                throw convertException(e);
+            }
+
+            // There won't be any application data until we're done handshaking.
+            // We first check handshakeFinished to eliminate the overhead of extra JNI call if
+            // possible.
+            int pendingCleartextBytes = handshakeFinished ? pendingInboundCleartextBytes() : 0;
+            if (pendingCleartextBytes > 0) {
+                // We filled all buffers but there is still some data pending in the BIO buffer,
+                // return BUFFER_OVERFLOW.
+                return new SSLEngineResult(BUFFER_OVERFLOW,
+                        mayFinishHandshake(handshakeStatus == FINISHED
+                                        ? handshakeStatus
+                                        : getHandshakeStatusInternal()),
+                        bytesConsumed, bytesProduced);
+            }
+
+            return newResult(bytesConsumed, bytesProduced, handshakeStatus);
+        }
+    }
+
+    private static int calcDstsLength(ByteBuffer[] dsts, int dstsOffset, int dstsLength) {
+        int capacity = 0;
+        for (int i = 0; i < dsts.length; i++) {
+            ByteBuffer dst = dsts[i];
+            checkArgument(dst != null, "dsts[%d] is null", i);
+            if (dst.isReadOnly()) {
+                throw new ReadOnlyBufferException();
+            }
+            if (i >= dstsOffset && i < dstsOffset + dstsLength) {
+                capacity += dst.remaining();
+            }
+        }
+        return capacity;
+    }
+
+    private static long calcSrcsLength(ByteBuffer[] srcs, int srcsOffset, int srcsEndOffset) {
+        long len = 0;
+        for (int i = srcsOffset; i < srcsEndOffset; i++) {
+            ByteBuffer src = srcs[i];
+            if (src == null) {
+                throw new IllegalArgumentException("srcs[" + i + "] is null");
+            }
+            len += src.remaining();
+        }
+        return len;
+    }
+
+    private SSLEngineResult.HandshakeStatus handshake() throws SSLException {
+        try {
+            // Only actually perform the handshake if we haven't already just completed it
+            // via BIO operations.
+            try {
+                int ssl_error_code = ssl.doHandshake();
+                switch (ssl_error_code) {
+                    case SSL_ERROR_WANT_READ:
+                        return pendingStatus(pendingOutboundEncryptedBytes());
+                    case SSL_ERROR_WANT_WRITE: {
+                        return NEED_WRAP;
+                    }
+                    default: {
+                        // SSL_ERROR_NONE.
+                    }
+                }
+            } catch (SSLException e) {
+                // Shut down the SSL and rethrow the exception.  Users will need to drain any alerts
+                // from the SSL before closing.
+                sendSSLShutdown();
+                throw e;
+            } catch (IOException e) {
+                sendSSLShutdown();
+                throw e;
+            }
+
+            // The handshake has completed successfully...
+
+            // Update the session from the current state of the SSL object.
+            activeSession.onPeerCertificateAvailable(getPeerHost(), getPeerPort());
+
+            finishHandshake();
+            return FINISHED;
+        } catch (Exception e) {
+            throw toSSLHandshakeException(e);
+        }
+    }
+
+    private void finishHandshake() throws SSLException {
+        handshakeFinished = true;
+        // Notify the listener, if provided.
+        if (handshakeListener != null) {
+            handshakeListener.onHandshakeFinished();
+        }
+    }
+
+    /**
+     * Write plaintext data to the OpenSSL internal BIO
+     *
+     * Calling this function with src.remaining == 0 is undefined.
+     */
+    private int writePlaintextData(final ByteBuffer src, int len) throws SSLException {
+        try {
+            final int pos = src.position();
+            final int sslWrote;
+            if (src.isDirect()) {
+                sslWrote = writePlaintextDataDirect(src, pos, len);
+            } else {
+                sslWrote = writePlaintextDataHeap(src, pos, len);
+            }
+            if (sslWrote > 0) {
+                src.position(pos + sslWrote);
+            }
+            return sslWrote;
+        } catch (Exception e) {
+            throw convertException(e);
+        }
+    }
+
+    private int writePlaintextDataDirect(ByteBuffer src, int pos, int len) throws IOException {
+        return ssl.writeDirectByteBuffer(directByteBufferAddress(src, pos), len);
+    }
+
+    private int writePlaintextDataHeap(ByteBuffer src, int pos, int len) throws IOException {
+        AllocatedBuffer allocatedBuffer = null;
+        try {
+            final ByteBuffer buffer;
+            if (bufferAllocator != null) {
+                allocatedBuffer = bufferAllocator.allocateDirectBuffer(len);
+                buffer = allocatedBuffer.nioBuffer();
+            } else {
+                // We don't have a buffer allocator, but we don't want to send a heap
+                // buffer to JNI. So lazy-create a direct buffer that we will use from now
+                // on to copy plaintext data.
+                buffer = getOrCreateLazyDirectBuffer();
+            }
+
+            // Copy the data to the direct buffer.
+            int limit = src.limit();
+            int bytesToWrite = min(len, buffer.remaining());
+            src.limit(pos + bytesToWrite);
+            buffer.put(src);
+            buffer.flip();
+            // Restore the original position and limit.
+            src.limit(limit);
+            src.position(pos);
+
+            return writePlaintextDataDirect(buffer, 0, bytesToWrite);
+        } finally {
+            if (allocatedBuffer != null) {
+                // Release the buffer back to the pool.
+                allocatedBuffer.release();
+            }
+        }
+    }
+
+    /**
+     * Read plaintext data from the OpenSSL internal BIO
+     */
+    private int readPlaintextData(final ByteBuffer dst) throws IOException {
+        try {
+            final int pos = dst.position();
+            final int limit = dst.limit();
+            final int len = min(SSL3_RT_MAX_PACKET_SIZE, limit - pos);
+            if (dst.isDirect()) {
+                int bytesRead = readPlaintextDataDirect(dst, pos, len);
+                if (bytesRead > 0) {
+                    dst.position(pos + bytesRead);
+                }
+                return bytesRead;
+            }
+
+            // The heap method updates the dst position automatically.
+            return readPlaintextDataHeap(dst, len);
+        } catch (CertificateException e) {
+            throw convertException(e);
+        }
+    }
+
+    private int readPlaintextDataDirect(ByteBuffer dst, int pos, int len)
+            throws IOException, CertificateException {
+        return ssl.readDirectByteBuffer(directByteBufferAddress(dst, pos), len);
+    }
+
+    private int readPlaintextDataHeap(ByteBuffer dst, int len)
+            throws IOException, CertificateException {
+        AllocatedBuffer allocatedBuffer = null;
+        try {
+            final ByteBuffer buffer;
+            if (bufferAllocator != null) {
+                allocatedBuffer = bufferAllocator.allocateDirectBuffer(len);
+                buffer = allocatedBuffer.nioBuffer();
+            } else {
+                // We don't have a buffer allocator, but we don't want to send a heap
+                // buffer to JNI. So lazy-create a direct buffer that we will use from now
+                // on to copy plaintext data.
+                buffer = getOrCreateLazyDirectBuffer();
+            }
+
+            // Read the data to the direct buffer.
+            int bytesToRead = min(len, buffer.remaining());
+            int bytesRead = readPlaintextDataDirect(buffer, 0, bytesToRead);
+            if (bytesRead > 0) {
+                // Copy the data to the heap buffer.
+                buffer.position(bytesRead);
+                buffer.flip();
+                dst.put(buffer);
+            }
+
+            return bytesRead;
+        } finally {
+            if (allocatedBuffer != null) {
+                // Release the buffer back to the pool.
+                allocatedBuffer.release();
+            }
+        }
+    }
+
+    private SSLException convertException(Throwable e) {
+        if (e instanceof SSLHandshakeException || !handshakeFinished) {
+            return SSLUtils.toSSLHandshakeException(e);
+        }
+        return SSLUtils.toSSLException(e);
+    }
+
+    /**
+     * Write encrypted data to the OpenSSL network BIO.
+     */
+    private int writeEncryptedData(final ByteBuffer src, int len) throws SSLException {
+        try {
+            final int pos = src.position();
+            final int bytesWritten;
+            if (src.isDirect()) {
+                bytesWritten = writeEncryptedDataDirect(src, pos, len);
+            } else {
+                bytesWritten = writeEncryptedDataHeap(src, pos, len);
+            }
+
+            if (bytesWritten > 0) {
+                src.position(pos + bytesWritten);
+            }
+
+            return bytesWritten;
+        } catch (IOException e) {
+            throw new SSLException(e);
+        }
+    }
+
+    private int writeEncryptedDataDirect(ByteBuffer src, int pos, int len) throws IOException {
+        return networkBio.writeDirectByteBuffer(directByteBufferAddress(src, pos), len);
+    }
+
+    private int writeEncryptedDataHeap(ByteBuffer src, int pos, int len) throws IOException {
+        AllocatedBuffer allocatedBuffer = null;
+        try {
+            final ByteBuffer buffer;
+            if (bufferAllocator != null) {
+                allocatedBuffer = bufferAllocator.allocateDirectBuffer(len);
+                buffer = allocatedBuffer.nioBuffer();
+            } else {
+                // We don't have a buffer allocator, but we don't want to send a heap
+                // buffer to JNI. So lazy-create a direct buffer that we will use from now
+                // on to copy encrypted packets.
+                buffer = getOrCreateLazyDirectBuffer();
+            }
+
+            int limit = src.limit();
+            int bytesToCopy = min(min(limit - pos, len), buffer.remaining());
+            src.limit(pos + bytesToCopy);
+            buffer.put(src);
+            // Restore the original limit.
+            src.limit(limit);
+
+            // Reset the original position on the source buffer.
+            src.position(pos);
+
+            int bytesWritten = writeEncryptedDataDirect(buffer, 0, bytesToCopy);
+
+            // Restore the original position.
+            src.position(pos);
+
+            return bytesWritten;
+        } finally {
+            if (allocatedBuffer != null) {
+                // Release the buffer back to the pool.
+                allocatedBuffer.release();
+            }
+        }
+    }
+
+    private ByteBuffer getOrCreateLazyDirectBuffer() {
+        if (lazyDirectBuffer == null) {
+            lazyDirectBuffer = ByteBuffer.allocateDirect(
+                    max(SSL3_RT_MAX_PLAIN_LENGTH, SSL3_RT_MAX_PACKET_SIZE));
+        }
+        lazyDirectBuffer.clear();
+        return lazyDirectBuffer;
+    }
+
+    private long directByteBufferAddress(ByteBuffer directBuffer, int pos) {
+        return NativeCrypto.getDirectBufferAddress(directBuffer) + pos;
+    }
+
+    private SSLEngineResult readPendingBytesFromBIO(ByteBuffer dst, int bytesConsumed,
+            int bytesProduced, SSLEngineResult.HandshakeStatus status) throws SSLException {
+        try {
+            // Check to see if the engine wrote data into the network BIO
+            int pendingNet = pendingOutboundEncryptedBytes();
+            if (pendingNet > 0) {
+                // Do we have enough room in dst to write encrypted data?
+                int capacity = dst.remaining();
+                if (capacity < pendingNet) {
+                    return new SSLEngineResult(BUFFER_OVERFLOW,
+                            mayFinishHandshake(
+                                    status == FINISHED ? status : getHandshakeStatus(pendingNet)),
+                            bytesConsumed, bytesProduced);
+                }
+
+                // Write the pending data from the network BIO into the dst buffer
+                int produced = readEncryptedData(dst, pendingNet);
+
+                if (produced <= 0) {
+                    // We ignore BIO_* errors here as we use in memory BIO anyway and will do
+                    // another SSL_* call later on in which we will produce an exception in
+                    // case of an error
+                    NativeCrypto.SSL_clear_error();
+                } else {
+                    bytesProduced += produced;
+                    pendingNet -= produced;
+                }
+
+                return new SSLEngineResult(getEngineStatus(),
+                        mayFinishHandshake(
+                                status == FINISHED ? status : getHandshakeStatus(pendingNet)),
+                        bytesConsumed, bytesProduced);
+            }
+            return null;
+        } catch (Exception e) {
+            throw convertException(e);
+        }
+    }
+
+    /**
+     * Read encrypted data from the OpenSSL network BIO
+     */
+    private int readEncryptedData(final ByteBuffer dst, final int pending) throws SSLException {
+        try {
+            int bytesRead = 0;
+            final int pos = dst.position();
+            if (dst.remaining() >= pending) {
+                final int limit = dst.limit();
+                final int len = min(pending, limit - pos);
+                if (dst.isDirect()) {
+                    bytesRead = readEncryptedDataDirect(dst, pos, len);
+                    // Need to update the position on the dst buffer.
+                    if (bytesRead > 0) {
+                        dst.position(pos + bytesRead);
+                    }
+                } else {
+                    // The heap method will update the position on the dst buffer automatically.
+                    bytesRead = readEncryptedDataHeap(dst, len);
+                }
+            }
+
+            return bytesRead;
+        } catch (Exception e) {
+            throw convertException(e);
+        }
+    }
+
+    private int readEncryptedDataDirect(ByteBuffer dst, int pos, int len) throws IOException {
+        return networkBio.readDirectByteBuffer(directByteBufferAddress(dst, pos), len);
+    }
+
+    private int readEncryptedDataHeap(ByteBuffer dst, int len) throws IOException {
+        AllocatedBuffer allocatedBuffer = null;
+        try {
+            final ByteBuffer buffer;
+            if (bufferAllocator != null) {
+                allocatedBuffer = bufferAllocator.allocateDirectBuffer(len);
+                buffer = allocatedBuffer.nioBuffer();
+            } else {
+                // We don't have a buffer allocator, but we don't want to send a heap
+                // buffer to JNI. So lazy-create a direct buffer that we will use from now
+                // on to copy encrypted packets.
+                buffer = getOrCreateLazyDirectBuffer();
+            }
+
+            int bytesToRead = min(len, buffer.remaining());
+            int bytesRead = readEncryptedDataDirect(buffer, 0, bytesToRead);
+            if (bytesRead > 0) {
+                buffer.position(bytesRead);
+                buffer.flip();
+                dst.put(buffer);
+            }
+
+            return bytesRead;
+        } finally {
+            if (allocatedBuffer != null) {
+                // Release the buffer back to the pool.
+                allocatedBuffer.release();
+            }
+        }
+    }
+
+    private SSLEngineResult.HandshakeStatus mayFinishHandshake(
+            SSLEngineResult.HandshakeStatus status) throws SSLException {
+        if (!handshakeFinished && status == NOT_HANDSHAKING) {
+            // If the status was NOT_HANDSHAKING and we not finished the handshake we need to call
+            // SSL_do_handshake() again
+            return handshake();
+        }
+        return status;
+    }
+
+    private SSLEngineResult.HandshakeStatus getHandshakeStatus(int pending) {
+        // Check if we are in the initial handshake phase or shutdown phase
+        return !handshakeFinished ? pendingStatus(pending) : NOT_HANDSHAKING;
+    }
+
+    private SSLEngineResult.Status getEngineStatus() {
+        switch (state) {
+            case STATE_CLOSED_INBOUND:
+            case STATE_CLOSED_OUTBOUND:
+            case STATE_CLOSED:
+                return CLOSED;
+            default:
+                return OK;
+        }
+    }
+
+    private void closeAll() {
+        closeOutbound();
+        closeInbound();
+    }
+
+    private void freeIfDone() {
+        if (isInboundDone() && isOutboundDone()) {
+            closeAndFreeResources();
+        }
+    }
+
+    private SSLException newSslExceptionWithMessage(String err) {
+        if (!handshakeFinished) {
+            return new SSLException(err);
+        }
+        return new SSLHandshakeException(err);
+    }
+
+    private SSLEngineResult newResult(int bytesConsumed, int bytesProduced,
+            SSLEngineResult.HandshakeStatus status) throws SSLException {
+        return new SSLEngineResult(getEngineStatus(),
+                mayFinishHandshake(status == FINISHED ? status : getHandshakeStatusInternal()),
+                bytesConsumed, bytesProduced);
+    }
+
+    @Override
+    public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        synchronized (ssl) {
+            try {
+                return wrap(singleSrcBuffer(src), dst);
+            } finally {
+                resetSingleSrcBuffer();
+            }
+        }
+    }
+
+    @Override
+    public SSLEngineResult wrap(ByteBuffer[] srcs, int srcsOffset, int srcsLength, ByteBuffer dst)
+            throws SSLException {
+        checkArgument(srcs != null, "srcs is null");
+        checkArgument(dst != null, "dst is null");
+        checkPositionIndexes(srcsOffset, srcsOffset + srcsLength, srcs.length);
+        if (dst.isReadOnly()) {
+            throw new ReadOnlyBufferException();
+        }
+
+        synchronized (ssl) {
+            switch (state) {
+                case STATE_MODE_SET:
+                    // Begin the handshake implicitly.
+                    beginHandshakeInternal();
+                    break;
+                case STATE_CLOSED_OUTBOUND:
+                case STATE_CLOSED:
+                    // We may have pending encrypted bytes from a close_notify alert, so
+                    // try to read them out
+                    SSLEngineResult pendingNetResult =
+                            readPendingBytesFromBIO(dst, 0, 0, HandshakeStatus.NOT_HANDSHAKING);
+                    if (pendingNetResult != null) {
+                        freeIfDone();
+                        return pendingNetResult;
+                    }
+                    return new SSLEngineResult(Status.CLOSED, getHandshakeStatusInternal(), 0, 0);
+                case STATE_NEW:
+                    throw new IllegalStateException(
+                            "Client/server mode must be set before calling wrap");
+                default:
+                    break;
+            }
+
+            // If we haven't completed the handshake yet, just let the caller know.
+            HandshakeStatus handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
+            // Prepare OpenSSL to work in server mode and receive handshake
+            if (!handshakeFinished) {
+                handshakeStatus = handshake();
+                if (handshakeStatus == NEED_UNWRAP) {
+                    return NEED_UNWRAP_OK;
+                }
+
+                if (state == STATE_CLOSED) {
+                    return NEED_UNWRAP_CLOSED;
+                }
+                // NEED_WRAP - just fall through to perform the wrap.
+            }
+
+            int srcsLen = 0;
+            final int endOffset = srcsOffset + srcsLength;
+            for (int i = srcsOffset; i < endOffset; ++i) {
+                final ByteBuffer src = srcs[i];
+                if (src == null) {
+                    throw new IllegalArgumentException("srcs[" + i + "] is null");
+                }
+                if (srcsLen == SSL3_RT_MAX_PLAIN_LENGTH) {
+                    continue;
+                }
+
+                srcsLen += src.remaining();
+                if (srcsLen > SSL3_RT_MAX_PLAIN_LENGTH || srcsLen < 0) {
+                    // If srcLen > MAX_PLAINTEXT_LENGTH or secLen < 0 just set it to
+                    // MAX_PLAINTEXT_LENGTH.
+                    // This also help us to guard against overflow.
+                    // We not break out here as we still need to check for null entries in srcs[].
+                    srcsLen = SSL3_RT_MAX_PLAIN_LENGTH;
+                }
+            }
+
+            if (dst.remaining() < calculateOutNetBufSize(srcsLen)) {
+                return new SSLEngineResult(
+                    Status.BUFFER_OVERFLOW, getHandshakeStatusInternal(), 0, 0);
+            }
+
+            int bytesProduced = 0;
+            int bytesConsumed = 0;
+        loop:
+            for (int i = srcsOffset; i < endOffset; ++i) {
+                final ByteBuffer src = srcs[i];
+                checkArgument(src != null, "srcs[%d] is null", i);
+                while (src.hasRemaining()) {
+                    final SSLEngineResult pendingNetResult;
+                    // Write plaintext application data to the SSL engine
+                    int result = writePlaintextData(
+                        src, min(src.remaining(), SSL3_RT_MAX_PLAIN_LENGTH - bytesConsumed));
+                    if (result > 0) {
+                        bytesConsumed += result;
+
+                        pendingNetResult = readPendingBytesFromBIO(
+                            dst, bytesConsumed, bytesProduced, handshakeStatus);
+                        if (pendingNetResult != null) {
+                            if (pendingNetResult.getStatus() != OK) {
+                                return pendingNetResult;
+                            }
+                            bytesProduced = pendingNetResult.bytesProduced();
+                        }
+                        if (bytesConsumed == SSL3_RT_MAX_PLAIN_LENGTH) {
+                            // If we consumed the maximum amount of bytes for the plaintext length
+                            // break out of the loop and start to fill the dst buffer.
+                            break loop;
+                        }
+                    } else {
+                        int sslError = ssl.getError(result);
+                        switch (sslError) {
+                            case SSL_ERROR_ZERO_RETURN:
+                                // This means the connection was shutdown correctly, close inbound
+                                // and outbound
+                                closeAll();
+                                pendingNetResult = readPendingBytesFromBIO(
+                                        dst, bytesConsumed, bytesProduced, handshakeStatus);
+                                return pendingNetResult != null ? pendingNetResult
+                                                                : CLOSED_NOT_HANDSHAKING;
+                            case SSL_ERROR_WANT_READ:
+                                // If there is no pending data to read from BIO we should go back to
+                                // event loop and try
+                                // to read more data [1]. It is also possible that event loop will
+                                // detect the socket
+                                // has been closed. [1]
+                                // https://www.openssl.org/docs/manmaster/man3/SSL_write.html
+                                pendingNetResult = readPendingBytesFromBIO(
+                                        dst, bytesConsumed, bytesProduced, handshakeStatus);
+                                return pendingNetResult != null
+                                        ? pendingNetResult
+                                        : new SSLEngineResult(getEngineStatus(), NEED_UNWRAP,
+                                                  bytesConsumed, bytesProduced);
+                            case SSL_ERROR_WANT_WRITE:
+                                // SSL_ERROR_WANT_WRITE typically means that the underlying
+                                // transport is not writable
+                                // and we should set the "want write" flag on the selector and try
+                                // again when the
+                                // underlying transport is writable [1]. However we are not directly
+                                // writing to the
+                                // underlying transport and instead writing to a BIO buffer. The
+                                // OpenSsl documentation
+                                // says we should do the following [1]:
+                                //
+                                // "When using a buffering BIO, like a BIO pair, data must be
+                                // written into or retrieved
+                                // out of the BIO before being able to continue."
+                                //
+                                // So we attempt to drain the BIO buffer below, but if there is no
+                                // data this condition
+                                // is undefined and we assume their is a fatal error with the
+                                // openssl engine and close.
+                                // [1] https://www.openssl.org/docs/manmaster/man3/SSL_write.html
+                                pendingNetResult = readPendingBytesFromBIO(
+                                        dst, bytesConsumed, bytesProduced, handshakeStatus);
+                                return pendingNetResult != null ? pendingNetResult
+                                                                : NEED_WRAP_CLOSED;
+                            default:
+                                // Everything else is considered as error
+                                sendSSLShutdown();
+                                throw newSslExceptionWithMessage("SSL_write");
+                        }
+                    }
+                }
+            }
+            // We need to check if pendingWrittenBytesInBIO was checked yet, as we may not checked
+            // if the srcs was
+            // empty, or only contained empty buffers.
+            if (bytesConsumed == 0) {
+                SSLEngineResult pendingNetResult =
+                        readPendingBytesFromBIO(dst, 0, bytesProduced, handshakeStatus);
+                if (pendingNetResult != null) {
+                    return pendingNetResult;
+                }
+            }
+
+            // return new SSLEngineResult(OK, getHandshakeStatusInternal(), bytesConsumed,
+            // bytesProduced);
+            return newResult(bytesConsumed, bytesProduced, handshakeStatus);
+        }
+    }
+
+    @Override
+    public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) {
+        return ssl.clientPSKKeyRequested(identityHint, identity, key);
+    }
+
+    @Override
+    public int serverPSKKeyRequested(String identityHint, String identity, byte[] key) {
+        return ssl.serverPSKKeyRequested(identityHint, identity, key);
+    }
+
+    @Override
+    public void onSSLStateChange(int type, int val) {
+        synchronized (ssl) {
+            switch (type) {
+                case SSL_CB_HANDSHAKE_START: {
+                    // For clients, this will allow the NEED_UNWRAP status to be
+                    // returned.
+                    transitionTo(STATE_HANDSHAKE_STARTED);
+                    break;
+                }
+                case SSL_CB_HANDSHAKE_DONE: {
+                    if (state != STATE_HANDSHAKE_STARTED
+                            && state != STATE_READY_HANDSHAKE_CUT_THROUGH) {
+                        throw new IllegalStateException(
+                                "Completed handshake while in mode " + state);
+                    }
+                    transitionTo(STATE_HANDSHAKE_COMPLETED);
+                    break;
+                }
+                default:
+                    // Ignore
+            }
+        }
+    }
+
+    @Override
+    public void onNewSessionEstablished(long sslSessionNativePtr) {
+        try {
+            // Increment the reference count to "take ownership" of the session resource.
+            NativeCrypto.SSL_SESSION_up_ref(sslSessionNativePtr);
+
+            // Create a native reference which will release the SSL_SESSION in its finalizer.
+            // This constructor will only throw if the native pointer passed in is NULL, which
+            // BoringSSL guarantees will not happen.
+            NativeRef.SSL_SESSION ref = new SSL_SESSION(sslSessionNativePtr);
+
+            NativeSslSession nativeSession = NativeSslSession.newInstance(ref, activeSession);
+
+            // Cache the newly established session.
+            AbstractSessionContext ctx = sessionContext();
+            ctx.cacheSession(nativeSession);
+        } catch (Exception ignored) {
+            // Ignore.
+        }
+    }
+
+    @Override
+    public long serverSessionRequested(byte[] id) {
+        // TODO(nathanmittler): Implement server-side caching for TLS < 1.3
+        return 0;
+    }
+
+    @Override
+    public void verifyCertificateChain(byte[][] certChain, String authMethod)
+            throws CertificateException {
+        try {
+            if (certChain == null || certChain.length == 0) {
+                throw new CertificateException("Peer sent no certificate");
+            }
+            X509Certificate[] peerCertChain = SSLUtils.decodeX509CertificateChain(certChain);
+
+            X509TrustManager x509tm = sslParameters.getX509TrustManager();
+            if (x509tm == null) {
+                throw new CertificateException("No X.509 TrustManager");
+            }
+
+            // Update the peer information on the session.
+            activeSession.onPeerCertificatesReceived(getPeerHost(), getPeerPort(), peerCertChain);
+
+            if (getUseClientMode()) {
+                Platform.checkServerTrusted(x509tm, peerCertChain, authMethod, this);
+            } else {
+                String authType = peerCertChain[0].getPublicKey().getAlgorithm();
+                Platform.checkClientTrusted(x509tm, peerCertChain, authType, this);
+            }
+        } catch (CertificateException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    @Override
+    public void clientCertificateRequested(byte[] keyTypeBytes, int[] signatureAlgs,
+            byte[][] asn1DerEncodedPrincipals)
+            throws CertificateEncodingException, SSLException {
+        ssl.chooseClientCertificate(keyTypeBytes, signatureAlgs, asn1DerEncodedPrincipals);
+    }
+
+    private void sendSSLShutdown() {
+        try {
+            ssl.shutdown();
+        } catch (IOException ignored) {
+            // TODO: The RI ignores close failures in SSLSocket, but need to
+            // investigate whether it does for SSLEngine.
+        }
+    }
+
+    private void closeAndFreeResources() {
+        transitionTo(STATE_CLOSED);
+        if (!ssl.isClosed()) {
+            ssl.close();
+            networkBio.close();
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            transitionTo(STATE_CLOSED);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    @Override
+    public String chooseServerAlias(X509KeyManager keyManager, String keyType) {
+        if (keyManager instanceof X509ExtendedKeyManager) {
+            X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) keyManager;
+            return ekm.chooseEngineServerAlias(keyType, null, this);
+        } else {
+            return keyManager.chooseServerAlias(keyType, null, null);
+        }
+    }
+
+    @Override
+    public String chooseClientAlias(
+            X509KeyManager keyManager, X500Principal[] issuers, String[] keyTypes) {
+        if (keyManager instanceof X509ExtendedKeyManager) {
+            X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) keyManager;
+            return ekm.chooseEngineClientAlias(keyTypes, issuers, this);
+        } else {
+            return keyManager.chooseClientAlias(keyTypes, issuers, null);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public String chooseServerPSKIdentityHint(PSKKeyManager keyManager) {
+        return keyManager.chooseServerKeyIdentityHint(this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) {
+        return keyManager.chooseClientKeyIdentity(identityHint, this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) {
+        return keyManager.getKey(identityHint, identity, this);
+    }
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param useSessionTickets True to enable session tickets
+     */
+    @Override
+    void setUseSessionTickets(boolean useSessionTickets) {
+        sslParameters.setUseSessionTickets(useSessionTickets);
+    }
+
+    @Override
+    String[] getApplicationProtocols() {
+        return sslParameters.getApplicationProtocols();
+    }
+
+    @Override
+    void setApplicationProtocols(String[] protocols) {
+        sslParameters.setApplicationProtocols(protocols);
+    }
+
+    @Override
+    void setApplicationProtocolSelector(ApplicationProtocolSelector selector) {
+        setApplicationProtocolSelector(
+                selector == null ? null : new ApplicationProtocolSelectorAdapter(this, selector));
+    }
+
+    @Override
+    byte[] getTlsUnique() {
+        return ssl.getTlsUnique();
+    }
+
+    @Override
+    byte[] exportKeyingMaterial(String label, byte[] context, int length) throws SSLException {
+        synchronized (ssl) {
+            if (state < STATE_HANDSHAKE_COMPLETED || state == STATE_CLOSED) {
+                return null;
+            }
+        }
+        return ssl.exportKeyingMaterial(label, context, length);
+    }
+
+    void setApplicationProtocolSelector(ApplicationProtocolSelectorAdapter adapter) {
+        sslParameters.setApplicationProtocolSelector(adapter);
+    }
+
+    @Override
+    public String getApplicationProtocol() {
+        return SSLUtils.toProtocolString(ssl.getApplicationProtocol());
+    }
+
+    @Override
+    public String getHandshakeApplicationProtocol() {
+        synchronized (ssl) {
+            return state == STATE_HANDSHAKE_STARTED ? getApplicationProtocol() : null;
+        }
+    }
+
+    private ByteBuffer[] singleSrcBuffer(ByteBuffer src) {
+        singleSrcBuffer[0] = src;
+        return singleSrcBuffer;
+    }
+
+    private void resetSingleSrcBuffer() {
+        singleSrcBuffer[0] = null;
+    }
+
+    private ByteBuffer[] singleDstBuffer(ByteBuffer src) {
+        singleDstBuffer[0] = src;
+        return singleDstBuffer;
+    }
+
+    private void resetSingleDstBuffer() {
+        singleDstBuffer[0] = null;
+    }
+
+    private ClientSessionContext clientSessionContext() {
+        return sslParameters.getClientSessionContext();
+    }
+
+    private AbstractSessionContext sessionContext() {
+        return sslParameters.getSessionContext();
+    }
+
+    private void transitionTo(int newState) {
+        switch (newState) {
+            case STATE_HANDSHAKE_STARTED: {
+                handshakeFinished = false;
+                activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+                break;
+            }
+            case STATE_CLOSED: {
+                if (!ssl.isClosed() && state >= STATE_HANDSHAKE_STARTED && state < STATE_CLOSED) {
+                    closedSession = new SessionSnapshot(activeSession);
+                }
+                break;
+            }
+            default: {
+                break;
+            }
+        }
+
+        // Update the state
+        this.state = newState;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngineSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngineSocket.java
new file mode 100644
index 0000000..96489f1
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptEngineSocket.java
@@ -0,0 +1,901 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2016 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 com.android.org.conscrypt;
+
+import static javax.net.ssl.SSLEngineResult.Status.OK;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_COMPLETED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_STARTED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_NEW;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_READY;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_READY_HANDSHAKE_CUT_THROUGH;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.security.PrivateKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedTrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Implements crypto handling by delegating to {@link ConscryptEngine}.
+ */
+class ConscryptEngineSocket extends OpenSSLSocketImpl {
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
+
+    private final ConscryptEngine engine;
+    private final Object stateLock = new Object();
+    private final Object handshakeLock = new Object();
+
+    private SSLOutputStream out;
+    private SSLInputStream in;
+
+    private BufferAllocator bufferAllocator = ConscryptEngine.getDefaultBufferAllocator();
+
+    // @GuardedBy("stateLock");
+    private int state = STATE_NEW;
+
+    // The constructors should not be called except from the Platform class, because we may
+    // want to construct a subclass instead.
+    ConscryptEngineSocket(SSLParametersImpl sslParameters) throws IOException {
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(String hostname, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(hostname, port);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(InetAddress address, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(address, port);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(String hostname, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(address, port, clientAddress, clientPort);
+        engine = newEngine(sslParameters, this);
+    }
+
+    ConscryptEngineSocket(Socket socket, String hostname, int port, boolean autoClose,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(socket, hostname, port, autoClose);
+        engine = newEngine(sslParameters, this);
+    }
+
+    private static ConscryptEngine newEngine(
+            SSLParametersImpl sslParameters, final ConscryptEngineSocket socket) {
+        SSLParametersImpl modifiedParams;
+        if (Platform.supportsX509ExtendedTrustManager()) {
+            modifiedParams = sslParameters.cloneWithTrustManager(
+                    getDelegatingTrustManager(sslParameters.getX509TrustManager(), socket));
+        } else {
+            modifiedParams = sslParameters;
+        }
+        ConscryptEngine engine = new ConscryptEngine(modifiedParams, socket.peerInfoProvider());
+
+        // When the handshake completes, notify any listeners.
+        engine.setHandshakeListener(new HandshakeListener() {
+            /**
+             * Protected by {@code stateLock}
+             */
+            @Override
+            public void onHandshakeFinished() {
+                // Just call the outer class method.
+                socket.onHandshakeFinished();
+            }
+        });
+
+        // Transition the engine state to MODE_SET
+        engine.setUseClientMode(sslParameters.getUseClientMode());
+        return engine;
+    }
+
+    // Returns a trust manager that delegates to the given trust manager, but maps SSLEngine
+    // references to the given ConscryptEngineSocket.  Our internal engine will call
+    // the SSLEngine-receiving methods, but our callers expect the SSLSocket-receiving
+    // methods to get called.
+    private static X509TrustManager getDelegatingTrustManager(
+            final X509TrustManager delegate, final ConscryptEngineSocket socket) {
+        if (delegate instanceof X509ExtendedTrustManager) {
+            final X509ExtendedTrustManager extendedDelegate = (X509ExtendedTrustManager) delegate;
+            return new X509ExtendedTrustManager() {
+                @Override
+                public void checkClientTrusted(X509Certificate[] x509Certificates, String s,
+                        Socket socket) throws CertificateException {
+                    throw new AssertionError("Should not be called");
+                }
+                @Override
+                public void checkServerTrusted(X509Certificate[] x509Certificates, String s,
+                        Socket socket) throws CertificateException {
+                    throw new AssertionError("Should not be called");
+                }
+                @Override
+                public void checkClientTrusted(X509Certificate[] x509Certificates, String s,
+                        SSLEngine sslEngine) throws CertificateException {
+                    extendedDelegate.checkClientTrusted(x509Certificates, s, socket);
+                }
+                @Override
+                public void checkServerTrusted(X509Certificate[] x509Certificates, String s,
+                        SSLEngine sslEngine) throws CertificateException {
+                    extendedDelegate.checkServerTrusted(x509Certificates, s, socket);
+                }
+                @Override
+                public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
+                        throws CertificateException {
+                    extendedDelegate.checkClientTrusted(x509Certificates, s);
+                }
+                @Override
+                public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
+                        throws CertificateException {
+                    extendedDelegate.checkServerTrusted(x509Certificates, s);
+                }
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return extendedDelegate.getAcceptedIssuers();
+                }
+            };
+        }
+        return delegate;
+    }
+
+    @Override
+    public final SSLParameters getSSLParameters() {
+        return engine.getSSLParameters();
+    }
+
+    @Override
+    public final void setSSLParameters(SSLParameters sslParameters) {
+        engine.setSSLParameters(sslParameters);
+    }
+
+    @Override
+    public final void startHandshake() throws IOException {
+        checkOpen();
+
+        try {
+            synchronized (handshakeLock) {
+                // Only lock stateLock when we begin the handshake. This is done so that we don't
+                // hold the stateLock when we invoke the handshake completion listeners.
+                synchronized (stateLock) {
+                    // Initialize the handshake if we haven't already.
+                    if (state == STATE_NEW) {
+                        state = STATE_HANDSHAKE_STARTED;
+                        engine.beginHandshake();
+                        in = new SSLInputStream();
+                        out = new SSLOutputStream();
+                    } else {
+                        // We've either started the handshake already or have been closed.
+                        // Do nothing in both cases.
+                        //
+                        // NOTE: BoringSSL does not support initiating renegotiation, so we always
+                        // ignore addition handshake calls.
+                        return;
+                    }
+                }
+
+                doHandshake();
+            }
+        } catch (SSLException e) {
+            close();
+            throw e;
+        } catch (IOException e) {
+            close();
+            throw e;
+        } catch (Exception e) {
+            close();
+            // Convert anything else to a handshake exception.
+            throw SSLUtils.toSSLHandshakeException(e);
+        }
+    }
+
+    private void doHandshake() throws IOException {
+        try {
+            boolean finished = false;
+            while (!finished) {
+                switch (engine.getHandshakeStatus()) {
+                    case NEED_UNWRAP:
+                        if (in.processDataFromSocket(EmptyArray.BYTE, 0, 0) < 0) {
+                            // Can't complete the handshake due to EOF.
+                            throw SSLUtils.toSSLHandshakeException(new EOFException());
+                        }
+                        break;
+                    case NEED_WRAP: {
+                        out.writeInternal(EMPTY_BUFFER);
+                        // Always flush handshake frames immediately.
+                        out.flushInternal();
+                        break;
+                    }
+                    case NEED_TASK: {
+                        // Should never get here, since our engine never provides tasks.
+                        throw new IllegalStateException("Engine tasks are unsupported");
+                    }
+                    case NOT_HANDSHAKING:
+                    case FINISHED: {
+                        // Handshake is complete.
+                        finished = true;
+                        break;
+                    }
+                    default: {
+                        throw new IllegalStateException(
+                            "Unknown handshake status: " + engine.getHandshakeStatus());
+                    }
+                }
+            }
+        } catch (SSLException e) {
+            drainOutgoingQueue();
+            close();
+            throw e;
+        } catch (IOException e) {
+            close();
+            throw e;
+        } catch (Exception e) {
+            close();
+            // Convert anything else to a handshake exception.
+            throw SSLUtils.toSSLHandshakeException(e);
+        }
+    }
+
+    @Override
+    public final InputStream getInputStream() throws IOException {
+        checkOpen();
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the input stream but
+        // all reads on it will throw.
+        waitForHandshake();
+        return in;
+    }
+
+    @Override
+    public final OutputStream getOutputStream() throws IOException {
+        checkOpen();
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the input stream but
+        // all reads on it will throw.
+        waitForHandshake();
+
+        return out;
+    }
+
+    @Override
+    public final SSLSession getHandshakeSession() {
+        return engine.handshakeSession();
+    }
+
+    @Override
+    public final SSLSession getSession() {
+        if (isConnected()) {
+            try {
+                waitForHandshake();
+            } catch (IOException e) {
+                // Fall through
+            }
+        }
+        return engine.getSession();
+    }
+
+    @Override
+    final SSLSession getActiveSession() {
+        return engine.getSession();
+    }
+
+    @Override
+    public final boolean getEnableSessionCreation() {
+        return engine.getEnableSessionCreation();
+    }
+
+    @Override
+    public final void setEnableSessionCreation(boolean flag) {
+        engine.setEnableSessionCreation(flag);
+    }
+
+    @Override
+    public final String[] getSupportedCipherSuites() {
+        return engine.getSupportedCipherSuites();
+    }
+
+    @Override
+    public final String[] getEnabledCipherSuites() {
+        return engine.getEnabledCipherSuites();
+    }
+
+    @Override
+    public final void setEnabledCipherSuites(String[] suites) {
+        engine.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public final String[] getSupportedProtocols() {
+        return engine.getSupportedProtocols();
+    }
+
+    @Override
+    public final String[] getEnabledProtocols() {
+        return engine.getEnabledProtocols();
+    }
+
+    @Override
+    public final void setEnabledProtocols(String[] protocols) {
+        engine.setEnabledProtocols(protocols);
+    }
+
+    /**
+     * This method enables Server Name Indication.  If the hostname is not a valid SNI hostname,
+     * the SNI extension will be omitted from the handshake.
+     *
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    @Override
+    public final void setHostname(String hostname) {
+        engine.setHostname(hostname);
+        super.setHostname(hostname);
+    }
+
+    @Override
+    public final void setUseSessionTickets(boolean useSessionTickets) {
+        engine.setUseSessionTickets(useSessionTickets);
+    }
+
+    @Override
+    public final void setChannelIdEnabled(boolean enabled) {
+        engine.setChannelIdEnabled(enabled);
+    }
+
+    @Override
+    public final byte[] getChannelId() throws SSLException {
+        return engine.getChannelId();
+    }
+
+    @Override
+    public final void setChannelIdPrivateKey(PrivateKey privateKey) {
+        engine.setChannelIdPrivateKey(privateKey);
+    }
+
+    @Override
+    byte[] getTlsUnique() {
+        return engine.getTlsUnique();
+    }
+
+    @Override
+    byte[] exportKeyingMaterial(String label, byte[] context, int length) throws SSLException {
+        return engine.exportKeyingMaterial(label, context, length);
+    }
+
+    @Override
+    public final boolean getUseClientMode() {
+        return engine.getUseClientMode();
+    }
+
+    @Override
+    public final void setUseClientMode(boolean mode) {
+        engine.setUseClientMode(mode);
+    }
+
+    @Override
+    public final boolean getWantClientAuth() {
+        return engine.getWantClientAuth();
+    }
+
+    @Override
+    public final boolean getNeedClientAuth() {
+        return engine.getNeedClientAuth();
+    }
+
+    @Override
+    public final void setNeedClientAuth(boolean need) {
+        engine.setNeedClientAuth(need);
+    }
+
+    @Override
+    public final void setWantClientAuth(boolean want) {
+        engine.setWantClientAuth(want);
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public final void close() throws IOException {
+        // TODO: Close SSL sockets using a background thread so they close gracefully.
+
+        if (stateLock == null) {
+            // close() has been called before we've initialized the socket, so just
+            // return.
+            return;
+        }
+
+        synchronized (stateLock) {
+            if (state == STATE_CLOSED) {
+                // close() has already been called, so do nothing and return.
+                return;
+            }
+
+            state = STATE_CLOSED;
+
+            stateLock.notifyAll();
+        }
+
+        try {
+            // Close the underlying socket.
+            super.close();
+        } finally {
+            // Close the engine.
+            engine.closeInbound();
+            engine.closeOutbound();
+            
+            // Release any resources we're holding
+            if (in != null) {
+                in.release();
+            }
+        }
+    }
+
+    @Override
+    final void setApplicationProtocols(String[] protocols) {
+        engine.setApplicationProtocols(protocols);
+    }
+
+    @Override
+    final String[] getApplicationProtocols() {
+        return engine.getApplicationProtocols();
+    }
+
+    @Override
+    public final String getApplicationProtocol() {
+        return engine.getApplicationProtocol();
+    }
+
+    @Override
+    public final String getHandshakeApplicationProtocol() {
+        return engine.getHandshakeApplicationProtocol();
+    }
+
+    @Override
+    public final void setApplicationProtocolSelector(ApplicationProtocolSelector selector) {
+        setApplicationProtocolSelector(
+                selector == null ? null : new ApplicationProtocolSelectorAdapter(this, selector));
+    }
+
+    @Override
+    final void setApplicationProtocolSelector(ApplicationProtocolSelectorAdapter selector) {
+        engine.setApplicationProtocolSelector(selector);
+    }
+
+    void setBufferAllocator(BufferAllocator bufferAllocator) {
+        engine.setBufferAllocator(bufferAllocator);
+        this.bufferAllocator = bufferAllocator;
+    }
+
+    private void onHandshakeFinished() {
+        boolean notify = false;
+        synchronized (stateLock) {
+            if (state != STATE_CLOSED) {
+                if (state == STATE_HANDSHAKE_STARTED) {
+                    state = STATE_READY_HANDSHAKE_CUT_THROUGH;
+                } else if (state == STATE_HANDSHAKE_COMPLETED) {
+                    state = STATE_READY;
+                }
+
+                // Unblock threads that are waiting for our state to transition
+                // into STATE_READY or STATE_READY_HANDSHAKE_CUT_THROUGH.
+                stateLock.notifyAll();
+                notify = true;
+            }
+        }
+
+        if (notify) {
+            notifyHandshakeCompletedListeners();
+        }
+    }
+
+    /**
+     * Waits for the handshake to complete.
+     */
+    private void waitForHandshake() throws IOException {
+        startHandshake();
+
+        synchronized (stateLock) {
+            while (state != STATE_READY && state != STATE_READY_HANDSHAKE_CUT_THROUGH
+                    && state != STATE_CLOSED) {
+                try {
+                    stateLock.wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new IOException("Interrupted waiting for handshake", e);
+                }
+            }
+
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed");
+            }
+        }
+    }
+
+    private void drainOutgoingQueue() {
+        try {
+            while (engine.pendingOutboundEncryptedBytes() > 0) {
+                out.writeInternal(EMPTY_BUFFER);
+                // Always flush handshake frames immediately.
+                out.flushInternal();
+            }
+        } catch (IOException e) {
+            // Ignore
+        }
+    }
+
+    private OutputStream getUnderlyingOutputStream() throws IOException {
+        return super.getOutputStream();
+    }
+
+    private InputStream getUnderlyingInputStream() throws IOException {
+        return super.getInputStream();
+    }
+
+    /**
+     * Wrap bytes written to the underlying socket.
+     */
+    private final class SSLOutputStream extends OutputStream {
+        private final Object writeLock = new Object();
+        private final ByteBuffer target;
+        private final int targetArrayOffset;
+        private OutputStream socketOutputStream;
+
+        SSLOutputStream() {
+            target = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
+            targetArrayOffset = target.arrayOffset();
+        }
+
+        @Override
+        public void close() throws IOException {
+            ConscryptEngineSocket.this.close();
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                write(new byte[] {(byte) b});
+            }
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                writeInternal(ByteBuffer.wrap(b));
+            }
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                writeInternal(ByteBuffer.wrap(b, off, len));
+            }
+        }
+
+        private void writeInternal(ByteBuffer buffer) throws IOException {
+            Platform.blockGuardOnNetwork();
+            checkOpen();
+            init();
+
+            // Need to loop through at least once to enable handshaking where no application
+            // bytes are
+            // processed.
+            int len = buffer.remaining();
+            SSLEngineResult engineResult;
+            do {
+                target.clear();
+                engineResult = engine.wrap(buffer, target);
+                if (engineResult.getStatus() != OK) {
+                    throw new SSLException("Unexpected engine result " + engineResult.getStatus());
+                }
+                if (target.position() != engineResult.bytesProduced()) {
+                    throw new SSLException("Engine bytesProduced " + engineResult.bytesProduced()
+                            + " does not match bytes written " + target.position());
+                }
+                len -= engineResult.bytesConsumed();
+                if (len != buffer.remaining()) {
+                    throw new SSLException("Engine did not read the correct number of bytes");
+                }
+
+                target.flip();
+
+                // Write the data to the socket.
+                writeToSocket();
+            } while (len > 0);
+        }
+
+        @Override
+        public void flush() throws IOException {
+            startHandshake();
+            synchronized (writeLock) {
+                flushInternal();
+            }
+        }
+
+        private void flushInternal() throws IOException {
+            checkOpen();
+            init();
+            socketOutputStream.flush();
+        }
+
+        private void init() throws IOException {
+            if (socketOutputStream == null) {
+                socketOutputStream = getUnderlyingOutputStream();
+            }
+        }
+
+        private void writeToSocket() throws IOException {
+            // Write the data to the socket.
+            socketOutputStream.write(target.array(), targetArrayOffset, target.limit());
+        }
+    }
+
+    /**
+     * Unwrap bytes read from the underlying socket.
+     */
+    private final class SSLInputStream extends InputStream {
+        private final Object readLock = new Object();
+        private final byte[] singleByte = new byte[1];
+        private final ByteBuffer fromEngine;
+        private final ByteBuffer fromSocket;
+        private final int fromSocketArrayOffset;
+        private final AllocatedBuffer allocatedBuffer;
+        private InputStream socketInputStream;
+
+        SSLInputStream() {
+            if (bufferAllocator != null) {
+                allocatedBuffer = bufferAllocator.allocateDirectBuffer(
+                        engine.getSession().getApplicationBufferSize());
+                fromEngine = allocatedBuffer.nioBuffer();
+            } else {
+                allocatedBuffer = null;
+                fromEngine = ByteBuffer.allocateDirect(engine.getSession().getApplicationBufferSize());
+            }
+            // Initially fromEngine.remaining() == 0.
+            fromEngine.flip();
+            fromSocket = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
+            fromSocketArrayOffset = fromSocket.arrayOffset();
+        }
+
+        @Override
+        public void close() throws IOException {
+            ConscryptEngineSocket.this.close();
+        }
+
+        void release() {
+            synchronized (readLock) {
+                if (allocatedBuffer != null) {
+                    allocatedBuffer.release();
+                }
+            }
+        }
+
+        @Override
+        public int read() throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                // Handle returning of -1 if EOF is reached.
+                int count = read(singleByte, 0, 1);
+                if (count == -1) {
+                    // Handle EOF.
+                    return -1;
+                }
+                if (count != 1) {
+                    throw new SSLException("read incorrect number of bytes " + count);
+                }
+                return (int) singleByte[0];
+            }
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                return read(b, 0, b.length);
+            }
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                return readUntilDataAvailable(b, off, len);
+            }
+        }
+
+        @Override
+        public int available() throws IOException {
+            startHandshake();
+            synchronized (readLock) {
+                init();
+                return fromEngine.remaining()
+                        + (fromSocket.hasRemaining() || socketInputStream.available() > 0 ? 1 : 0);
+            }
+        }
+
+        private boolean isHandshaking(HandshakeStatus status) {
+            switch(status) {
+                case NEED_TASK:
+                case NEED_WRAP:
+                case NEED_UNWRAP:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+        private int readUntilDataAvailable(byte[] b, int off, int len) throws IOException {
+            int count;
+            do {
+                count = processDataFromSocket(b, off, len);
+            } while (count == 0);
+            return count;
+        }
+
+        // Returns any decrypted data from the engine.  If no data is currently present in the
+        // engine's output buffer, reads from the input socket until the engine has processed
+        // at least one TLS record, then returns any data in the output buffer or 0 if no
+        // data is available.  This is used both during handshaking (in which case, the records
+        // will produce no data and this method will return 0) and by the InputStream read()
+        // methods that expect records to produce application data.
+        private int processDataFromSocket(byte[] b, int off, int len) throws IOException {
+            Platform.blockGuardOnNetwork();
+            checkOpen();
+
+            // Make sure the input stream has been created.
+            init();
+
+            for (;;) {
+                // Serve any remaining data from the engine first.
+                if (fromEngine.remaining() > 0) {
+                    int readFromEngine = Math.min(fromEngine.remaining(), len);
+                    fromEngine.get(b, off, readFromEngine);
+                    return readFromEngine;
+                }
+
+                // Try to unwrap any data already in the socket buffer.
+                boolean needMoreDataFromSocket = true;
+
+                // Unwrap the unencrypted bytes into the engine buffer.
+                fromSocket.flip();
+                fromEngine.clear();
+
+                boolean engineHandshaking = isHandshaking(engine.getHandshakeStatus());
+                SSLEngineResult engineResult = engine.unwrap(fromSocket, fromEngine);
+
+                // Shift any remaining data to the beginning of the buffer so that
+                // we can accommodate the next full packet. After this is called,
+                // limit will be restored to capacity and position will point just
+                // past the end of the data.
+                fromSocket.compact();
+                fromEngine.flip();
+
+                switch (engineResult.getStatus()) {
+                    case BUFFER_UNDERFLOW: {
+                        if (engineResult.bytesProduced() == 0) {
+                            // Need to read more data from the socket.
+                            break;
+                        }
+                        // Also serve the data that was produced.
+                        needMoreDataFromSocket = false;
+                        break;
+                    }
+                    case OK: {
+                        // We processed the entire packet successfully...
+
+                        if (!engineHandshaking && isHandshaking(engineResult.getHandshakeStatus())
+                            && isHandshakeFinished()) {
+                            // The received packet is the beginning of a renegotiation handshake.
+                            // Perform another handshake.
+                            renegotiate();
+                            return 0;
+                        }
+
+                        needMoreDataFromSocket = false;
+                        break;
+                    }
+                    case CLOSED: {
+                        // EOF
+                        return -1;
+                    }
+                    default: {
+                        // Anything else is an error.
+                        throw new SSLException(
+                                "Unexpected engine result " + engineResult.getStatus());
+                    }
+                }
+
+                if (!needMoreDataFromSocket && engineResult.bytesProduced() == 0) {
+                    // Read successfully, but produced no data. Possibly part of a
+                    // handshake.
+                    return 0;
+                }
+
+                // Read more data from the socket.
+                if (needMoreDataFromSocket && readFromSocket() == -1) {
+                    // Failed to read the next encrypted packet before reaching EOF.
+                    return -1;
+                }
+
+                // Continue the loop and return the data from the engine buffer.
+            }
+        }
+
+        private boolean isHandshakeFinished() {
+            synchronized (stateLock) {
+                return state >= STATE_READY_HANDSHAKE_CUT_THROUGH;
+            }
+        }
+
+        /**
+         * Processes a renegotiation received from the remote peer.
+         */
+        private void renegotiate() throws IOException {
+            synchronized (handshakeLock) {
+                doHandshake();
+            }
+        }
+
+        private void init() throws IOException {
+            if (socketInputStream == null) {
+                socketInputStream = getUnderlyingInputStream();
+            }
+        }
+
+        private int readFromSocket() throws IOException {
+            try {
+                // Read directly to the underlying array and increment the buffer position if
+                // appropriate.
+                int pos = fromSocket.position();
+                int lim = fromSocket.limit();
+                int read = socketInputStream.read(
+                    fromSocket.array(), fromSocketArrayOffset + pos, lim - pos);
+
+                if (read > 0) {
+                    fromSocket.position(pos + read);
+                }
+                return read;
+            } catch (EOFException e) {
+                return -1;
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java
new file mode 100644
index 0000000..05af7c1
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptFileDescriptorSocket.java
@@ -0,0 +1,1180 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_CLOSED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_COMPLETED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_HANDSHAKE_STARTED;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_NEW;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_READY;
+import static com.android.org.conscrypt.SSLUtils.EngineStates.STATE_READY_HANDSHAKE_CUT_THROUGH;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECKey;
+import java.security.spec.ECParameterSpec;
+import javax.crypto.SecretKey;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLProtocolException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.ExternalSession.Provider;
+import com.android.org.conscrypt.NativeRef.SSL_SESSION;
+
+/**
+ * Implementation of the class OpenSSLSocketImpl based on OpenSSL.
+ * <p>
+ * Extensions to SSLSocket include:
+ * <ul>
+ * <li>handshake timeout
+ * <li>session tickets
+ * <li>Server Name Indication
+ * </ul>
+ */
+class ConscryptFileDescriptorSocket extends OpenSSLSocketImpl
+        implements NativeCrypto.SSLHandshakeCallbacks, SSLParametersImpl.AliasChooser,
+                   SSLParametersImpl.PSKCallbacks {
+    private static final boolean DBG_STATE = false;
+
+    // @GuardedBy("ssl");
+    private int state = STATE_NEW;
+
+    /**
+     * Wrapper around the underlying SSL object.
+     */
+    private final NativeSsl ssl;
+
+    /**
+     * Protected by synchronizing on ssl. Starts as null, set by
+     * getInputStream.
+     */
+    // @GuardedBy("ssl");
+    private SSLInputStream is;
+
+    /**
+     * Protected by synchronizing on ssl. Starts as null, set by
+     * getInputStream.
+     */
+    // @GuardedBy("ssl");
+    private SSLOutputStream os;
+
+    private final SSLParametersImpl sslParameters;
+
+    /*
+     * A CloseGuard object on Android. On other platforms, this is nothing.
+     */
+    private final Object guard = Platform.closeGuardGet();
+
+    /**
+     * Private key for the TLS Channel ID extension. This field is client-side
+     * only. Set during startHandshake.
+     */
+    private OpenSSLKey channelIdPrivateKey;
+
+    private final ActiveSession activeSession;
+    /**
+     * A snapshot of the active session when the engine was closed.
+     */
+    private SessionSnapshot closedSession;
+    /**
+     * The session object exposed externally from this class.
+     */
+    private final SSLSession externalSession =
+        Platform.wrapSSLSession(new ExternalSession(new Provider() {
+            @Override
+            public ConscryptSession provideSession() {
+                return ConscryptFileDescriptorSocket.this.provideSession();
+            }
+        }));
+
+    private int writeTimeoutMilliseconds = 0;
+    private int handshakeTimeoutMilliseconds = -1; // -1 = same as timeout; 0 = infinite
+
+    // The constructors should not be called except from the Platform class, because we may
+    // want to construct a subclass instead.
+    ConscryptFileDescriptorSocket(SSLParametersImpl sslParameters) throws IOException {
+        this.sslParameters = sslParameters;
+        this.ssl = newSsl(sslParameters, this);
+        activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+    }
+
+    ConscryptFileDescriptorSocket(String hostname, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(hostname, port);
+        this.sslParameters = sslParameters;
+        this.ssl = newSsl(sslParameters, this);
+        activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+    }
+
+    ConscryptFileDescriptorSocket(InetAddress address, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(address, port);
+        this.sslParameters = sslParameters;
+        this.ssl = newSsl(sslParameters, this);
+        activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+    }
+
+    ConscryptFileDescriptorSocket(String hostname, int port, InetAddress clientAddress,
+            int clientPort, SSLParametersImpl sslParameters) throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+        this.sslParameters = sslParameters;
+        this.ssl = newSsl(sslParameters, this);
+        activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+    }
+
+    ConscryptFileDescriptorSocket(InetAddress address, int port, InetAddress clientAddress,
+            int clientPort, SSLParametersImpl sslParameters) throws IOException {
+        super(address, port, clientAddress, clientPort);
+        this.sslParameters = sslParameters;
+        this.ssl = newSsl(sslParameters, this);
+        activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+    }
+
+    ConscryptFileDescriptorSocket(Socket socket, String hostname, int port, boolean autoClose,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(socket, hostname, port, autoClose);
+        this.sslParameters = sslParameters;
+        this.ssl = newSsl(sslParameters, this);
+        activeSession = new ActiveSession(ssl, sslParameters.getSessionContext());
+    }
+
+    private static NativeSsl newSsl(SSLParametersImpl sslParameters,
+            ConscryptFileDescriptorSocket engine) throws SSLException {
+        return NativeSsl.newInstance(sslParameters, engine, engine, engine);
+    }
+
+    /**
+     * Starts a TLS/SSL handshake on this connection using some native methods
+     * from the OpenSSL library. It can negotiate new encryption keys, change
+     * cipher suites, or initiate a new session. The certificate chain is
+     * verified if the correspondent property in java.Security is set. All
+     * listeners are notified at the end of the TLS/SSL handshake.
+     */
+    @Override
+    public final void startHandshake() throws IOException {
+        checkOpen();
+        synchronized (ssl) {
+            if (state == STATE_NEW) {
+                transitionTo(STATE_HANDSHAKE_STARTED);
+            } else {
+                // We've either started the handshake already or have been closed.
+                // Do nothing in both cases.
+                return;
+            }
+        }
+
+        boolean releaseResources = true;
+        try {
+            Platform.closeGuardOpen(guard, "close");
+
+            // Prepare the SSL object for the handshake.
+            ssl.initialize(getHostname(), channelIdPrivateKey);
+
+            // For clients, offer to resume a previously cached session to avoid the
+            // full TLS handshake.
+            if (getUseClientMode()) {
+                NativeSslSession cachedSession = clientSessionContext().getCachedSession(
+                        getHostnameOrIP(), getPort(), sslParameters);
+                if (cachedSession != null) {
+                    cachedSession.offerToResume(ssl);
+                }
+            }
+
+            // Temporarily use a different timeout for the handshake process
+            int savedReadTimeoutMilliseconds = getSoTimeout();
+            int savedWriteTimeoutMilliseconds = getSoWriteTimeout();
+            if (handshakeTimeoutMilliseconds >= 0) {
+                setSoTimeout(handshakeTimeoutMilliseconds);
+                setSoWriteTimeout(handshakeTimeoutMilliseconds);
+            }
+
+            synchronized (ssl) {
+                if (state == STATE_CLOSED) {
+                    return;
+                }
+            }
+
+            try {
+                ssl.doHandshake(Platform.getFileDescriptor(socket), getSoTimeout());
+
+                // Update the session from the current state of the SSL object.
+                activeSession.onPeerCertificateAvailable(getHostnameOrIP(), getPort());
+            } catch (CertificateException e) {
+                SSLHandshakeException wrapper = new SSLHandshakeException(e.getMessage());
+                wrapper.initCause(e);
+                throw wrapper;
+            } catch (SSLException e) {
+                // Swallow this exception if it's thrown as the result of an interruption.
+                //
+                // TODO: SSL_read and SSL_write return -1 when interrupted, but SSL_do_handshake
+                // will throw the last sslError that it saw before sslSelect, usually SSL_WANT_READ
+                // (or WANT_WRITE). Catching that exception here doesn't seem much worse than
+                // changing the native code to return a "special" native pointer value when that
+                // happens.
+                synchronized (ssl) {
+                    if (state == STATE_CLOSED) {
+                        return;
+                    }
+                }
+
+                // Write CCS errors to EventLog
+                String message = e.getMessage();
+                // Must match error string of SSL_R_UNEXPECTED_CCS
+                if (message.contains("unexpected CCS")) {
+                    String logMessage =
+                            String.format("ssl_unexpected_ccs: host=%s", getHostnameOrIP());
+                    Platform.logEvent(logMessage);
+                }
+
+                throw e;
+            }
+
+            synchronized (ssl) {
+                if (state == STATE_CLOSED) {
+                    return;
+                }
+            }
+
+            // Restore the original timeout now that the handshake is complete
+            if (handshakeTimeoutMilliseconds >= 0) {
+                setSoTimeout(savedReadTimeoutMilliseconds);
+                setSoWriteTimeout(savedWriteTimeoutMilliseconds);
+            }
+
+            synchronized (ssl) {
+                releaseResources = (state == STATE_CLOSED);
+
+                if (state == STATE_HANDSHAKE_STARTED) {
+                    transitionTo(STATE_READY_HANDSHAKE_CUT_THROUGH);
+                } else {
+                    transitionTo(STATE_READY);
+                }
+
+                if (!releaseResources) {
+                    // Unblock threads that are waiting for our state to transition
+                    // into STATE_READY or STATE_READY_HANDSHAKE_CUT_THROUGH.
+                    ssl.notifyAll();
+                }
+            }
+        } catch (SSLProtocolException e) {
+            throw(SSLHandshakeException) new SSLHandshakeException("Handshake failed").initCause(e);
+        } finally {
+            // on exceptional exit, treat the socket as closed
+            if (releaseResources) {
+                synchronized (ssl) {
+                    // Mark the socket as closed since we might have reached this as
+                    // a result on an exception thrown by the handshake process.
+                    //
+                    // The state will already be set to closed if we reach this as a result of
+                    // an early return or an interruption due to a concurrent call to close().
+                    transitionTo(STATE_CLOSED);
+                    ssl.notifyAll();
+                }
+
+                try {
+                    shutdownAndFreeSslNative();
+                } catch (IOException ignored) {
+                    // Ignored.
+                }
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / client_cert_cb
+    public final void clientCertificateRequested(byte[] keyTypeBytes, int[] signatureAlgs,
+            byte[][] asn1DerEncodedPrincipals)
+            throws CertificateEncodingException, SSLException {
+        ssl.chooseClientCertificate(keyTypeBytes, signatureAlgs, asn1DerEncodedPrincipals);
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by native psk_client_callback
+    public final int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) {
+        return ssl.clientPSKKeyRequested(identityHint, identity, key);
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by native psk_server_callback
+    public final int serverPSKKeyRequested(String identityHint, String identity, byte[] key) {
+        return ssl.serverPSKKeyRequested(identityHint, identity, key);
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / info_callback
+    public final void onSSLStateChange(int type, int val) {
+        if (type != NativeConstants.SSL_CB_HANDSHAKE_DONE) {
+            // We only care about successful completion.
+            return;
+        }
+
+        // The handshake has completed successfully ...
+
+        // First, update the state.
+        synchronized (ssl) {
+            if (state == STATE_CLOSED) {
+                // Someone called "close" but the handshake hasn't been interrupted yet.
+                return;
+            }
+
+            // Now that we've fixed up our state, we can tell waiting threads that
+            // we're ready.
+            transitionTo(STATE_READY);
+        }
+
+        // Let listeners know we are finally done
+        notifyHandshakeCompletedListeners();
+
+        synchronized (ssl) {
+            // Notify all threads waiting for the handshake to complete.
+            ssl.notifyAll();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / new_session_callback
+    public final void onNewSessionEstablished(long sslSessionNativePtr) {
+        try {
+            // Increment the reference count to "take ownership" of the session resource.
+            NativeCrypto.SSL_SESSION_up_ref(sslSessionNativePtr);
+
+            // Create a native reference which will release the SSL_SESSION in its finalizer.
+            // This constructor will only throw if the native pointer passed in is NULL, which
+            // BoringSSL guarantees will not happen.
+            NativeRef.SSL_SESSION ref = new SSL_SESSION(sslSessionNativePtr);
+
+            NativeSslSession nativeSession = NativeSslSession.newInstance(ref, activeSession);
+
+            // Cache the newly established session.
+            AbstractSessionContext ctx = sessionContext();
+            ctx.cacheSession(nativeSession);
+        } catch (Exception ignored) {
+            // Ignore.
+        }
+    }
+
+    @Override
+    public final long serverSessionRequested(byte[] id) {
+        // TODO(nathanmittler): Implement server-side caching for TLS < 1.3
+        return 0;
+    }
+
+    @Override
+    public final void verifyCertificateChain(byte[][] certChain, String authMethod)
+            throws CertificateException {
+        try {
+            if (certChain == null || certChain.length == 0) {
+                throw new CertificateException("Peer sent no certificate");
+            }
+            X509Certificate[] peerCertChain = SSLUtils.decodeX509CertificateChain(certChain);
+
+            X509TrustManager x509tm = sslParameters.getX509TrustManager();
+            if (x509tm == null) {
+                throw new CertificateException("No X.509 TrustManager");
+            }
+            // Update the peer information on the session.
+            activeSession.onPeerCertificatesReceived(getHostnameOrIP(), getPort(), peerCertChain);
+
+            if (getUseClientMode()) {
+                Platform.checkServerTrusted(x509tm, peerCertChain, authMethod, this);
+            } else {
+                String authType = peerCertChain[0].getPublicKey().getAlgorithm();
+                Platform.checkClientTrusted(x509tm, peerCertChain, authType, this);
+            }
+        } catch (CertificateException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    @Override
+    public final InputStream getInputStream() throws IOException {
+        checkOpen();
+
+        InputStream returnVal;
+        synchronized (ssl) {
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed.");
+            }
+
+            if (is == null) {
+                is = new SSLInputStream();
+            }
+
+            returnVal = is;
+        }
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the input stream but
+        // all reads on it will throw.
+        waitForHandshake();
+        return returnVal;
+    }
+
+    @Override
+    public final OutputStream getOutputStream() throws IOException {
+        checkOpen();
+
+        OutputStream returnVal;
+        synchronized (ssl) {
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed.");
+            }
+
+            if (os == null) {
+                os = new SSLOutputStream();
+            }
+
+            returnVal = os;
+        }
+
+        // Block waiting for a handshake without a lock held. It's possible that the socket
+        // is closed at this point. If that happens, we'll still return the output stream but
+        // all writes on it will throw.
+        waitForHandshake();
+        return returnVal;
+    }
+
+    private void assertReadableOrWriteableState() {
+        if (state == STATE_READY || state == STATE_READY_HANDSHAKE_CUT_THROUGH) {
+            return;
+        }
+
+        throw new AssertionError("Invalid state: " + state);
+    }
+
+    private void waitForHandshake() throws IOException {
+        startHandshake();
+
+        synchronized (ssl) {
+            while (state != STATE_READY &&
+                    state != STATE_READY_HANDSHAKE_CUT_THROUGH &&
+                    state != STATE_CLOSED) {
+                try {
+                    ssl.wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new IOException("Interrupted waiting for handshake", e);
+                }
+            }
+
+            if (state == STATE_CLOSED) {
+                throw new SocketException("Socket is closed");
+            }
+        }
+    }
+
+    /**
+     * This inner class provides input data stream functionality
+     * for the OpenSSL native implementation. It is used to
+     * read data received via SSL protocol.
+     */
+    private class SSLInputStream extends InputStream {
+        /**
+         * OpenSSL only lets one thread read at a time, so this is used to
+         * make sure we serialize callers of SSL_read. Thread is already
+         * expected to have completed handshaking.
+         */
+        private final Object readLock = new Object();
+
+        SSLInputStream() {
+        }
+
+        /**
+         * Reads one byte. If there is no data in the underlying buffer,
+         * this operation can block until the data will be
+         * available.
+         */
+        @Override
+        public int read() throws IOException {
+            byte[] buffer = new byte[1];
+            int result = read(buffer, 0, 1);
+            return (result != -1) ? buffer[0] & 0xff : -1;
+        }
+
+        /**
+         * Method acts as described in spec for superclass.
+         * @see java.io.InputStream#read(byte[],int,int)
+         */
+        @Override
+        public int read(byte[] buf, int offset, int byteCount) throws IOException {
+            Platform.blockGuardOnNetwork();
+
+            checkOpen();
+            ArrayUtils.checkOffsetAndCount(buf.length, offset, byteCount);
+            if (byteCount == 0) {
+                return 0;
+            }
+
+            synchronized (readLock) {
+                synchronized (ssl) {
+                    if (state == STATE_CLOSED) {
+                        throw new SocketException("socket is closed");
+                    }
+
+                    if (DBG_STATE) {
+                        assertReadableOrWriteableState();
+                    }
+                }
+
+                int ret =  ssl.read(
+                        Platform.getFileDescriptor(socket), buf, offset, byteCount, getSoTimeout());
+                if (ret == -1) {
+                    synchronized (ssl) {
+                        if (state == STATE_CLOSED) {
+                            throw new SocketException("socket is closed");
+                        }
+                    }
+                }
+                return ret;
+            }
+        }
+
+        void awaitPendingOps() {
+            if (DBG_STATE) {
+                synchronized (ssl) {
+                    if (state != STATE_CLOSED) {
+                        throw new AssertionError("State is: " + state);
+                    }
+                }
+            }
+
+            synchronized (readLock) {}
+        }
+    }
+
+    /**
+     * This inner class provides output data stream functionality
+     * for the OpenSSL native implementation. It is used to
+     * write data according to the encryption parameters given in SSL context.
+     */
+    private class SSLOutputStream extends OutputStream {
+        /**
+         * OpenSSL only lets one thread write at a time, so this is used
+         * to make sure we serialize callers of SSL_write. Thread is
+         * already expected to have completed handshaking.
+         */
+        private final Object writeLock = new Object();
+
+        SSLOutputStream() {
+        }
+
+        /**
+         * Method acts as described in spec for superclass.
+         * @see java.io.OutputStream#write(int)
+         */
+        @Override
+        public void write(int oneByte) throws IOException {
+            byte[] buffer = new byte[1];
+            buffer[0] = (byte) (oneByte & 0xff);
+            write(buffer);
+        }
+
+        /**
+         * Method acts as described in spec for superclass.
+         * @see java.io.OutputStream#write(byte[],int,int)
+         */
+        @Override
+        public void write(byte[] buf, int offset, int byteCount) throws IOException {
+            Platform.blockGuardOnNetwork();
+            checkOpen();
+            ArrayUtils.checkOffsetAndCount(buf.length, offset, byteCount);
+            if (byteCount == 0) {
+                return;
+            }
+
+            synchronized (writeLock) {
+                synchronized (ssl) {
+                    if (state == STATE_CLOSED) {
+                        throw new SocketException("socket is closed");
+                    }
+
+                    if (DBG_STATE) {
+                        assertReadableOrWriteableState();
+                    }
+                }
+
+                ssl.write(Platform.getFileDescriptor(socket), buf, offset, byteCount,
+                        writeTimeoutMilliseconds);
+
+                synchronized (ssl) {
+                    if (state == STATE_CLOSED) {
+                        throw new SocketException("socket is closed");
+                    }
+                }
+            }
+        }
+
+        void awaitPendingOps() {
+            if (DBG_STATE) {
+                synchronized (ssl) {
+                    if (state != STATE_CLOSED) {
+                        throw new AssertionError("State is: " + state);
+                    }
+                }
+            }
+
+            synchronized (writeLock) {}
+        }
+    }
+
+    @Override
+    public final SSLSession getSession() {
+        return externalSession;
+    }
+
+    private ConscryptSession provideSession() {
+        boolean handshakeCompleted = false;
+        synchronized (ssl) {
+            if (state == STATE_CLOSED) {
+                return closedSession != null ? closedSession : SSLNullSession.getNullSession();
+            }
+
+            try {
+                handshakeCompleted = state >= STATE_READY;
+                if (!handshakeCompleted && isConnected()) {
+                    waitForHandshake();
+                    handshakeCompleted = true;
+                }
+            } catch (IOException e) {
+                // Fall through.
+            }
+        }
+
+        if (!handshakeCompleted) {
+            // return an invalid session with
+            // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
+            return SSLNullSession.getNullSession();
+        }
+
+        return activeSession;
+    }
+
+    private ConscryptSession provideHandshakeSession() {
+        synchronized (ssl) {
+            return state >= STATE_HANDSHAKE_STARTED && state < STATE_READY ? activeSession
+                : SSLNullSession.getNullSession();
+        }
+    }
+
+    @Override
+    final SSLSession getActiveSession() {
+        return activeSession;
+    }
+
+    @Override
+    public final SSLSession getHandshakeSession() {
+        synchronized (ssl) {
+            if (state >= STATE_HANDSHAKE_STARTED && state < STATE_READY) {
+                return Platform.wrapSSLSession(new ExternalSession(new Provider() {
+                    @Override
+                    public ConscryptSession provideSession() {
+                        return ConscryptFileDescriptorSocket.this.provideHandshakeSession();
+                    }
+                }));
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public final boolean getEnableSessionCreation() {
+        return sslParameters.getEnableSessionCreation();
+    }
+
+    @Override
+    public final void setEnableSessionCreation(boolean flag) {
+        sslParameters.setEnableSessionCreation(flag);
+    }
+
+    @Override
+    public final String[] getSupportedCipherSuites() {
+        return NativeCrypto.getSupportedCipherSuites();
+    }
+
+    @Override
+    public final String[] getEnabledCipherSuites() {
+        return sslParameters.getEnabledCipherSuites();
+    }
+
+    @Override
+    public final void setEnabledCipherSuites(String[] suites) {
+        sslParameters.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public final String[] getSupportedProtocols() {
+        return NativeCrypto.getSupportedProtocols();
+    }
+
+    @Override
+    public final String[] getEnabledProtocols() {
+        return sslParameters.getEnabledProtocols();
+    }
+
+    @Override
+    public final void setEnabledProtocols(String[] protocols) {
+        sslParameters.setEnabledProtocols(protocols);
+    }
+
+    /**
+     * This method enables session ticket support.
+     *
+     * @param useSessionTickets True to enable session tickets
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public final void setUseSessionTickets(boolean useSessionTickets) {
+        sslParameters.setUseSessionTickets(useSessionTickets);
+    }
+
+    /**
+     * This method enables Server Name Indication.  If the hostname is not a valid SNI hostname,
+     * the SNI extension will be omitted from the handshake.
+     *
+     * @param hostname the desired SNI hostname, or null to disable
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public final void setHostname(String hostname) {
+        sslParameters.setUseSni(hostname != null);
+        super.setHostname(hostname);
+    }
+
+    /**
+     * Enables/disables TLS Channel ID for this server socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has already
+     *         started.
+     */
+    @Override
+    public final void setChannelIdEnabled(boolean enabled) {
+        if (getUseClientMode()) {
+            throw new IllegalStateException("Client mode");
+        }
+
+        synchronized (ssl) {
+            if (state != STATE_NEW) {
+                throw new IllegalStateException(
+                        "Could not enable/disable Channel ID after the initial handshake has"
+                                + " begun.");
+            }
+        }
+        sslParameters.channelIdEnabled = enabled;
+    }
+
+    /**
+     * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
+     * handshake completes.
+     *
+     * @return channel ID or {@code null} if not available.
+     *
+     * @throws IllegalStateException if this is a client socket or if the handshake has not yet
+     *         completed.
+     * @throws SSLException if channel ID is available but could not be obtained.
+     */
+    @Override
+    public final byte[] getChannelId() throws SSLException {
+        if (getUseClientMode()) {
+            throw new IllegalStateException("Client mode");
+        }
+
+        synchronized (ssl) {
+            if (state != STATE_READY) {
+                throw new IllegalStateException(
+                        "Channel ID is only available after handshake completes");
+            }
+        }
+        return ssl.getTlsChannelId();
+    }
+
+    /**
+     * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
+     *
+     * <p>This method needs to be invoked before the handshake starts.
+     *
+     * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
+     *        TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
+     *        P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
+     *
+     * @throws IllegalStateException if this is a server socket or if the handshake has already
+     *         started.
+     */
+    @Override
+    public final void setChannelIdPrivateKey(PrivateKey privateKey) {
+        if (!getUseClientMode()) {
+            throw new IllegalStateException("Server mode");
+        }
+
+        synchronized (ssl) {
+            if (state != STATE_NEW) {
+                throw new IllegalStateException(
+                        "Could not change Channel ID private key after the initial handshake has"
+                                + " begun.");
+            }
+        }
+
+        if (privateKey == null) {
+            sslParameters.channelIdEnabled = false;
+            channelIdPrivateKey = null;
+        } else {
+            sslParameters.channelIdEnabled = true;
+            try {
+                ECParameterSpec ecParams = null;
+                if (privateKey instanceof ECKey) {
+                    ecParams = ((ECKey) privateKey).getParams();
+                }
+                if (ecParams == null) {
+                    // Assume this is a P-256 key, as specified in the contract of this method.
+                    ecParams =
+                            OpenSSLECGroupContext.getCurveByName("prime256v1").getECParameterSpec();
+                }
+                channelIdPrivateKey =
+                        OpenSSLKey.fromECPrivateKeyForTLSStackOnly(privateKey, ecParams);
+            } catch (InvalidKeyException e) {
+                // Will have error in startHandshake
+            }
+        }
+    }
+
+    @Override
+    byte[] getTlsUnique() {
+        return ssl.getTlsUnique();
+    }
+
+    @Override
+    byte[] exportKeyingMaterial(String label, byte[] context, int length) throws SSLException {
+        synchronized (ssl) {
+            if (state < STATE_HANDSHAKE_COMPLETED || state == STATE_CLOSED) {
+                return null;
+            }
+        }
+        return ssl.exportKeyingMaterial(label, context, length);
+    }
+
+    @Override
+    public final boolean getUseClientMode() {
+        return sslParameters.getUseClientMode();
+    }
+
+    @Override
+    public final void setUseClientMode(boolean mode) {
+        synchronized (ssl) {
+            if (state != STATE_NEW) {
+                throw new IllegalArgumentException(
+                        "Could not change the mode after the initial handshake has begun.");
+            }
+        }
+        sslParameters.setUseClientMode(mode);
+    }
+
+    @Override
+    public final boolean getWantClientAuth() {
+        return sslParameters.getWantClientAuth();
+    }
+
+    @Override
+    public final boolean getNeedClientAuth() {
+        return sslParameters.getNeedClientAuth();
+    }
+
+    @Override
+    public final void setNeedClientAuth(boolean need) {
+        sslParameters.setNeedClientAuth(need);
+    }
+
+    @Override
+    public final void setWantClientAuth(boolean want) {
+        sslParameters.setWantClientAuth(want);
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    @Override
+    public final void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+        this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
+
+        Platform.setSocketWriteTimeout(this, writeTimeoutMilliseconds);
+    }
+
+    /**
+     * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
+     */
+    @Override
+    public final 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.
+     */
+    @Override
+    public final void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+        this.handshakeTimeoutMilliseconds = handshakeTimeoutMilliseconds;
+    }
+
+    @Override
+    @SuppressWarnings("UnsynchronizedOverridesSynchronized")
+    public final void close() throws IOException {
+        // TODO: Close SSL sockets using a background thread so they close gracefully.
+
+        SSLInputStream sslInputStream;
+        SSLOutputStream sslOutputStream;
+
+        if (ssl == null) {
+            // close() has been called before we've initialized the socket, so just
+            // return.
+            return;
+        }
+
+        synchronized (ssl) {
+            if (state == STATE_CLOSED) {
+                // close() has already been called, so do nothing and return.
+                return;
+            }
+
+            int oldState = state;
+            transitionTo(STATE_CLOSED);
+
+            if (oldState == STATE_NEW) {
+                // The handshake hasn't been started yet, so there's no OpenSSL related
+                // state to clean up. We still need to close the underlying socket if
+                // we're wrapping it and were asked to autoClose.
+                free();
+                closeUnderlyingSocket();
+
+                ssl.notifyAll();
+                return;
+            }
+
+            if (oldState != STATE_READY && oldState != STATE_READY_HANDSHAKE_CUT_THROUGH) {
+                // If we're in these states, we still haven't returned from startHandshake.
+                // We call SSL_interrupt so that we can interrupt SSL_do_handshake and then
+                // set the state to STATE_CLOSED. startHandshake will handle all cleanup
+                // after SSL_do_handshake returns, so we don't have anything to do here.
+                ssl.interrupt();
+
+                ssl.notifyAll();
+                return;
+            }
+
+            ssl.notifyAll();
+            // We've already returned from startHandshake, so we potentially have
+            // input and output streams to clean up.
+            sslInputStream = is;
+            sslOutputStream = os;
+        }
+
+        // Don't bother interrupting unless we have something to interrupt.
+        if (sslInputStream != null || sslOutputStream != null) {
+            ssl.interrupt();
+        }
+
+        // Wait for the input and output streams to finish any reads they have in
+        // progress. If there are no reads in progress at this point, future reads will
+        // throw because state == STATE_CLOSED
+        if (sslInputStream != null) {
+            sslInputStream.awaitPendingOps();
+        }
+        if (sslOutputStream != null) {
+            sslOutputStream.awaitPendingOps();
+        }
+
+        shutdownAndFreeSslNative();
+    }
+
+    private void shutdownAndFreeSslNative() throws IOException {
+        try {
+            Platform.blockGuardOnNetwork();
+            ssl.shutdown(Platform.getFileDescriptor(socket));
+        } catch (IOException ignored) {
+            /*
+             * Note that although close() can throw
+             * IOException, the RI does not throw if there
+             * is problem sending a "close notify" which
+             * can happen if the underlying socket is closed.
+             */
+        } finally {
+            free();
+            closeUnderlyingSocket();
+        }
+    }
+
+    private void closeUnderlyingSocket() throws IOException {
+        super.close();
+    }
+
+    private void free() {
+        if (!ssl.isClosed()) {
+            ssl.close();
+            Platform.closeGuardClose(guard);
+        }
+    }
+
+    @Override
+    protected final void finalize() throws Throwable {
+        try {
+            /*
+             * Just worry about our own state. Notably we do not try and
+             * close anything. The SocketImpl, either our own
+             * PlainSocketImpl, or the Socket we are wrapping, will do
+             * that. This might mean we do not properly SSL_shutdown, but
+             * if you want to do that, properly close the socket yourself.
+             *
+             * The reason why we don't try to SSL_shutdown, is that there
+             * can be a race between finalizers where the PlainSocketImpl
+             * finalizer runs first and closes the socket. However, in the
+             * meanwhile, the underlying file descriptor could be reused
+             * for another purpose. If we call SSL_shutdown, the
+             * underlying socket BIOs still have the old file descriptor
+             * and will write the close notify to some unsuspecting
+             * reader.
+             */
+            if (guard != null) {
+                Platform.closeGuardWarnIfOpen(guard);
+            }
+            if (ssl != null) {
+                synchronized (ssl) {
+                    transitionTo(STATE_CLOSED);
+                }
+            }
+        } finally {
+            super.finalize();
+        }
+
+    }
+
+    @Override
+    public final void setApplicationProtocolSelector(ApplicationProtocolSelector selector) {
+        setApplicationProtocolSelector(
+                selector == null ? null : new ApplicationProtocolSelectorAdapter(this, selector));
+    }
+
+    @Override
+    final void setApplicationProtocolSelector(ApplicationProtocolSelectorAdapter selector) {
+        sslParameters.setApplicationProtocolSelector(selector);
+    }
+
+    @Override
+    final void setApplicationProtocols(String[] protocols) {
+        sslParameters.setApplicationProtocols(protocols);
+    }
+
+    @Override
+    final String[] getApplicationProtocols() {
+        return sslParameters.getApplicationProtocols();
+    }
+
+    @Override
+    public final String getApplicationProtocol() {
+        return SSLUtils.toProtocolString(ssl.getApplicationProtocol());
+    }
+
+    @Override
+    public final String getHandshakeApplicationProtocol() {
+        synchronized (ssl) {
+            return state >= STATE_HANDSHAKE_STARTED && state < STATE_READY
+                ? getApplicationProtocol() : null;
+        }
+    }
+
+    @Override
+    public final SSLParameters getSSLParameters() {
+        SSLParameters params = super.getSSLParameters();
+        Platform.getSSLParameters(params, sslParameters, this);
+        return params;
+    }
+
+    @Override
+    public final void setSSLParameters(SSLParameters p) {
+        super.setSSLParameters(p);
+        Platform.setSSLParameters(p, sslParameters, this);
+    }
+
+    @Override
+    public final String chooseServerAlias(X509KeyManager keyManager, String keyType) {
+        return keyManager.chooseServerAlias(keyType, null, this);
+    }
+
+    @Override
+    public final String chooseClientAlias(X509KeyManager keyManager, X500Principal[] issuers,
+            String[] keyTypes) {
+        return keyManager.chooseClientAlias(keyTypes, issuers, this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public final String chooseServerPSKIdentityHint(PSKKeyManager keyManager) {
+        return keyManager.chooseServerKeyIdentityHint(this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public final String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint) {
+        return keyManager.chooseClientKeyIdentity(identityHint, this);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    public final SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity) {
+        return keyManager.getKey(identityHint, identity, this);
+    }
+
+    private ClientSessionContext clientSessionContext() {
+        return sslParameters.getClientSessionContext();
+    }
+
+    private AbstractSessionContext sessionContext() {
+        return sslParameters.getSessionContext();
+    }
+
+    private void transitionTo(int newState) {
+        switch (newState) {
+            case STATE_CLOSED: {
+                if (!ssl.isClosed() && state >= STATE_HANDSHAKE_STARTED && state < STATE_CLOSED ) {
+                    closedSession = new SessionSnapshot(activeSession);
+                }
+                break;
+            }
+            default: {
+                break;
+            }
+        }
+
+        // Update the state
+        this.state = newState;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptHostnameVerifier.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptHostnameVerifier.java
new file mode 100644
index 0000000..a62cf9f
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptHostnameVerifier.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2019 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 com.android.org.conscrypt;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * This interface is used to implement hostname verification in Conscrypt.  Unlike with
+ * {@link javax.net.ssl.HostnameVerifier}, the hostname verifier is called whenever hostname
+ * verification is needed, without any use of default rules.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface ConscryptHostnameVerifier {
+
+  /**
+   * Returns whether the given hostname is allowable given the peer's authentication information
+   * from the given session.
+   */
+  boolean verify(String hostname, SSLSession session);
+
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptServerSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptServerSocket.java
new file mode 100644
index 0000000..c667e8b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptServerSocket.java
@@ -0,0 +1,190 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2007 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import javax.net.ssl.SSLServerSocket;
+
+/**
+ * BoringSSL-based implementation of server sockets.
+ */
+final class ConscryptServerSocket extends SSLServerSocket {
+    private final SSLParametersImpl sslParameters;
+    private boolean channelIdEnabled;
+    private boolean useEngineSocket;
+
+    ConscryptServerSocket(SSLParametersImpl sslParameters) throws IOException {
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptServerSocket(int port, SSLParametersImpl sslParameters)
+        throws IOException {
+        super(port);
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptServerSocket(int port, int backlog, SSLParametersImpl sslParameters)
+        throws IOException {
+        super(port, backlog);
+        this.sslParameters = sslParameters;
+    }
+
+    ConscryptServerSocket(int port,
+                                      int backlog,
+                                      InetAddress iAddress,
+                                      SSLParametersImpl sslParameters)
+        throws IOException {
+        super(port, backlog, iAddress);
+        this.sslParameters = sslParameters;
+    }
+
+    /**
+     * Configures the socket to be created for this instance.
+     */
+    ConscryptServerSocket setUseEngineSocket(boolean useEngineSocket) {
+        this.useEngineSocket = useEngineSocket;
+        return this;
+    }
+
+    @Override
+    public boolean getEnableSessionCreation() {
+        return sslParameters.getEnableSessionCreation();
+    }
+
+    @Override
+    public void setEnableSessionCreation(boolean flag) {
+        sslParameters.setEnableSessionCreation(flag);
+    }
+
+    /**
+     * The names of the protocols' versions that may be used on this SSL
+     * connection.
+     * @return an array of protocols names
+     */
+    @Override
+    public String[] getSupportedProtocols() {
+        return NativeCrypto.getSupportedProtocols();
+    }
+
+    /**
+     * The names of the protocols' versions that in use on this SSL connection.
+     *
+     * @return an array of protocols names
+     */
+    @Override
+    public String[] getEnabledProtocols() {
+        return sslParameters.getEnabledProtocols();
+    }
+
+    /**
+     * This method enables the protocols' versions listed by
+     * getSupportedProtocols().
+     *
+     * @param protocols names of all the protocols to enable.
+     *
+     * @throws IllegalArgumentException when one or more of the names in the
+     *             array are not supported, or when the array is null.
+     */
+    @Override
+    public void setEnabledProtocols(String[] protocols) {
+        sslParameters.setEnabledProtocols(protocols);
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return NativeCrypto.getSupportedCipherSuites();
+    }
+
+    @Override
+    public String[] getEnabledCipherSuites() {
+        return sslParameters.getEnabledCipherSuites();
+    }
+
+    /**
+     * Enables/disables the TLS Channel ID extension for this server socket.
+     */
+    void setChannelIdEnabled(boolean enabled) {
+      channelIdEnabled = enabled;
+    }
+
+    /**
+     * Checks whether the TLS Channel ID extension is enabled for this server socket.
+     */
+    boolean isChannelIdEnabled() {
+      return channelIdEnabled;
+    }
+
+    /**
+     * This method enables the cipher suites listed by
+     * getSupportedCipherSuites().
+     *
+     * @param suites the names of all the cipher suites to enable
+     * @throws IllegalArgumentException when one or more of the ciphers in array
+     *         suites are not supported, or when the array is null.
+     */
+    @Override
+    public void setEnabledCipherSuites(String[] suites) {
+        sslParameters.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public boolean getWantClientAuth() {
+        return sslParameters.getWantClientAuth();
+    }
+
+    @Override
+    public void setWantClientAuth(boolean want) {
+        sslParameters.setWantClientAuth(want);
+    }
+
+    @Override
+    public boolean getNeedClientAuth() {
+        return sslParameters.getNeedClientAuth();
+    }
+
+    @Override
+    public void setNeedClientAuth(boolean need) {
+        sslParameters.setNeedClientAuth(need);
+    }
+
+    @Override
+    public void setUseClientMode(boolean mode) {
+        sslParameters.setUseClientMode(mode);
+    }
+
+    @Override
+    public boolean getUseClientMode() {
+        return sslParameters.getUseClientMode();
+    }
+
+    @Override
+    public Socket accept() throws IOException {
+        final AbstractConscryptSocket socket;
+        if (useEngineSocket) {
+            socket = Platform.createEngineSocket(sslParameters);
+        } else {
+            socket = Platform.createFileDescriptorSocket(sslParameters);
+        }
+
+        socket.setChannelIdEnabled(channelIdEnabled);
+        implAccept(socket);
+        return socket;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptSession.java
new file mode 100644
index 0000000..c4732f1
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ConscryptSession.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * Extends the default interface for {@link SSLSession} to provide additional properties exposed
+ * by Conscrypt.
+ */
+interface ConscryptSession extends SSLSession {
+
+  String getRequestedServerName();
+
+  /**
+   * Returns the OCSP stapled response. Returns a copy of the internal arrays.
+   *
+   * The method signature matches
+   * <a
+   * href="http://download.java.net/java/jdk9/docs/api/javax/net/ssl/ExtendedSSLSession.html#getStatusResponses--">Java
+   * 9</a>.
+   *
+   * @see <a href="https://tools.ietf.org/html/rfc6066">RFC 6066</a>
+   * @see <a href="https://tools.ietf.org/html/rfc6961">RFC 6961</a>
+   */
+  List<byte[]> getStatusResponses();
+
+  /**
+   * Returns the signed certificate timestamp (SCT) received from the peer. Returns a
+   * copy of the internal array.
+   *
+   * @see <a href="https://tools.ietf.org/html/rfc6962">RFC 6962</a>
+   */
+  byte[] getPeerSignedCertificateTimestamp();
+
+  @Override
+  X509Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException;
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/CryptoUpcalls.java b/repackaged/common/src/main/java/com/android/org/conscrypt/CryptoUpcalls.java
new file mode 100644
index 0000000..7e2a4e9
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/CryptoUpcalls.java
@@ -0,0 +1,230 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Security;
+import java.security.Signature;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * Provides a place where NativeCrypto can call back up to do Java language
+ * calls to work on delegated key types from native code. Delegated keys are
+ * usually backed by hardware so we don't have access directly to the private
+ * key material. If it were a key where we can get to the private key, we
+ * would not ever call into this class.
+ */
+final class CryptoUpcalls {
+    private static final Logger logger = Logger.getLogger(CryptoUpcalls.class.getName());
+
+    private CryptoUpcalls() {}
+
+    /**
+     * Finds providers that are not us that provide the requested algorithms.
+     */
+    private static ArrayList<Provider> getExternalProviders(String algorithm) {
+        ArrayList<Provider> providers = new ArrayList<Provider>(1);
+        for (Provider p : Security.getProviders(algorithm)) {
+            if (!Conscrypt.isConscrypt(p)) {
+                providers.add(p);
+            }
+        }
+        if (providers.isEmpty()) {
+            logger.warning("Could not find external provider for algorithm: " + algorithm);
+        }
+        return providers;
+    }
+
+    static byte[] ecSignDigestWithPrivateKey(PrivateKey javaKey, byte[] message) {
+        // Hint: Algorithm names come from:
+        // http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html
+        String keyAlgorithm = javaKey.getAlgorithm();
+        if (!"EC".equals(keyAlgorithm)) {
+            throw new RuntimeException("Unexpected key type: " + javaKey.toString());
+        }
+
+        return signDigestWithPrivateKey(javaKey, message, "NONEwithECDSA");
+    }
+
+    private static byte[] signDigestWithPrivateKey(PrivateKey javaKey, byte[] message,
+            String algorithm) {
+        Signature signature;
+
+        // Since this is a delegated key, we cannot handle providing a signature using this key.
+        // Otherwise we wouldn't end up in this class in the first place. The first step is to
+        // try to get the most preferred provider as long as it isn't us.
+        try {
+            signature = Signature.getInstance(algorithm);
+            signature.initSign(javaKey);
+
+            // Ignore it if it points back to us.
+            if (Conscrypt.isConscrypt(signature.getProvider())) {
+                signature = null;
+            }
+        } catch (NoSuchAlgorithmException e) {
+            logger.warning("Unsupported signature algorithm: " + algorithm);
+            return null;
+        } catch (InvalidKeyException e) {
+            logger.warning("Preferred provider doesn't support key:");
+            e.printStackTrace();
+            signature = null;
+        }
+
+        // If the preferred provider was us, fall back to trying to find the
+        // first not-us provider that initializes correctly.
+        if (signature == null) {
+            ArrayList<Provider> providers = getExternalProviders("Signature." + algorithm);
+            RuntimeException savedRuntimeException = null;
+            for (Provider p : providers) {
+                try {
+                    signature = Signature.getInstance(algorithm, p);
+                    signature.initSign(javaKey);
+                    break;
+                } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+                    signature = null;
+                } catch (RuntimeException e) {
+                    signature = null;
+                    if (savedRuntimeException == null) {
+                        savedRuntimeException = e;
+                    }
+                }
+            }
+            if (signature == null) {
+                if (savedRuntimeException != null) {
+                    throw savedRuntimeException;
+                }
+                logger.warning("Could not find provider for algorithm: " + algorithm);
+                return null;
+            }
+        }
+
+        // Sign the message.
+        try {
+            signature.update(message);
+            return signature.sign();
+        } catch (Exception e) {
+            logger.log(Level.WARNING,
+                    "Exception while signing message with " + javaKey.getAlgorithm()
+                            + " private key:",
+                    e);
+            return null;
+        }
+    }
+
+    static byte[] rsaSignDigestWithPrivateKey(PrivateKey javaKey, int openSSLPadding,
+            byte[] message) {
+        // An RSA cipher + ENCRYPT_MODE produces a standard RSA signature
+        return rsaOpWithPrivateKey(javaKey, openSSLPadding, Cipher.ENCRYPT_MODE, message);
+    }
+
+    static byte[] rsaDecryptWithPrivateKey(PrivateKey javaKey, int openSSLPadding, byte[] input) {
+        return rsaOpWithPrivateKey(javaKey, openSSLPadding, Cipher.DECRYPT_MODE, input);
+    }
+
+    private static byte[] rsaOpWithPrivateKey(PrivateKey javaKey, int openSSLPadding,
+            int cipherMode, byte[] input) {
+        String keyAlgorithm = javaKey.getAlgorithm();
+        if (!"RSA".equals(keyAlgorithm)) {
+            logger.warning("Unexpected key type: " + keyAlgorithm);
+            return null;
+        }
+
+        String jcaPadding;
+        switch (openSSLPadding) {
+            case NativeConstants.RSA_PKCS1_PADDING:
+                // Since we're using this with a private key, this will produce RSASSA-PKCS1-v1_5
+                // (signature) padding rather than RSAES-PKCS1-v1_5 (encryption) padding
+                jcaPadding = "PKCS1Padding";
+                break;
+            case NativeConstants.RSA_NO_PADDING:
+                jcaPadding = "NoPadding";
+                break;
+            case NativeConstants.RSA_PKCS1_OAEP_PADDING:
+                jcaPadding = "OAEPPadding";
+                break;
+            default:
+                logger.warning("Unsupported OpenSSL/BoringSSL padding: " + openSSLPadding);
+                return null;
+        }
+
+        String transformation = "RSA/ECB/" + jcaPadding;
+        Cipher c = null;
+
+        // Since this is a delegated key, we cannot handle providing a cipher using this key.
+        // Otherwise we wouldn't end up in this class in the first place. The first step is to
+        // try to get the most preferred provider as long as it isn't us.
+        try {
+            c = Cipher.getInstance(transformation);
+            c.init(cipherMode, javaKey);
+
+            // Ignore it if it points back to us.
+            if (Conscrypt.isConscrypt(c.getProvider())) {
+                c = null;
+            }
+        } catch (NoSuchAlgorithmException e) {
+            logger.warning("Unsupported cipher algorithm: " + transformation);
+            return null;
+        } catch (NoSuchPaddingException e) {
+            logger.warning("Unsupported cipher algorithm: " + transformation);
+            return null;
+        } catch (InvalidKeyException e) {
+            logger.log(Level.WARNING, "Preferred provider doesn't support key:", e);
+            c = null;
+        }
+
+        // If the preferred provider was us, fall back to trying to find the
+        // first not-us provider that initializes correctly.
+        if (c == null) {
+            ArrayList<Provider> providers = getExternalProviders("Cipher." + transformation);
+            for (Provider p : providers) {
+                try {
+                    c = Cipher.getInstance(transformation, p);
+                    c.init(cipherMode, javaKey);
+                    break;
+                } catch (NoSuchAlgorithmException e) {
+                    c = null;
+                } catch (InvalidKeyException e) {
+                    c = null;
+                } catch (NoSuchPaddingException e) {
+                    c = null;
+                }
+            }
+            if (c == null) {
+                logger.warning("Could not find provider for algorithm: " + transformation);
+                return null;
+            }
+        }
+
+        try {
+            return c.doFinal(input);
+        } catch (Exception e) {
+            logger.log(Level.WARNING,
+                    "Exception while decrypting message with " + javaKey.getAlgorithm()
+                            + " private key using " + transformation + ":",
+                    e);
+            return null;
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/DESEDESecretKeyFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/DESEDESecretKeyFactory.java
new file mode 100644
index 0000000..2fce21f
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/DESEDESecretKeyFactory.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactorySpi;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * An implementation of {@link javax.crypto.SecretKeyFactory} for use with DESEDE keys.  This
+ * class supports {@link SecretKeySpec} and {@link DESedeKeySpec} for key specs.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class DESEDESecretKeyFactory extends SecretKeyFactorySpi {
+
+    @libcore.api.IntraCoreApi
+    public DESEDESecretKeyFactory() {}
+
+    @Override
+    protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException {
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("Null KeySpec");
+        }
+        if (keySpec instanceof SecretKeySpec) {
+            SecretKeySpec key = (SecretKeySpec) keySpec;
+            try {
+                if (!DESedeKeySpec.isParityAdjusted(key.getEncoded(), 0)) {
+                    throw new InvalidKeySpecException(
+                            "SecretKeySpec is not a parity-adjusted DESEDE key");
+                }
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException(e);
+            }
+            return key;
+        } else if (keySpec instanceof DESedeKeySpec) {
+            DESedeKeySpec desKeySpec = (DESedeKeySpec) keySpec;
+            return new SecretKeySpec(desKeySpec.getKey(), "DESEDE");
+        } else {
+            throw new InvalidKeySpecException(
+                    "Unsupported KeySpec class: " + keySpec.getClass().getName());
+        }
+    }
+
+    @Override
+    protected KeySpec engineGetKeySpec(SecretKey secretKey,
+            @SuppressWarnings("rawtypes") Class aClass) throws InvalidKeySpecException {
+        if (secretKey == null) {
+            throw new InvalidKeySpecException("Null SecretKey");
+        }
+        if (aClass == SecretKeySpec.class) {
+            try {
+                if (!DESedeKeySpec.isParityAdjusted(secretKey.getEncoded(), 0)) {
+                    throw new InvalidKeySpecException("SecretKey is not a parity-adjusted DESEDE key");
+                }
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException(e);
+            }
+            if (secretKey instanceof SecretKeySpec) {
+                return (KeySpec) secretKey;
+            } else {
+                return new SecretKeySpec(secretKey.getEncoded(), "DESEDE");
+            }
+        } else if (aClass == DESedeKeySpec.class) {
+            try {
+                return new DESedeKeySpec(secretKey.getEncoded());
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException(e);
+            }
+        } else {
+            throw new InvalidKeySpecException("Unsupported KeySpec class: " + aClass);
+        }
+    }
+
+    @Override
+    protected SecretKey engineTranslateKey(SecretKey secretKey) throws InvalidKeyException {
+        if (secretKey == null) {
+            throw new InvalidKeyException("Null SecretKey");
+        }
+        return new SecretKeySpec(secretKey.getEncoded(), secretKey.getAlgorithm());
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/DefaultSSLContextImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/DefaultSSLContextImpl.java
new file mode 100644
index 0000000..26676f0
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/DefaultSSLContextImpl.java
@@ -0,0 +1,133 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+/**
+ * Support class for this package.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class DefaultSSLContextImpl extends OpenSSLContextImpl {
+
+    /**
+     * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
+     * DefaultSSLContextImpl.class monitor
+     */
+    private static KeyManager[] KEY_MANAGERS;
+
+    /**
+     * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
+     * DefaultSSLContextImpl.class monitor
+     */
+    private static TrustManager[] TRUST_MANAGERS;
+
+    /**
+     * DefaultSSLContextImpl delegates the work to the super class since there
+     * is no way to put a synchronized around both the call to super and the
+     * rest of this constructor to guarantee that we don't have races in
+     * creating the state shared between all default SSLContexts.
+     */
+    @libcore.api.IntraCoreApi
+    public DefaultSSLContextImpl() throws GeneralSecurityException, IOException {
+        super();
+    }
+
+    // TODO javax.net.ssl.keyStoreProvider system property
+    KeyManager[] getKeyManagers () throws GeneralSecurityException, IOException {
+        if (KEY_MANAGERS != null) {
+            return KEY_MANAGERS;
+        }
+        // find KeyStore, KeyManagers
+        String keystore = System.getProperty("javax.net.ssl.keyStore");
+        if (keystore == null) {
+            return null;
+        }
+        String keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
+        char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
+
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        InputStream is = null;
+        try {
+            is = new BufferedInputStream(new FileInputStream(keystore));
+            ks.load(is, pwd);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+
+        String kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlg);
+        kmf.init(ks, pwd);
+        KEY_MANAGERS = kmf.getKeyManagers();
+        return KEY_MANAGERS;
+    }
+
+    // TODO javax.net.ssl.trustStoreProvider system property
+    TrustManager[] getTrustManagers() throws GeneralSecurityException, IOException {
+        if (TRUST_MANAGERS != null) {
+            return TRUST_MANAGERS;
+        }
+
+        // find TrustStore, TrustManagers
+        String keystore = System.getProperty("javax.net.ssl.trustStore");
+        if (keystore == null) {
+            return null;
+        }
+        String keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
+        char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
+
+        // TODO Defaults: jssecacerts; cacerts
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        InputStream is = null;
+        try {
+            is = new BufferedInputStream(new FileInputStream(keystore));
+            ks.load(is, pwd);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+        String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
+        tmf.init(ks);
+        TRUST_MANAGERS = tmf.getTrustManagers();
+        return TRUST_MANAGERS;
+    }
+
+    @Override
+    public void engineInit(KeyManager[] kms, TrustManager[] tms,
+            SecureRandom sr) throws KeyManagementException {
+        throw new KeyManagementException("Do not init() the default SSLContext ");
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedPSKKeyManager.java b/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedPSKKeyManager.java
new file mode 100644
index 0000000..7c6eccf
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/DuckTypedPSKKeyManager.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import java.lang.reflect.Method;
+import java.net.Socket;
+import javax.crypto.SecretKey;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Reflection-based {@link PSKKeyManager} adaptor for objects which expose all the methods of the
+ * {@code PSKKeyManager} interface but do not implement the interface.
+ *
+ * <p>This is expected to be useful on platforms where there are multiple instances of the
+ * {@code PSKKeyManager} interface.
+ *
+ * Visible for testing only.
+ *
+ * @deprecated This abstraction is deprecated because it does not work with TLS 1.3.
+ */
+@Deprecated
+final class DuckTypedPSKKeyManager implements PSKKeyManager {
+
+    private final Object mDelegate;
+
+    private DuckTypedPSKKeyManager(Object delegate) {
+        mDelegate = delegate;
+    }
+
+    /**
+     * Gets an instance of {@code DuckTypedPSKKeyManager} which delegates all invocations of methods
+     * of the {@link PSKKeyManager} interface to the same methods of the provided object.
+     *
+     * @throws NoSuchMethodException if {@code obj} does not implement a method of the
+     *         {@code PSKKeyManager} interface.
+     */
+    static DuckTypedPSKKeyManager getInstance(Object obj) throws NoSuchMethodException {
+        Class<?> sourceClass = obj.getClass();
+        for (Method targetMethod : PSKKeyManager.class.getMethods()) {
+            if (targetMethod.isSynthetic()) {
+                continue;
+            }
+            // Check that obj exposes the target method (same name and parameter types)
+            Method sourceMethod =
+                    sourceClass.getMethod(targetMethod.getName(), targetMethod.getParameterTypes());
+            // Check that the return type of obj's method matches the target method.
+            Class<?> sourceReturnType = sourceMethod.getReturnType();
+            Class<?> targetReturnType = targetMethod.getReturnType();
+            if (!targetReturnType.isAssignableFrom(sourceReturnType)) {
+                throw new NoSuchMethodException(sourceMethod + " return value (" + sourceReturnType
+                        + ") incompatible with target return value (" + targetReturnType + ")");
+            }
+        }
+
+        return new DuckTypedPSKKeyManager(obj);
+    }
+
+    @Override
+    public String chooseServerKeyIdentityHint(Socket socket) {
+        try {
+            return (String) mDelegate.getClass()
+                    .getMethod("chooseServerKeyIdentityHint", Socket.class)
+                    .invoke(mDelegate, socket);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to invoke chooseServerKeyIdentityHint", e);
+        }
+    }
+
+    @Override
+    public String chooseServerKeyIdentityHint(SSLEngine engine) {
+        try {
+            return (String) mDelegate.getClass()
+                    .getMethod("chooseServerKeyIdentityHint", SSLEngine.class)
+                    .invoke(mDelegate, engine);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to invoke chooseServerKeyIdentityHint", e);
+        }
+    }
+
+    @Override
+    public String chooseClientKeyIdentity(String identityHint, Socket socket) {
+        try {
+            return (String) mDelegate.getClass()
+                    .getMethod("chooseClientKeyIdentity", String.class, Socket.class)
+                    .invoke(mDelegate, identityHint, socket);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to invoke chooseClientKeyIdentity", e);
+        }
+    }
+
+    @Override
+    public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+        try {
+            return (String) mDelegate.getClass()
+                    .getMethod("chooseClientKeyIdentity", String.class, SSLEngine.class)
+                    .invoke(mDelegate, identityHint, engine);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to invoke chooseClientKeyIdentity", e);
+        }
+    }
+
+    @Override
+    public SecretKey getKey(String identityHint, String identity, Socket socket) {
+        try {
+            return (SecretKey) mDelegate.getClass()
+                    .getMethod("getKey", String.class, String.class, Socket.class)
+                    .invoke(mDelegate, identityHint, identity, socket);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to invoke getKey", e);
+        }
+    }
+
+    @Override
+    public SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
+        try {
+            return (SecretKey) mDelegate.getClass()
+                    .getMethod("getKey", String.class, String.class, SSLEngine.class)
+                    .invoke(mDelegate, identityHint, identity, engine);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to invoke getKey", e);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ECParameters.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ECParameters.java
new file mode 100644
index 0000000..1e995fd
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ECParameters.java
@@ -0,0 +1,117 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.security.AlgorithmParametersSpi;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * AlgorithmParameters implementation for elliptic curves.  The only supported encoding format is
+ * ASN.1, as specified in RFC 3279, section 2.3.5.  However, only named curves are supported.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class ECParameters extends AlgorithmParametersSpi {
+
+    private OpenSSLECGroupContext curve;
+
+    @libcore.api.IntraCoreApi
+    public ECParameters() {}
+
+    @Override
+    protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+            throws InvalidParameterSpecException {
+        if (algorithmParameterSpec instanceof ECGenParameterSpec) {
+            String newCurveName = ((ECGenParameterSpec) algorithmParameterSpec).getName();
+            OpenSSLECGroupContext newCurve = OpenSSLECGroupContext.getCurveByName(newCurveName);
+            if (newCurve == null) {
+                throw new InvalidParameterSpecException("Unknown EC curve name: " + newCurveName);
+            }
+            this.curve = newCurve;
+        } else if (algorithmParameterSpec instanceof ECParameterSpec) {
+            ECParameterSpec ecParamSpec = (ECParameterSpec) algorithmParameterSpec;
+            try {
+                OpenSSLECGroupContext newCurve = OpenSSLECGroupContext.getInstance(ecParamSpec);
+                if (newCurve == null) {
+                    throw new InvalidParameterSpecException("Unknown EC curve: " + ecParamSpec);
+                }
+                this.curve = newCurve;
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new InvalidParameterSpecException(e.getMessage());
+            }
+        } else {
+            throw new InvalidParameterSpecException(
+                    "Only ECParameterSpec and ECGenParameterSpec are supported");
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes) throws IOException {
+        long ref = NativeCrypto.EC_KEY_parse_curve_name(bytes);
+        if (ref == 0) {
+            throw new IOException("Error reading ASN.1 encoding");
+        }
+        this.curve = new OpenSSLECGroupContext(new NativeRef.EC_GROUP(ref));
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes, String format) throws IOException {
+        if (format == null || format.equals("ASN.1")) {
+            engineInit(bytes);
+        } else {
+            throw new IOException("Unsupported format: " + format);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> aClass)
+            throws InvalidParameterSpecException {
+        if (aClass == ECParameterSpec.class) {
+            return (T) curve.getECParameterSpec();
+        } else if (aClass == ECGenParameterSpec.class) {
+            return (T) new ECGenParameterSpec(Platform.getCurveName(curve.getECParameterSpec()));
+        } else {
+            throw new InvalidParameterSpecException("Unsupported class: " + aClass);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded() throws IOException {
+        return NativeCrypto.EC_KEY_marshal_curve_name(curve.getNativeRef());
+    }
+
+    @Override
+    protected byte[] engineGetEncoded(String format) throws IOException {
+        if (format == null || format.equals("ASN.1")) {
+            return engineGetEncoded();
+        }
+        throw new IOException("Unsupported format: " + format);
+    }
+
+    @Override
+    protected String engineToString() {
+        return "Conscrypt EC AlgorithmParameters";
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/EmptyArray.java b/repackaged/common/src/main/java/com/android/org/conscrypt/EmptyArray.java
new file mode 100644
index 0000000..a36d337
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/EmptyArray.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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.
+ */
+
+// Copied from libcore.util.EmptyArray
+
+package com.android.org.conscrypt;
+
+final class EmptyArray {
+    private EmptyArray() {}
+
+    static final boolean[] BOOLEAN = new boolean[0];
+    static final byte[] BYTE = new byte[0];
+    static final char[] CHAR = new char[0];
+    static final double[] DOUBLE = new double[0];
+    static final int[] INT = new int[0];
+
+    static final Class<?>[] CLASS = new Class<?>[ 0 ];
+    static final Object[] OBJECT = new Object[0];
+    static final String[] STRING = new String[0];
+    static final Throwable[] THROWABLE = new Throwable[0];
+    static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/EvpMdRef.java b/repackaged/common/src/main/java/com/android/org/conscrypt/EvpMdRef.java
new file mode 100644
index 0000000..fd62130
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/EvpMdRef.java
@@ -0,0 +1,159 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2016 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 com.android.org.conscrypt;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
+
+/**
+ * Utility class to convert between BoringSSL- and JCE-style message digest identifiers.
+ */
+final class EvpMdRef {
+    static final String MGF1_ALGORITHM_NAME = "MGF1";
+    static final String MGF1_OID = "1.2.840.113549.1.1.8";
+
+    /**
+     * Returns the canonical JCA digest algorithm name for the provided digest
+     * algorithm name or {@code null} if the digest algorithm is not known.
+     */
+    static String getJcaDigestAlgorithmStandardName(String algorithm) {
+        String algorithmUpper = algorithm.toUpperCase(Locale.US);
+        if (SHA256.JCA_NAME.equals(algorithmUpper) || SHA256.OID.equals(algorithmUpper)) {
+            return SHA256.JCA_NAME;
+        } else if (SHA512.JCA_NAME.equals(algorithmUpper) || SHA512.OID.equals(algorithmUpper)) {
+            return SHA512.JCA_NAME;
+        } else if (SHA1.JCA_NAME.equals(algorithmUpper) || SHA1.OID.equals(algorithmUpper)) {
+            return SHA1.JCA_NAME;
+        } else if (SHA384.JCA_NAME.equals(algorithmUpper) || SHA384.OID.equals(algorithmUpper)) {
+            return SHA384.JCA_NAME;
+        } else if (SHA224.JCA_NAME.equals(algorithmUpper) || SHA224.OID.equals(algorithmUpper)) {
+            return SHA224.JCA_NAME;
+        } else {
+            return null;
+        }
+    }
+
+    static long getEVP_MDByJcaDigestAlgorithmStandardName(String algorithm)
+            throws NoSuchAlgorithmException {
+        String algorithmUpper = algorithm.toUpperCase(Locale.US);
+        if (SHA256.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA256.EVP_MD;
+        } else if (SHA512.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA512.EVP_MD;
+        } else if (SHA1.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA1.EVP_MD;
+        } else if (SHA384.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA384.EVP_MD;
+        } else if (SHA224.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA224.EVP_MD;
+        } else {
+            throw new NoSuchAlgorithmException("Unsupported algorithm: " + algorithm);
+        }
+    }
+
+    static int getDigestSizeBytesByJcaDigestAlgorithmStandardName(String algorithm)
+            throws NoSuchAlgorithmException {
+        String algorithmUpper = algorithm.toUpperCase(Locale.US);
+        if (SHA256.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA256.SIZE_BYTES;
+        } else if (SHA512.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA512.SIZE_BYTES;
+        } else if (SHA1.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA1.SIZE_BYTES;
+        } else if (SHA384.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA384.SIZE_BYTES;
+        } else if (SHA224.JCA_NAME.equals(algorithmUpper)) {
+            return EvpMdRef.SHA224.SIZE_BYTES;
+        } else {
+            throw new NoSuchAlgorithmException("Unsupported algorithm: " + algorithm);
+        }
+    }
+
+    static String getJcaDigestAlgorithmStandardNameFromEVP_MD(long evpMdRef) {
+        if (evpMdRef == MD5.EVP_MD) {
+            return MD5.JCA_NAME;
+        } else if (evpMdRef == SHA1.EVP_MD) {
+            return SHA1.JCA_NAME;
+        } else if (evpMdRef == SHA224.EVP_MD) {
+            return SHA224.JCA_NAME;
+        } else if (evpMdRef == SHA256.EVP_MD) {
+            return SHA256.JCA_NAME;
+        } else if (evpMdRef == SHA384.EVP_MD) {
+            return SHA384.JCA_NAME;
+        } else if (evpMdRef == SHA512.EVP_MD) {
+            return SHA512.JCA_NAME;
+        } else {
+            throw new IllegalArgumentException("Unknown EVP_MD reference");
+        }
+    }
+
+    static final class MD5 {
+        static final String JCA_NAME = "MD5";
+        static final String OID = "1.2.840.113549.2.5";
+        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
+        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
+
+        private MD5() {}
+    }
+
+    static final class SHA1 {
+        static final String JCA_NAME = "SHA-1";
+        static final String OID = "1.3.14.3.2.26";
+        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
+        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
+        private SHA1() {}
+    }
+
+    static final class SHA224 {
+        static final String JCA_NAME = "SHA-224";
+        static final String OID = "2.16.840.1.101.3.4.2.4";
+        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha224");
+        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
+
+        private SHA224() {}
+    }
+
+    static final class SHA256 {
+        static final String JCA_NAME = "SHA-256";
+        static final String OID = "2.16.840.1.101.3.4.2.1";
+        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
+        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
+
+        private SHA256() {}
+    }
+
+    static final class SHA384 {
+        static final String JCA_NAME = "SHA-384";
+        static final String OID = "2.16.840.1.101.3.4.2.2";
+        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
+        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
+
+        private SHA384() {}
+    }
+
+    static final class SHA512 {
+        static final String JCA_NAME = "SHA-512";
+        static final String OID = "2.16.840.1.101.3.4.2.3";
+        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
+        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
+
+        private SHA512() {}
+    }
+
+    private EvpMdRef() {}
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ExperimentalApi.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ExperimentalApi.java
new file mode 100644
index 0000000..947ab63
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ExperimentalApi.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates a public API that can change at any time, and has no guarantee of API stability and
+ * backward-compatibility.
+ *
+ * <p>Usage guidelines:
+ * <ol>
+ * <li>This annotation is used only on public API. Internal interfaces should not use it.</li>
+ * <li>This annotation should only be added to new APIs. Adding it to an existing API is
+ * considered API-breaking.</li>
+ * <li>Removing this annotation from an API gives it stable status.</li>
+ * </ol>
+ */
+@Internal
+@Retention(RetentionPolicy.SOURCE)
+@Target({
+        ElementType.ANNOTATION_TYPE,
+        ElementType.CONSTRUCTOR,
+        ElementType.FIELD,
+        ElementType.METHOD,
+        ElementType.PACKAGE,
+        ElementType.TYPE})
+@Documented
+public @interface ExperimentalApi {
+    /**
+     * Context information such as links to discussion thread, tracking issue etc.
+     */
+    String value() default "";
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ExternalSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ExternalSession.java
new file mode 100644
index 0000000..c6eaa41
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ExternalSession.java
@@ -0,0 +1,214 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.HashMap;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.X509Certificate;
+
+/**
+ * An externalized view of the underlying {@link SSLSession} used within a
+ * socket/engine. This class provides the caller with a consistent session
+ * handle which will continue to be usable regardless of internal changes
+ * to the connection.  It does this by delegating calls to the <b>current</b>
+ * internal session, which is provided by the session {@code Provider}
+ * (i.e. the socket or engine that owns the session).  This allows the provider
+ * to switch implementations (for instance, using a JNI implementation to
+ * access live values while the connection is open and a set of final values
+ * when the connection is closed), even if the caller stores a reference to
+ * the session object.
+ *
+ * <p>This class implements the {@link SSLSession} value API itself, rather
+ * than delegating to the provided session, to ensure the caller has a consistent
+ * value map, regardless of which internal session is currently being used by the
+ * socket/engine.  This class will never call the value API methods on the
+ * underlying sessions, so they need not be implemented.
+ */
+final class ExternalSession implements ConscryptSession {
+    // Use an initialcapacity of 2 to keep it small in the average case.
+    private final HashMap<String, Object> values = new HashMap<String, Object>(2);
+    private final Provider provider;
+
+    public ExternalSession(Provider provider) {
+        this.provider = provider;
+    }
+
+    @Override
+    public String getRequestedServerName() {
+        return provider.provideSession().getRequestedServerName();
+    }
+
+    @Override
+    public List<byte[]> getStatusResponses() {
+        return provider.provideSession().getStatusResponses();
+    }
+
+    @Override
+    public byte[] getPeerSignedCertificateTimestamp() {
+        return provider.provideSession().getPeerSignedCertificateTimestamp();
+    }
+
+    @Override
+    public byte[] getId() {
+        return provider.provideSession().getId();
+    }
+
+    @Override
+    public SSLSessionContext getSessionContext() {
+        return provider.provideSession().getSessionContext();
+    }
+
+    @Override
+    public long getCreationTime() {
+        return provider.provideSession().getCreationTime();
+    }
+
+    @Override
+    public long getLastAccessedTime() {
+        return provider.provideSession().getLastAccessedTime();
+    }
+
+    @Override
+    public void invalidate() {
+        provider.provideSession().invalidate();
+    }
+
+    @Override
+    public boolean isValid() {
+        return provider.provideSession().isValid();
+    }
+
+    @Override
+    public java.security.cert.X509Certificate[] getPeerCertificates()
+            throws SSLPeerUnverifiedException {
+        return provider.provideSession().getPeerCertificates();
+    }
+
+    @Override
+    public Certificate[] getLocalCertificates() {
+        return provider.provideSession().getLocalCertificates();
+    }
+
+    @Override
+    public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
+        return provider.provideSession().getPeerCertificateChain();
+    }
+
+    @Override
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        return provider.provideSession().getPeerPrincipal();
+    }
+
+    @Override
+    public Principal getLocalPrincipal() {
+        return provider.provideSession().getLocalPrincipal();
+    }
+
+    @Override
+    public String getCipherSuite() {
+        return provider.provideSession().getCipherSuite();
+    }
+
+    @Override
+    public String getProtocol() {
+        return provider.provideSession().getProtocol();
+    }
+
+    @Override
+    public String getPeerHost() {
+        return provider.provideSession().getPeerHost();
+    }
+
+    @Override
+    public int getPeerPort() {
+        return provider.provideSession().getPeerPort();
+    }
+
+    @Override
+    public int getPacketBufferSize() {
+        return provider.provideSession().getPacketBufferSize();
+    }
+
+    @Override
+    public int getApplicationBufferSize() {
+        return provider.provideSession().getApplicationBufferSize();
+    }
+
+    @Override
+    public Object getValue(String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("name == null");
+        }
+        return values.get(name);
+    }
+
+    @Override
+    public String[] getValueNames() {
+        return values.keySet().toArray(new String[values.size()]);
+    }
+
+    @Override
+    public void putValue(String name, Object value) {
+        putValue(this, name, value);
+    }
+
+    void putValue(SSLSession session, String name, Object value) {
+        if (name == null || value == null) {
+            throw new IllegalArgumentException("name == null || value == null");
+        }
+        Object old = values.put(name, value);
+        if (value instanceof SSLSessionBindingListener) {
+            ((SSLSessionBindingListener) value)
+                    .valueBound(new SSLSessionBindingEvent(session, name));
+        }
+        if (old instanceof SSLSessionBindingListener) {
+            ((SSLSessionBindingListener) old)
+                    .valueUnbound(new SSLSessionBindingEvent(session, name));
+        }
+    }
+
+    @Override
+    public void removeValue(String name) {
+        removeValue(this, name);
+    }
+
+    void removeValue(SSLSession session, String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("name == null");
+        }
+        Object old = values.remove(name);
+        if (old instanceof SSLSessionBindingListener) {
+            SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
+            listener.valueUnbound(new SSLSessionBindingEvent(session, name));
+        }
+    }
+
+    /**
+     * The provider of the current delegate session.
+     */
+    interface Provider {
+        ConscryptSession provideSession();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/FileClientSessionCache.java b/repackaged/common/src/main/java/com/android/org/conscrypt/FileClientSessionCache.java
new file mode 100644
index 0000000..2526cfe
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/FileClientSessionCache.java
@@ -0,0 +1,386 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.net.ssl.SSLSession;
+
+/**
+ * File-based cache implementation. Only one process should access the
+ * underlying directory at a time.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public final class FileClientSessionCache {
+    private static final Logger logger = Logger.getLogger(FileClientSessionCache.class.getName());
+
+    public static final int MAX_SIZE = 12; // ~72k
+
+    private FileClientSessionCache() {}
+
+    /**
+     * This cache creates one file per SSL session using "host.port" for
+     * the file name. Files are created or replaced when session data is put
+     * in the cache (see {@link #putSessionData}). Files are read on
+     * cache hits, but not on cache misses.
+     *
+     * <p>When the number of session files exceeds MAX_SIZE, we delete the
+     * least-recently-used file. We don't current persist the last access time,
+     * so the ordering actually ends up being least-recently-modified in some
+     * cases and even just "not accessed in this process" if the filesystem
+     * doesn't track last modified times.
+     */
+    static class Impl implements SSLClientSessionCache {
+        /** Directory to store session files in. */
+        final File directory;
+
+        /**
+         * Map of name -> File. Keeps track of the order files were accessed in.
+         */
+        Map<String, File> accessOrder = newAccessOrder();
+
+        /** The number of files on disk. */
+        int size;
+
+        /**
+         * The initial set of files. We use this to defer adding information
+         * about all files to accessOrder until necessary.
+         */
+        String[] initialFiles;
+
+        /**
+         * Constructs a new cache backed by the given directory.
+         */
+        Impl(File directory) throws IOException {
+            boolean exists = directory.exists();
+            if (exists && !directory.isDirectory()) {
+                throw new IOException(directory + " exists but is not a directory.");
+            }
+
+            if (exists) {
+                // Read and sort initial list of files. We defer adding
+                // information about these files to accessOrder until necessary
+                // (see indexFiles()). Sorting the list enables us to detect
+                // cache misses in getSessionData().
+                // Note: Sorting an array here was faster than creating a
+                // HashSet on Dalvik.
+                initialFiles = directory.list();
+                if (initialFiles == null) {
+                    // File.list() will return null in error cases without throwing IOException
+                    // http://b/3363561
+                    throw new IOException(directory + " exists but cannot list contents.");
+                }
+                Arrays.sort(initialFiles);
+                size = initialFiles.length;
+            } else {
+                // Create directory.
+                if (!directory.mkdirs()) {
+                    throw new IOException("Creation of " + directory + " directory failed.");
+                }
+                size = 0;
+            }
+
+            this.directory = directory;
+        }
+
+        /**
+         * Creates a new access-ordered linked hash map.
+         */
+        private static Map<String, File> newAccessOrder() {
+            return new LinkedHashMap<String, File>(MAX_SIZE, 0.75f, true /* access order */);
+        }
+
+        /**
+         * Gets the file name for the given host and port.
+         */
+        private static String fileName(String host, int port) {
+            if (host == null) {
+                throw new NullPointerException("host == null");
+            }
+            return host + "." + port;
+        }
+
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        @Override
+        public synchronized byte[] getSessionData(String host, int port) {
+            /*
+             * Note: This method is only called when the in-memory cache
+             * in SSLSessionContext misses, so it would be unnecessarily
+             * redundant for this cache to store data in memory.
+             */
+
+            String name = fileName(host, port);
+            File file = accessOrder.get(name);
+
+            if (file == null) {
+                // File wasn't in access order. Check initialFiles...
+                if (initialFiles == null) {
+                    // All files are in accessOrder, so it doesn't exist.
+                    return null;
+                }
+
+                // Look in initialFiles.
+                if (Arrays.binarySearch(initialFiles, name) < 0) {
+                    // Not found.
+                    return null;
+                }
+
+                // The file is on disk but not in accessOrder yet.
+                file = new File(directory, name);
+                accessOrder.put(name, file);
+            }
+
+            FileInputStream in;
+            try {
+                in = new FileInputStream(file);
+            } catch (FileNotFoundException e) {
+                logReadError(host, file, e);
+                return null;
+            }
+            try {
+                int size = (int) file.length();
+                byte[] data = new byte[size];
+                new DataInputStream(in).readFully(data);
+                return data;
+            } catch (IOException e) {
+                logReadError(host, file, e);
+                return null;
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (Exception ignored) {
+                    }
+                }
+            }
+        }
+
+        static void logReadError(String host, File file, Throwable t) {
+            logger.log(Level.WARNING,
+                    "FileClientSessionCache: Error reading session data for " + host + " from "
+                            + file + ".",
+                    t);
+        }
+
+        @Override
+        public synchronized void putSessionData(SSLSession session, byte[] sessionData) {
+            String host = session.getPeerHost();
+            if (sessionData == null) {
+                throw new NullPointerException("sessionData == null");
+            }
+
+            String name = fileName(host, session.getPeerPort());
+            File file = new File(directory, name);
+
+            // Used to keep track of whether or not we're expanding the cache.
+            boolean existedBefore = file.exists();
+
+            FileOutputStream out;
+            try {
+                out = new FileOutputStream(file);
+            } catch (FileNotFoundException e) {
+                // We can't write to the file.
+                logWriteError(host, file, e);
+                return;
+            }
+
+            // If we expanded the cache (by creating a new file)...
+            if (!existedBefore) {
+                size++;
+
+                // Delete an old file if necessary.
+                makeRoom();
+            }
+
+            boolean writeSuccessful = false;
+            try {
+                out.write(sessionData);
+                writeSuccessful = true;
+            } catch (IOException e) {
+                logWriteError(host, file, e);
+            } finally {
+                boolean closeSuccessful = false;
+                try {
+                    out.close();
+                    closeSuccessful = true;
+                } catch (IOException e) {
+                    logWriteError(host, file, e);
+                } finally {
+                    if (!writeSuccessful || !closeSuccessful) {
+                        // Storage failed. Clean up.
+                        delete(file);
+                    } else {
+                        // Success!
+                        accessOrder.put(name, file);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Deletes old files if necessary.
+         */
+        private void makeRoom() {
+            if (size <= MAX_SIZE) {
+                return;
+            }
+
+            indexFiles();
+
+            // Delete LRUed files.
+            int removals = size - MAX_SIZE;
+            Iterator<File> i = accessOrder.values().iterator();
+            do {
+                delete(i.next());
+                i.remove();
+            } while (--removals > 0);
+        }
+
+        /**
+         * Lazily updates accessOrder to know about all files as opposed to
+         * just the files accessed since this process started.
+         */
+        private void indexFiles() {
+            String[] initialFiles = this.initialFiles;
+            if (initialFiles != null) {
+                this.initialFiles = null;
+
+                // Files on disk only, sorted by last modified time.
+                // TODO: Use last access time.
+                Set<CacheFile> diskOnly = new TreeSet<CacheFile>();
+                for (String name : initialFiles) {
+                    // If the file hasn't been accessed in this process...
+                    if (!accessOrder.containsKey(name)) {
+                        diskOnly.add(new CacheFile(directory, name));
+                    }
+                }
+
+                if (!diskOnly.isEmpty()) {
+                    // Add files not accessed in this process to the beginning
+                    // of accessOrder.
+                    Map<String, File> newOrder = newAccessOrder();
+                    for (CacheFile cacheFile : diskOnly) {
+                        newOrder.put(cacheFile.name, cacheFile);
+                    }
+                    newOrder.putAll(accessOrder);
+
+                    this.accessOrder = newOrder;
+                }
+            }
+        }
+
+        @SuppressWarnings("ThrowableInstanceNeverThrown")
+        private void delete(File file) {
+            if (!file.delete()) {
+                Exception e =
+                        new IOException("FileClientSessionCache: Failed to delete " + file + ".");
+                logger.log(Level.WARNING, e.getMessage(), e);
+            }
+            size--;
+        }
+
+        static void logWriteError(String host, File file, Throwable t) {
+            logger.log(Level.WARNING,
+                    "FileClientSessionCache: Error writing session data for " + host + " to " + file
+                            + ".",
+                    t);
+        }
+    }
+
+    /**
+     * Maps directories to the cache instances that are backed by those
+     * directories. We synchronize access using the cache instance, so it's
+     * important that everyone shares the same instance.
+     */
+    static final Map<File, FileClientSessionCache.Impl> caches =
+            new HashMap<File, FileClientSessionCache.Impl>();
+
+    /**
+     * Returns a cache backed by the given directory. Creates the directory
+     * (including parent directories) if necessary. This cache should have
+     * exclusive access to the given directory.
+     *
+     * @param directory to store files in
+     * @return a cache backed by the given directory
+     * @throws IOException if the file exists and is not a directory or if
+     *  creating the directories fails
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static synchronized SSLClientSessionCache usingDirectory(File directory)
+            throws IOException {
+        FileClientSessionCache.Impl cache = caches.get(directory);
+        if (cache == null) {
+            cache = new FileClientSessionCache.Impl(directory);
+            caches.put(directory, cache);
+        }
+        return cache;
+    }
+
+    /** For testing. */
+    static synchronized void reset() {
+        caches.clear();
+    }
+
+    /** A file containing a piece of cached data. */
+    @SuppressWarnings("serial")
+    static class CacheFile extends File {
+        final String name;
+
+        CacheFile(File dir, String name) {
+            super(dir, name);
+            this.name = name;
+        }
+
+        long lastModified = -1;
+
+        @Override
+        public long lastModified() {
+            long lastModified = this.lastModified;
+            if (lastModified == -1) {
+                lastModified = this.lastModified = super.lastModified();
+            }
+            return lastModified;
+        }
+
+        @Override
+        public int compareTo(File another) {
+            // Sort by last modified time.
+            long result = lastModified() - another.lastModified();
+            if (result == 0) {
+                return super.compareTo(another);
+            }
+            return result < 0 ? -1 : 1;
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/GCMParameters.java b/repackaged/common/src/main/java/com/android/org/conscrypt/GCMParameters.java
new file mode 100644
index 0000000..d6fd56a
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/GCMParameters.java
@@ -0,0 +1,156 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2015 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * GCM parameters used during an ciphering operation with {@link OpenSSLCipher}.
+ * This class is used internally for backward compatibility with Android versions
+ * that did not have the {@code GCMParameterSpec} class, in addition to being the
+ * implementation of the GCM AlgorithmParameters implementation.
+ * <p>
+ * The only supported encoding format is ASN.1, as specified in RFC 5084 section 3.2.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class GCMParameters extends AlgorithmParametersSpi {
+
+    // The default value (in bits) for TLEN in the GCM ASN.1 module
+    private static final int DEFAULT_TLEN = 96;
+
+    /** The tag length in bits. */
+    private int tLen;
+
+    /** Actually the nonce value for the GCM operation. */
+    private byte[] iv;
+
+    @libcore.api.IntraCoreApi
+    public GCMParameters() { }
+
+    GCMParameters(int tLen, byte[] iv) {
+        this.tLen = tLen;
+        this.iv = iv;
+    }
+
+    /**
+     * Returns the tag length in bits.
+     */
+    int getTLen() {
+        return tLen;
+    }
+
+    /**
+     * Returns a non-cloned version of the IV.
+     */
+    byte[] getIV() {
+        return iv;
+    }
+
+    @Override
+    protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+            throws InvalidParameterSpecException {
+        GCMParameters params = Platform.fromGCMParameterSpec(algorithmParameterSpec);
+        if (params == null) {
+            throw new InvalidParameterSpecException("Only GCMParameterSpec is supported");
+        }
+        this.tLen = params.tLen;
+        this.iv = params.iv;
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes) throws IOException {
+        long readRef = 0;
+        long seqRef = 0;
+        try {
+            readRef = NativeCrypto.asn1_read_init(bytes);
+            seqRef = NativeCrypto.asn1_read_sequence(readRef);
+            byte[] newIv = NativeCrypto.asn1_read_octetstring(seqRef);
+            int newTlen = DEFAULT_TLEN;
+            if (!NativeCrypto.asn1_read_is_empty(seqRef)) {
+                newTlen = 8 * (int) NativeCrypto.asn1_read_uint64(seqRef);
+            }
+            if (!NativeCrypto.asn1_read_is_empty(seqRef)
+                    || !NativeCrypto.asn1_read_is_empty(readRef)) {
+                throw new IOException("Error reading ASN.1 encoding");
+            }
+            this.iv = newIv;
+            this.tLen = newTlen;
+        } finally {
+            NativeCrypto.asn1_read_free(seqRef);
+            NativeCrypto.asn1_read_free(readRef);
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes, String format) throws IOException {
+        if ((format == null) || format.equals("ASN.1")) {
+            engineInit(bytes);
+        } else {
+            throw new IOException("Unsupported format: " + format);
+        }
+    }
+
+    @Override
+    protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> aClass)
+            throws InvalidParameterSpecException {
+        if ((aClass != null) && aClass.getName().equals("javax.crypto.spec.GCMParameterSpec")) {
+            return aClass.cast(Platform.toGCMParameterSpec(tLen, iv));
+        } else {
+            throw new InvalidParameterSpecException("Unsupported class: " + aClass);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded() throws IOException {
+        long cbbRef = 0;
+        long seqRef = 0;
+        try {
+            cbbRef = NativeCrypto.asn1_write_init();
+            seqRef = NativeCrypto.asn1_write_sequence(cbbRef);
+            NativeCrypto.asn1_write_octetstring(seqRef, this.iv);
+            if (this.tLen != DEFAULT_TLEN) {
+                NativeCrypto.asn1_write_uint64(seqRef, this.tLen / 8);
+            }
+            return NativeCrypto.asn1_write_finish(cbbRef);
+        } catch (IOException e) {
+            NativeCrypto.asn1_write_cleanup(cbbRef);
+            throw e;
+        } finally {
+            NativeCrypto.asn1_write_free(seqRef);
+            NativeCrypto.asn1_write_free(cbbRef);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded(String format) throws IOException {
+        if ((format == null) || format.equals("ASN.1")) {
+            return engineGetEncoded();
+        }
+        throw new IOException("Unsupported format: " + format);
+    }
+
+    @Override
+    protected String engineToString() {
+        return "Conscrypt GCM AlgorithmParameters";
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/HandshakeListener.java b/repackaged/common/src/main/java/com/android/org/conscrypt/HandshakeListener.java
new file mode 100644
index 0000000..72d7767
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/HandshakeListener.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import javax.net.ssl.SSLException;
+
+/**
+ * Similar in concept to {@link javax.net.ssl.HandshakeCompletedListener}, but used for listening directly
+ * to the engine. Allows the caller to be notified immediately upon completion of the TLS handshake.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class HandshakeListener {
+
+    /**
+     * Called by the engine when the TLS handshake has completed.
+     */
+    public abstract void onHandshakeFinished() throws SSLException;
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Internal.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Internal.java
new file mode 100644
index 0000000..febeda2
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Internal.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates a program element (class, method, package etc) which is internal to Conscrypt, not part
+ * of
+ * the public API, and should not be used by users of Conscrypt.
+ */
+@Internal
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
+        ElementType.METHOD, ElementType.PACKAGE, ElementType.TYPE})
+@Documented
+public @interface Internal {}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/IvParameters.java b/repackaged/common/src/main/java/com/android/org/conscrypt/IvParameters.java
new file mode 100644
index 0000000..7c8f8dc
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/IvParameters.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * An implementation of {@link java.security.AlgorithmParameters} that contains only an IV.  The
+ * supported encoding formats are ASN.1 (primary) and RAW.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class IvParameters extends AlgorithmParametersSpi {
+    private byte[] iv;
+
+    @libcore.api.IntraCoreApi
+    public IvParameters() {}
+
+    @Override
+    protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+            throws InvalidParameterSpecException {
+        if (!(algorithmParameterSpec instanceof IvParameterSpec)) {
+            throw new InvalidParameterSpecException("Only IvParameterSpec is supported");
+        }
+        iv = ((IvParameterSpec) algorithmParameterSpec).getIV().clone();
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes) throws IOException {
+        long readRef = 0;
+        try {
+            readRef = NativeCrypto.asn1_read_init(bytes);
+            byte[] newIv = NativeCrypto.asn1_read_octetstring(readRef);
+            if (!NativeCrypto.asn1_read_is_empty(readRef)) {
+                throw new IOException("Error reading ASN.1 encoding");
+            }
+            this.iv = newIv;
+        } finally {
+            NativeCrypto.asn1_read_free(readRef);
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes, String format) throws IOException {
+        if (format == null || format.equals("ASN.1")) {
+            engineInit(bytes);
+        } else if (format.equals("RAW")) {
+            iv = bytes.clone();
+        } else {
+            throw new IOException("Unsupported format: " + format);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> aClass)
+            throws InvalidParameterSpecException {
+        if (aClass != IvParameterSpec.class) {
+            throw new InvalidParameterSpecException(
+                    "Incompatible AlgorithmParametersSpec class: " + aClass);
+        }
+        return (T) new IvParameterSpec(iv);
+    }
+
+    @Override
+    protected byte[] engineGetEncoded() throws IOException {
+        long cbbRef = 0;
+        try {
+            cbbRef = NativeCrypto.asn1_write_init();
+            NativeCrypto.asn1_write_octetstring(cbbRef, this.iv);
+            return NativeCrypto.asn1_write_finish(cbbRef);
+        } catch (IOException e) {
+            NativeCrypto.asn1_write_cleanup(cbbRef);
+            throw e;
+        } finally {
+            NativeCrypto.asn1_write_free(cbbRef);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded(String format) throws IOException {
+        if (format == null || format.equals("ASN.1")) {
+            return engineGetEncoded();
+        } else if (format.equals("RAW")) {
+            return iv.clone();
+        } else {
+            throw new IOException("Unsupported format: " + format);
+        }
+    }
+
+    @Override
+    protected String engineToString() {
+        return "Conscrypt IV AlgorithmParameters";
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class AES extends IvParameters {
+        @libcore.api.IntraCoreApi
+        public AES() {}
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class DESEDE extends IvParameters {
+        @libcore.api.IntraCoreApi
+        public DESEDE() {}
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class ChaCha20 extends IvParameters {
+        @libcore.api.IntraCoreApi
+        public ChaCha20() {}
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Java7ExtendedSSLSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Java7ExtendedSSLSession.java
new file mode 100644
index 0000000..4544eb2
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Java7ExtendedSSLSession.java
@@ -0,0 +1,181 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.List;
+import javax.net.ssl.ExtendedSSLSession;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.X509Certificate;
+
+/**
+ * This is an adapter that wraps the active session with {@link ExtendedSSLSession}, if running
+ * on Java 7+.
+ */
+class Java7ExtendedSSLSession extends ExtendedSSLSession implements ConscryptSession {
+    // TODO: use BoringSSL API to actually fetch the real data
+    private static final String[] LOCAL_SUPPORTED_SIGNATURE_ALGORITHMS = new String[] {
+            "SHA512withRSA", "SHA512withECDSA", "SHA384withRSA", "SHA384withECDSA", "SHA256withRSA",
+            "SHA256withECDSA", "SHA224withRSA", "SHA224withECDSA", "SHA1withRSA", "SHA1withECDSA",
+    };
+    // TODO: use BoringSSL API to actually fetch the real data
+    private static final String[] PEER_SUPPORTED_SIGNATURE_ALGORITHMS =
+            new String[] {"SHA1withRSA", "SHA1withECDSA"};
+    protected final ExternalSession delegate;
+
+    Java7ExtendedSSLSession(ExternalSession delegate) {
+        this.delegate = delegate;
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For Android backward-compatibility.
+    public final String[] getLocalSupportedSignatureAlgorithms() {
+        return LOCAL_SUPPORTED_SIGNATURE_ALGORITHMS.clone();
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For Android backward-compatibility.
+    public final String[] getPeerSupportedSignatureAlgorithms() {
+        return PEER_SUPPORTED_SIGNATURE_ALGORITHMS.clone();
+    }
+
+    @Override
+    public final String getRequestedServerName() {
+        return delegate.getRequestedServerName();
+    }
+
+    /**
+     * Provides forward-compatibility with Java 9.
+     */
+    @Override
+    public final List<byte[]> getStatusResponses() {
+        return delegate.getStatusResponses();
+    }
+
+    @Override
+    public final byte[] getPeerSignedCertificateTimestamp() {
+        return delegate.getPeerSignedCertificateTimestamp();
+    }
+
+    @Override
+    public final byte[] getId() {
+        return delegate.getId();
+    }
+
+    @Override
+    public final SSLSessionContext getSessionContext() {
+        return delegate.getSessionContext();
+    }
+
+    @Override
+    public final long getCreationTime() {
+        return delegate.getCreationTime();
+    }
+
+    @Override
+    public final long getLastAccessedTime() {
+        return delegate.getLastAccessedTime();
+    }
+
+    @Override
+    public final void invalidate() {
+        delegate.invalidate();
+    }
+
+    @Override
+    public final boolean isValid() {
+        return delegate.isValid();
+    }
+
+    @Override
+    public final void putValue(String s, Object o) {
+        delegate.putValue(this, s, o);
+    }
+
+    @Override
+    public final Object getValue(String s) {
+        return delegate.getValue(s);
+    }
+
+    @Override
+    public final void removeValue(String s) {
+        delegate.removeValue(this, s);
+    }
+
+    @Override
+    public final String[] getValueNames() {
+        return delegate.getValueNames();
+    }
+
+    @Override
+    public java.security.cert.X509Certificate[] getPeerCertificates()
+        throws SSLPeerUnverifiedException {
+        return delegate.getPeerCertificates();
+    }
+
+    @Override
+    public final Certificate[] getLocalCertificates() {
+        return delegate.getLocalCertificates();
+    }
+
+    @Override
+    public final X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
+        return delegate.getPeerCertificateChain();
+    }
+
+    @Override
+    public final Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        return delegate.getPeerPrincipal();
+    }
+
+    @Override
+    public final Principal getLocalPrincipal() {
+        return delegate.getLocalPrincipal();
+    }
+
+    @Override
+    public final String getCipherSuite() {
+        return delegate.getCipherSuite();
+    }
+
+    @Override
+    public final String getProtocol() {
+        return delegate.getProtocol();
+    }
+
+    @Override
+    public final String getPeerHost() {
+        return delegate.getPeerHost();
+    }
+
+    @Override
+    public final int getPeerPort() {
+        return delegate.getPeerPort();
+    }
+
+    @Override
+    public final int getPacketBufferSize() {
+        return delegate.getPacketBufferSize();
+    }
+
+    @Override
+    public final int getApplicationBufferSize() {
+        return delegate.getApplicationBufferSize();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Java8EngineSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8EngineSocket.java
new file mode 100644
index 0000000..b1c852b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8EngineSocket.java
@@ -0,0 +1,93 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.List;
+import java.util.function.BiFunction;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * A version of ConscryptEngineSocket that includes the new Java 9 (and potentially later
+ * patches of 8) {@code setHandshakeApplicationProtocolSelector} API (which requires Java 8 for
+ * compilation, due to the use of {@link BiFunction}).
+ */
+final class Java8EngineSocket extends ConscryptEngineSocket {
+    private BiFunction<SSLSocket, List<String>, String> selector;
+
+    Java8EngineSocket(SSLParametersImpl sslParameters) throws IOException {
+        super(sslParameters);
+    }
+
+    Java8EngineSocket(String hostname, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(hostname, port, sslParameters);
+    }
+
+    Java8EngineSocket(InetAddress address, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(address, port, sslParameters);
+    }
+
+    Java8EngineSocket(String hostname, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(hostname, port, clientAddress, clientPort, sslParameters);
+    }
+
+    Java8EngineSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(address, port, clientAddress, clientPort, sslParameters);
+    }
+
+    Java8EngineSocket(Socket socket, String hostname, int port, boolean autoClose,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(socket, hostname, port, autoClose, sslParameters);
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java < 9.
+    public void setHandshakeApplicationProtocolSelector(
+            final BiFunction<SSLSocket, List<String>, String> selector) {
+        this.selector = selector;
+        setApplicationProtocolSelector(toApplicationProtocolSelector(selector));
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java < 9.
+    public BiFunction<SSLSocket, List<String>, String> getHandshakeApplicationProtocolSelector() {
+        return selector;
+    }
+
+    private static ApplicationProtocolSelector toApplicationProtocolSelector(
+        final BiFunction<SSLSocket, List<String>, String> selector) {
+        return selector == null ? null : new ApplicationProtocolSelector() {
+            @Override
+            public String selectApplicationProtocol(SSLEngine socket, List<String> protocols) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public String selectApplicationProtocol(SSLSocket socket, List<String> protocols) {
+                return selector.apply(socket, protocols);
+            }
+        };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Java8EngineWrapper.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8EngineWrapper.java
new file mode 100644
index 0000000..6462219
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8EngineWrapper.java
@@ -0,0 +1,342 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Preconditions.checkNotNull;
+
+import java.nio.ByteBuffer;
+import java.security.PrivateKey;
+import java.util.List;
+import java.util.function.BiFunction;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * A wrapper around {@link ConscryptEngine} that adapts to the new Java 9 (and potentially later
+ * patches of 8) {@code setHandshakeApplicationProtocolSelector} API (which requires Java 8 for
+ * compilation, due to the use of {@link BiFunction}).
+ */
+final class Java8EngineWrapper extends AbstractConscryptEngine {
+    private final ConscryptEngine delegate;
+    private BiFunction<SSLEngine, List<String>, String> selector;
+
+    Java8EngineWrapper(ConscryptEngine delegate) {
+        this.delegate = checkNotNull(delegate, "delegate");
+    }
+
+    static SSLEngine getDelegate(SSLEngine engine) {
+        if (engine instanceof Java8EngineWrapper) {
+            return ((Java8EngineWrapper) engine).delegate;
+        }
+        return engine;
+    }
+
+    @Override
+    public SSLEngineResult wrap(ByteBuffer[] byteBuffers, ByteBuffer byteBuffer)
+            throws SSLException {
+        return delegate.wrap(byteBuffers, byteBuffer);
+    }
+
+    @Override
+    public SSLParameters getSSLParameters() {
+        return delegate.getSSLParameters();
+    }
+
+    @Override
+    public void setSSLParameters(SSLParameters sslParameters) {
+        delegate.setSSLParameters(sslParameters);
+    }
+
+    @Override
+    void setBufferAllocator(BufferAllocator bufferAllocator) {
+        delegate.setBufferAllocator(bufferAllocator);
+    }
+
+    @Override
+    int maxSealOverhead() {
+        return delegate.maxSealOverhead();
+    }
+
+    @Override
+    void setChannelIdEnabled(boolean enabled) {
+        delegate.setChannelIdEnabled(enabled);
+    }
+
+    @Override
+    byte[] getChannelId() throws SSLException {
+        return delegate.getChannelId();
+    }
+
+    @Override
+    void setChannelIdPrivateKey(PrivateKey privateKey) {
+        delegate.setChannelIdPrivateKey(privateKey);
+    }
+
+    @Override
+    void setHandshakeListener(HandshakeListener handshakeListener) {
+        delegate.setHandshakeListener(handshakeListener);
+    }
+
+    @Override
+    void setHostname(String hostname) {
+        delegate.setHostname(hostname);
+    }
+
+    @Override
+    String getHostname() {
+        return delegate.getHostname();
+    }
+
+    @Override
+    public String getPeerHost() {
+        return delegate.getPeerHost();
+    }
+
+    @Override
+    public int getPeerPort() {
+        return delegate.getPeerPort();
+    }
+
+    @Override
+    public void beginHandshake() throws SSLException {
+        delegate.beginHandshake();
+    }
+
+    @Override
+    public void closeInbound() throws SSLException {
+        delegate.closeInbound();
+    }
+
+    @Override
+    public void closeOutbound() {
+        delegate.closeOutbound();
+    }
+
+    @Override
+    public Runnable getDelegatedTask() {
+        return delegate.getDelegatedTask();
+    }
+
+    @Override
+    public String[] getEnabledCipherSuites() {
+        return delegate.getEnabledCipherSuites();
+    }
+
+    @Override
+    public String[] getEnabledProtocols() {
+        return delegate.getEnabledProtocols();
+    }
+
+    @Override
+    public boolean getEnableSessionCreation() {
+        return delegate.getEnableSessionCreation();
+    }
+
+    @Override
+    public HandshakeStatus getHandshakeStatus() {
+        return delegate.getHandshakeStatus();
+    }
+
+    @Override
+    public boolean getNeedClientAuth() {
+        return delegate.getNeedClientAuth();
+    }
+
+    @Override
+    SSLSession handshakeSession() {
+        return delegate.handshakeSession();
+    }
+
+    @Override
+    public SSLSession getSession() {
+        return delegate.getSession();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return delegate.getSupportedCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedProtocols() {
+        return delegate.getSupportedProtocols();
+    }
+
+    @Override
+    public boolean getUseClientMode() {
+        return delegate.getUseClientMode();
+    }
+
+    @Override
+    public boolean getWantClientAuth() {
+        return delegate.getWantClientAuth();
+    }
+
+    @Override
+    public boolean isInboundDone() {
+        return delegate.isInboundDone();
+    }
+
+    @Override
+    public boolean isOutboundDone() {
+        return delegate.isOutboundDone();
+    }
+
+    @Override
+    public void setEnabledCipherSuites(String[] suites) {
+        delegate.setEnabledCipherSuites(suites);
+    }
+
+    @Override
+    public void setEnabledProtocols(String[] protocols) {
+        delegate.setEnabledProtocols(protocols);
+    }
+
+    @Override
+    public void setEnableSessionCreation(boolean flag) {
+        delegate.setEnableSessionCreation(flag);
+    }
+
+    @Override
+    public void setNeedClientAuth(boolean need) {
+        delegate.setNeedClientAuth(need);
+    }
+
+    @Override
+    public void setUseClientMode(boolean mode) {
+        delegate.setUseClientMode(mode);
+    }
+
+    @Override
+    public void setWantClientAuth(boolean want) {
+        delegate.setWantClientAuth(want);
+    }
+
+    @Override
+    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        return delegate.unwrap(src, dst);
+    }
+
+    @Override
+    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException {
+        return delegate.unwrap(src, dsts);
+    }
+
+    @Override
+    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length)
+            throws SSLException {
+        return delegate.unwrap(src, dsts, offset, length);
+    }
+
+    @Override
+    SSLEngineResult unwrap(ByteBuffer[] srcs, ByteBuffer[] dsts) throws SSLException {
+        return delegate.unwrap(srcs, dsts);
+    }
+
+    @Override
+    SSLEngineResult unwrap(ByteBuffer[] srcs, int srcsOffset, int srcsLength, ByteBuffer[] dsts,
+            int dstsOffset, int dstsLength) throws SSLException {
+        return delegate.unwrap(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
+    }
+
+    @Override
+    public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
+        return delegate.wrap(src, dst);
+    }
+
+    @Override
+    public SSLEngineResult wrap(ByteBuffer[] srcs, int srcsOffset, int srcsLength, ByteBuffer dst)
+            throws SSLException {
+        return delegate.wrap(srcs, srcsOffset, srcsLength, dst);
+    }
+
+    @Override
+    void setUseSessionTickets(boolean useSessionTickets) {
+        delegate.setUseSessionTickets(useSessionTickets);
+    }
+
+    @Override
+    void setApplicationProtocols(String[] protocols) {
+        delegate.setApplicationProtocols(protocols);
+    }
+
+    @Override
+    String[] getApplicationProtocols() {
+        return delegate.getApplicationProtocols();
+    }
+
+    @Override
+    public String getApplicationProtocol() {
+        return delegate.getApplicationProtocol();
+    }
+
+    @Override
+    void setApplicationProtocolSelector(ApplicationProtocolSelector selector) {
+        delegate.setApplicationProtocolSelector(
+                selector == null ? null : new ApplicationProtocolSelectorAdapter(this, selector));
+    }
+
+    @Override
+    byte[] getTlsUnique() {
+        return delegate.getTlsUnique();
+    }
+
+    @Override
+    byte[] exportKeyingMaterial(String label, byte[] context, int length) throws SSLException {
+        return delegate.exportKeyingMaterial(label, context, length);
+    }
+
+    @Override
+    public String getHandshakeApplicationProtocol() {
+        return delegate.getHandshakeApplicationProtocol();
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java < 9.
+    public void setHandshakeApplicationProtocolSelector(
+            final BiFunction<SSLEngine, List<String>, String> selector) {
+        this.selector = selector;
+        setApplicationProtocolSelector(toApplicationProtocolSelector(selector));
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java < 9.
+    public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() {
+        return selector;
+    }
+
+    private static ApplicationProtocolSelector toApplicationProtocolSelector(
+            final BiFunction<SSLEngine, List<String>, String> selector) {
+        return selector == null ? null : new ApplicationProtocolSelector() {
+            @Override
+            public String selectApplicationProtocol(SSLEngine engine, List<String> protocols) {
+                return selector.apply(engine, protocols);
+            }
+
+            @Override
+            public String selectApplicationProtocol(SSLSocket socket, List<String> protocols) {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Java8ExtendedSSLSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8ExtendedSSLSession.java
new file mode 100644
index 0000000..16c4c38
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8ExtendedSSLSession.java
@@ -0,0 +1,44 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.ExtendedSSLSession;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+
+/**
+ * This is an adapter that wraps the active session with {@link ExtendedSSLSession}, if running
+ * on Java 8+.
+ */
+class Java8ExtendedSSLSession extends Java7ExtendedSSLSession {
+    public Java8ExtendedSSLSession(ExternalSession delegate) {
+        super(delegate);
+    }
+
+  @Override
+  public final List<SNIServerName> getRequestedServerNames() {
+      String requestedServerName = delegate.getRequestedServerName();
+      if (requestedServerName == null) {
+        return null;
+      }
+
+      return Collections.singletonList((SNIServerName) new SNIHostName(requestedServerName));
+  }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Java8FileDescriptorSocket.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8FileDescriptorSocket.java
new file mode 100644
index 0000000..2d9f3bc
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Java8FileDescriptorSocket.java
@@ -0,0 +1,93 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.List;
+import java.util.function.BiFunction;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * A version of ConscryptFileDescriptorSocket that includes the new Java 9 (and potentially later
+ * patches of 8) {@code setHandshakeApplicationProtocolSelector} API (which requires Java 8 for
+ * compilation, due to the use of {@link BiFunction}).
+ */
+final class Java8FileDescriptorSocket extends ConscryptFileDescriptorSocket {
+    private BiFunction<SSLSocket, List<String>, String> selector;
+
+    Java8FileDescriptorSocket(SSLParametersImpl sslParameters) throws IOException {
+        super(sslParameters);
+    }
+
+    Java8FileDescriptorSocket(String hostname, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(hostname, port, sslParameters);
+    }
+
+    Java8FileDescriptorSocket(InetAddress address, int port, SSLParametersImpl sslParameters)
+            throws IOException {
+        super(address, port, sslParameters);
+    }
+
+    Java8FileDescriptorSocket(String hostname, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(hostname, port, clientAddress, clientPort, sslParameters);
+    }
+
+    Java8FileDescriptorSocket(InetAddress address, int port, InetAddress clientAddress, int clientPort,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(address, port, clientAddress, clientPort, sslParameters);
+    }
+
+    Java8FileDescriptorSocket(Socket socket, String hostname, int port, boolean autoClose,
+            SSLParametersImpl sslParameters) throws IOException {
+        super(socket, hostname, port, autoClose, sslParameters);
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java < 9.
+    public void setHandshakeApplicationProtocolSelector(
+            final BiFunction<SSLSocket, List<String>, String> selector) {
+        this.selector = selector;
+        setApplicationProtocolSelector(toApplicationProtocolSelector(selector));
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride") // For compilation with Java < 9.
+    public BiFunction<SSLSocket, List<String>, String> getHandshakeApplicationProtocolSelector() {
+        return selector;
+    }
+
+    private static ApplicationProtocolSelector toApplicationProtocolSelector(
+        final BiFunction<SSLSocket, List<String>, String> selector) {
+        return selector == null ? null : new ApplicationProtocolSelector() {
+            @Override
+            public String selectApplicationProtocol(SSLEngine socket, List<String> protocols) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public String selectApplicationProtocol(SSLSocket socket, List<String> protocols) {
+                return selector.apply(socket, protocols);
+            }
+        };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/KeyGeneratorImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/KeyGeneratorImpl.java
new file mode 100644
index 0000000..c1fc87d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/KeyGeneratorImpl.java
@@ -0,0 +1,245 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyGeneratorSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * An implementation of {@link javax.crypto.KeyGenerator} suitable for use with other Conscrypt
+ * algorithms.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class KeyGeneratorImpl extends KeyGeneratorSpi {
+    private final String algorithm;
+    protected SecureRandom secureRandom;
+    private int keySizeBits;
+
+    private KeyGeneratorImpl(String algorithm, int defaultKeySizeBits) {
+        this.algorithm = algorithm;
+        this.keySizeBits = defaultKeySizeBits;
+    }
+
+    protected void checkKeySize(int keySize) {
+        if (keySize <= 0) {
+            throw new InvalidParameterException("Key size must be positive");
+        }
+    }
+
+    @Override
+    protected void engineInit(SecureRandom secureRandom) {
+        this.secureRandom = secureRandom;
+    }
+
+    @Override
+    protected void engineInit(AlgorithmParameterSpec params, SecureRandom secureRandom)
+            throws InvalidAlgorithmParameterException {
+        if (params == null) {
+            throw new InvalidAlgorithmParameterException("No params provided");
+        } else {
+            throw new InvalidAlgorithmParameterException(
+                    "Unknown param type: " + params.getClass().getName());
+        }
+    }
+
+    @Override
+    protected void engineInit(int keySize, SecureRandom secureRandom) {
+        checkKeySize(keySize);
+        this.keySizeBits = keySize;
+        this.secureRandom = secureRandom;
+    }
+
+    protected byte[] doKeyGeneration(int keyBytes) {
+        byte[] keyData = new byte[keyBytes];
+        secureRandom.nextBytes(keyData);
+        return keyData;
+    }
+
+    @Override
+    protected SecretKey engineGenerateKey() {
+        if (secureRandom == null) {
+            secureRandom = new SecureRandom();
+        }
+
+        return new SecretKeySpec(doKeyGeneration((keySizeBits + 7) / 8), algorithm);
+    }
+
+    // For HMAC, RFC 2104 recommends using the hash's output length as the key length
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacMD5 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public HmacMD5() {
+            super("HmacMD5", 128);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA1 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public HmacSHA1() {
+            super("HmacSHA1", 160);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA224 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public HmacSHA224() {
+            super("HmacSHA224", 224);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA256 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public HmacSHA256() {
+            super("HmacSHA256", 256);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA384 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public HmacSHA384() {
+            super("HmacSHA384", 384);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA512 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public HmacSHA512() {
+            super("HmacSHA512", 512);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class DESEDE extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public DESEDE() {
+            super("DESEDE", 192);
+        }
+
+        @Override
+        protected void checkKeySize(int keySize) {
+            if ((keySize != 112) && (keySize != 168)) {
+                throw new InvalidParameterException("Key size must be either 112 or 168 bits");
+            }
+        }
+
+        @Override
+        protected byte[] doKeyGeneration(int keyBytes) {
+            byte[] keyData = new byte[DESedeKeySpec.DES_EDE_KEY_LEN];
+            secureRandom.nextBytes(keyData);
+            // Set the parity bit for each byte
+            for (int i = 0; i < keyData.length; i++) {
+                if (Integer.bitCount(keyData[i]) % 2 == 0) {
+                    keyData[i] = (byte) (keyData[i] ^ 1);
+                }
+            }
+            if (keyBytes == 14) {
+                // The user requested an A-B-A key
+                System.arraycopy(keyData, 0, keyData, 16, 8);
+            }
+            return keyData;
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class AES extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public AES() {
+            super("AES", 128);
+        }
+
+        @Override
+        protected void checkKeySize(int keySize) {
+            if ((keySize != 128) && (keySize != 192) && (keySize != 256)) {
+                throw new InvalidParameterException(
+                        "Key size must be either 128, 192, or 256 bits");
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class ChaCha20 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public ChaCha20() {
+            super("ChaCha20", 256);
+        }
+
+        @Override
+        protected void checkKeySize(int keySize) {
+            if (keySize != 256) {
+                throw new InvalidParameterException("Key size must be 256 bits");
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class ARC4 extends KeyGeneratorImpl {
+        @libcore.api.IntraCoreApi
+        public ARC4() {
+            super("ARC4", 128);
+        }
+
+        @Override
+        protected void checkKeySize(int keySize) {
+            if (keySize < 40 || 2048 < keySize) {
+                throw new InvalidParameterException("Key size must be between 40 and 2048 bits");
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/KeyManagerFactoryImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/KeyManagerFactoryImpl.java
new file mode 100644
index 0000000..5b02be2
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/KeyManagerFactoryImpl.java
@@ -0,0 +1,117 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.android.org.conscrypt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactorySpi;
+import javax.net.ssl.ManagerFactoryParameters;
+
+/**
+ * KeyManagerFactory implementation.
+ * @see KeyManagerFactorySpi
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class KeyManagerFactoryImpl extends KeyManagerFactorySpi {
+
+    // source of key material
+    private KeyStore keyStore;
+
+    //password
+    private char[] pwd;
+
+    /**
+     * @see KeyManagerFactorySpi#engineInit(KeyStore ks, char[] password)
+     */
+    @Override
+    protected void engineInit(KeyStore ks, char[] password)
+            throws KeyStoreException, NoSuchAlgorithmException,
+            UnrecoverableKeyException {
+        if (ks != null) {
+            keyStore = ks;
+            if (password != null) {
+                pwd = password.clone();
+            } else {
+                pwd = EmptyArray.CHAR;
+            }
+        } else {
+            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+            String keyStoreName = System.getProperty("javax.net.ssl.keyStore");
+            String keyStorePwd = null;
+            if (keyStoreName == null || keyStoreName.equalsIgnoreCase("NONE") || keyStoreName.isEmpty()) {
+                try {
+                    keyStore.load(null, null);
+                } catch (IOException e) {
+                    throw new KeyStoreException(e);
+                } catch (CertificateException e) {
+                    throw new KeyStoreException(e);
+                }
+            } else {
+                keyStorePwd = System.getProperty("javax.net.ssl.keyStorePassword");
+                if (keyStorePwd == null) {
+                    pwd = EmptyArray.CHAR;
+                } else {
+                    pwd = keyStorePwd.toCharArray();
+                }
+                try {
+                    keyStore.load(new FileInputStream(new File(keyStoreName)), pwd);
+                } catch (FileNotFoundException e) {
+                    throw new KeyStoreException(e);
+                } catch (IOException e) {
+                    throw new KeyStoreException(e);
+                } catch (CertificateException e) {
+                    throw new KeyStoreException(e);
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * @see KeyManagerFactorySpi#engineInit(ManagerFactoryParameters spec)
+     */
+    @Override
+    protected void engineInit(ManagerFactoryParameters spec)
+            throws InvalidAlgorithmParameterException {
+        throw new InvalidAlgorithmParameterException(
+                "ManagerFactoryParameters not supported");
+
+    }
+
+    /**
+     * @see KeyManagerFactorySpi#engineGetKeyManagers()
+     */
+    @Override
+    protected KeyManager[] engineGetKeyManagers() {
+        if (keyStore == null) {
+            throw new IllegalStateException("KeyManagerFactory is not initialized");
+        }
+        return new KeyManager[] { new KeyManagerImpl(keyStore, pwd) };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/KeyManagerImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/KeyManagerImpl.java
new file mode 100644
index 0000000..4682e1b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/KeyManagerImpl.java
@@ -0,0 +1,232 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.android.org.conscrypt;
+
+import java.net.Socket;
+import java.security.KeyStore;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.UnrecoverableEntryException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * KeyManager implementation.
+ *
+ * This implementation uses hashed key store information. It works faster than retrieving all of the
+ * data from the key store. Any key store changes, that happen after key manager was created, have
+ * no effect. The implementation does not use peer information (host, port) that may be obtained
+ * from socket or engine.
+ *
+ * @see javax.net.ssl.KeyManager
+ */
+class KeyManagerImpl extends X509ExtendedKeyManager {
+
+    // hashed key store information
+    private final HashMap<String, PrivateKeyEntry> hash;
+
+    /**
+     * Creates Key manager
+     */
+    KeyManagerImpl(KeyStore keyStore, char[] pwd) {
+        this.hash = new HashMap<String, PrivateKeyEntry>();
+        final Enumeration<String> aliases;
+        try {
+            aliases = keyStore.aliases();
+        } catch (KeyStoreException e) {
+            return;
+        }
+        for (; aliases.hasMoreElements();) {
+            final String alias = aliases.nextElement();
+            try {
+                if (keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
+                    KeyStore.PrivateKeyEntry entry;
+                    try {
+                        entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(
+                                alias, new KeyStore.PasswordProtection(pwd));
+                    } catch (UnsupportedOperationException e) {
+                        // If the KeyStore doesn't support getEntry(), as Android Keystore
+                        // doesn't, fall back to reading the two values separately.
+                        PrivateKey key = (PrivateKey) keyStore.getKey(alias, pwd);
+                        Certificate[] certs = keyStore.getCertificateChain(alias);
+                        entry = new KeyStore.PrivateKeyEntry(key, certs);
+                    }
+                    hash.put(alias, entry);
+                }
+            } catch (KeyStoreException ignored) {
+                // Ignored.
+            } catch (UnrecoverableEntryException ignored) {
+                // Ignored.
+            } catch (NoSuchAlgorithmException ignored) {
+                // Ignored.
+            }
+        }
+    }
+
+    @Override
+    public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) {
+        final String[] al = chooseAlias(keyTypes, issuers);
+        return (al == null ? null : al[0]);
+    }
+
+    @Override
+    public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+        final String[] al = chooseAlias(new String[] { keyType }, issuers);
+        return (al == null ? null : al[0]);
+    }
+
+    @Override
+    public X509Certificate[] getCertificateChain(String alias) {
+        if (alias == null) {
+            return null;
+        }
+        if (hash.containsKey(alias)) {
+            Certificate[] certs = hash.get(alias).getCertificateChain();
+            if (certs[0] instanceof X509Certificate) {
+                X509Certificate[] xcerts = new X509Certificate[certs.length];
+                for (int i = 0; i < certs.length; i++) {
+                    xcerts[i] = (X509Certificate) certs[i];
+                }
+                return xcerts;
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        return chooseAlias(new String[] { keyType }, issuers);
+    }
+
+    @Override
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        return chooseAlias(new String[] { keyType }, issuers);
+    }
+
+    @Override
+    public PrivateKey getPrivateKey(String alias) {
+        if (alias == null) {
+            return null;
+        }
+        if (hash.containsKey(alias)) {
+            return hash.get(alias).getPrivateKey();
+        }
+        return null;
+    }
+
+    @Override
+    public String chooseEngineClientAlias(String[] keyTypes, Principal[] issuers, SSLEngine engine) {
+        final String[] al = chooseAlias(keyTypes, issuers);
+        return (al == null ? null : al[0]);
+    }
+
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
+        final String[] al = chooseAlias(new String[] { keyType }, issuers);
+        return (al == null ? null : al[0]);
+    }
+
+    private String[] chooseAlias(String[] keyTypes, Principal[] issuers) {
+        if (keyTypes == null || keyTypes.length == 0) {
+            return null;
+        }
+        List<Principal> issuersList = (issuers == null) ? null : Arrays.asList(issuers);
+        ArrayList<String> found = new ArrayList<String>();
+        for (final Map.Entry<String, PrivateKeyEntry> entry : hash.entrySet()) {
+            final String alias = entry.getKey();
+            final Certificate[] chain = entry.getValue().getCertificateChain();
+            final Certificate cert = chain[0];
+            final String certKeyAlg = cert.getPublicKey().getAlgorithm();
+            final String certSigAlg = (cert instanceof X509Certificate
+                                       ? ((X509Certificate) cert).getSigAlgName().toUpperCase(Locale.US)
+                                       : null);
+            for (String keyAlgorithm : keyTypes) {
+                if (keyAlgorithm == null) {
+                    continue;
+                }
+                final String sigAlgorithm;
+                // handle cases like EC_EC and EC_RSA
+                int index = keyAlgorithm.indexOf('_');
+                if (index == -1) {
+                    sigAlgorithm = null;
+                } else {
+                    sigAlgorithm = keyAlgorithm.substring(index + 1);
+                    keyAlgorithm = keyAlgorithm.substring(0, index);
+                }
+                // key algorithm does not match
+                if (!certKeyAlg.equals(keyAlgorithm)) {
+                    continue;
+                }
+                /*
+                 * TODO find a more reliable test for signature
+                 * algorithm. Unfortunately value varies with
+                 * provider. For example for "EC" it could be
+                 * "SHA1WithECDSA" or simply "ECDSA".
+                 */
+                // sig algorithm does not match
+                if (sigAlgorithm != null && certSigAlg != null
+                        && !certSigAlg.contains(sigAlgorithm)) {
+                    continue;
+                }
+                // no issuers to match, just add to return list and continue
+                if (issuers == null || issuers.length == 0) {
+                    found.add(alias);
+                    continue;
+                }
+                // check that a certificate in the chain was issued by one of the specified issuers
+                for (Certificate certFromChain : chain) {
+                    if (!(certFromChain instanceof X509Certificate)) {
+                        // skip non-X509Certificates
+                        continue;
+                    }
+                    X509Certificate xcertFromChain = (X509Certificate) certFromChain;
+                    /*
+                     * Note use of X500Principal from
+                     * getIssuerX500Principal as opposed to Principal
+                     * from getIssuerDN. Principal.equals test does
+                     * not work in the case where
+                     * xcertFromChain.getIssuerDN is a bouncycastle
+                     * org.bouncycastle.jce.X509Principal.
+                     */
+                    X500Principal issuerFromChain = xcertFromChain.getIssuerX500Principal();
+                    if (issuersList.contains(issuerFromChain)) {
+                        found.add(alias);
+                    }
+                }
+            }
+        }
+        if (!found.isEmpty()) {
+            return found.toArray(new String[found.size()]);
+        }
+        return null;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
new file mode 100644
index 0000000..a313f7c
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
@@ -0,0 +1,1472 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2008 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 com.android.org.conscrypt;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+import java.nio.Buffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+import javax.net.ssl.SSLException;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * Provides the Java side of our JNI glue for OpenSSL.
+ * <p>
+ * Note: Many methods in this class take a reference to a Java object that holds a
+ * native pointer in the form of a long in addition to the long itself and don't use
+ * the Java object in the native implementation.  This is to prevent the Java object
+ * from becoming eligible for GC while the native method is executing.  See
+ * <a href="https://github.com/google/error-prone/blob/master/docs/bugpattern/UnsafeFinalization.md">this</a>
+ * for more details.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class NativeCrypto {
+    // --- OpenSSL library initialization --------------------------------------
+    private static final UnsatisfiedLinkError loadError;
+    static {
+        UnsatisfiedLinkError error = null;
+        try {
+            NativeCryptoJni.init();
+            clinit();
+        } catch (UnsatisfiedLinkError t) {
+            // Don't rethrow the error, so that we can later on interrogate the
+            // value of loadError.
+            error = t;
+        }
+        loadError = error;
+    }
+
+    private native static void clinit();
+
+    /**
+     * Checks to see whether or not the native library was successfully loaded. If not, throws
+     * the {@link UnsatisfiedLinkError} that was encountered while attempting to load the library.
+     */
+    static void checkAvailability() {
+        if (loadError != null) {
+            throw loadError;
+        }
+    }
+
+    // --- DSA/RSA public/private key handling functions -----------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
+            byte[] dmp1, byte[] dmq1, byte[] iqmp);
+
+    static native int EVP_PKEY_type(NativeRef.EVP_PKEY pkey);
+
+    static native String EVP_PKEY_print_public(NativeRef.EVP_PKEY pkeyRef);
+
+    static native String EVP_PKEY_print_params(NativeRef.EVP_PKEY pkeyRef);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void EVP_PKEY_free(long pkey);
+
+    static native int EVP_PKEY_cmp(NativeRef.EVP_PKEY pkey1, NativeRef.EVP_PKEY pkey2);
+
+    static native byte[] EVP_marshal_private_key(NativeRef.EVP_PKEY pkey);
+
+    static native long EVP_parse_private_key(byte[] data) throws ParsingException;
+
+    static native byte[] EVP_marshal_public_key(NativeRef.EVP_PKEY pkey);
+
+    static native long EVP_parse_public_key(byte[] data) throws ParsingException;
+
+    static native long PEM_read_bio_PUBKEY(long bioCtx);
+
+    static native long PEM_read_bio_PrivateKey(long bioCtx);
+
+    static native long getRSAPrivateKeyWrapper(PrivateKey key, byte[] modulus);
+
+    static native long getECPrivateKeyWrapper(PrivateKey key, NativeRef.EC_GROUP ecGroupRef);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long RSA_generate_key_ex(int modulusBits, byte[] publicExponent);
+
+    static native int RSA_size(NativeRef.EVP_PKEY pkey);
+
+    static native int RSA_private_encrypt(
+            int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey, int padding);
+
+    static native int RSA_public_decrypt(int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey,
+            int padding) throws BadPaddingException, SignatureException;
+
+    static native int RSA_public_encrypt(
+            int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey, int padding);
+
+    static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey,
+            int padding) throws BadPaddingException, SignatureException;
+
+    /**
+     * @return array of {n, e}
+     */
+    static native byte[][] get_RSA_public_params(NativeRef.EVP_PKEY rsa);
+
+    /**
+     * @return array of {n, e, d, p, q, dmp1, dmq1, iqmp}
+     */
+    static native byte[][] get_RSA_private_params(NativeRef.EVP_PKEY rsa);
+
+    // --- ChaCha20 -----------------------
+
+    /**
+     * Returns the encrypted or decrypted version of the data.
+     */
+    static native void chacha20_encrypt_decrypt(byte[] in, int inOffset, byte[] out, int outOffset,
+            int length, byte[] key, byte[] nonce, int blockCounter);
+
+    // --- EC functions --------------------------
+
+    static native long EVP_PKEY_new_EC_KEY(
+            NativeRef.EC_GROUP groupRef, NativeRef.EC_POINT pubkeyRef, byte[] privkey);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long EC_GROUP_new_by_curve_name(String curveName);
+
+    static native long EC_GROUP_new_arbitrary(
+            byte[] p, byte[] a, byte[] b, byte[] x, byte[] y, byte[] order, int cofactor);
+
+    static native String EC_GROUP_get_curve_name(NativeRef.EC_GROUP groupRef);
+
+    static native byte[][] EC_GROUP_get_curve(NativeRef.EC_GROUP groupRef);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void EC_GROUP_clear_free(long groupRef);
+
+    static native long EC_GROUP_get_generator(NativeRef.EC_GROUP groupRef);
+
+    static native byte[] EC_GROUP_get_order(NativeRef.EC_GROUP groupRef);
+
+    static native int EC_GROUP_get_degree(NativeRef.EC_GROUP groupRef);
+
+    static native byte[] EC_GROUP_get_cofactor(NativeRef.EC_GROUP groupRef);
+
+    static native long EC_POINT_new(NativeRef.EC_GROUP groupRef);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void EC_POINT_clear_free(long pointRef);
+
+    static native byte[][] EC_POINT_get_affine_coordinates(
+            NativeRef.EC_GROUP groupRef, NativeRef.EC_POINT pointRef);
+
+    static native void EC_POINT_set_affine_coordinates(
+            NativeRef.EC_GROUP groupRef, NativeRef.EC_POINT pointRef, byte[] x, byte[] y);
+
+    static native long EC_KEY_generate_key(NativeRef.EC_GROUP groupRef);
+
+    static native long EC_KEY_get1_group(NativeRef.EVP_PKEY pkeyRef);
+
+    static native byte[] EC_KEY_get_private_key(NativeRef.EVP_PKEY keyRef);
+
+    static native long EC_KEY_get_public_key(NativeRef.EVP_PKEY keyRef);
+
+    static native byte[] EC_KEY_marshal_curve_name(NativeRef.EC_GROUP groupRef) throws IOException;
+
+    static native long EC_KEY_parse_curve_name(byte[] encoded) throws IOException;
+
+    static native int ECDH_compute_key(byte[] out, int outOffset, NativeRef.EVP_PKEY publicKeyRef,
+            NativeRef.EVP_PKEY privateKeyRef) throws InvalidKeyException, IndexOutOfBoundsException;
+
+    static native int ECDSA_size(NativeRef.EVP_PKEY pkey);
+
+    static native int ECDSA_sign(byte[] data, byte[] sig, NativeRef.EVP_PKEY pkey);
+
+    static native int ECDSA_verify(byte[] data, byte[] sig, NativeRef.EVP_PKEY pkey);
+
+    // --- Message digest functions --------------
+
+    // These return const references
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long EVP_get_digestbyname(String name);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native int EVP_MD_size(long evp_md_const);
+
+    // --- Message digest context functions --------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long EVP_MD_CTX_create();
+
+    static native void EVP_MD_CTX_cleanup(NativeRef.EVP_MD_CTX ctx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void EVP_MD_CTX_destroy(long ctx);
+
+    static native int EVP_MD_CTX_copy_ex(
+            NativeRef.EVP_MD_CTX dst_ctx, NativeRef.EVP_MD_CTX src_ctx);
+
+    // --- Digest handling functions -------------------------------------------
+
+    static native int EVP_DigestInit_ex(NativeRef.EVP_MD_CTX ctx, long evp_md);
+
+    static native void EVP_DigestUpdate(
+            NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset, int length);
+
+    static native void EVP_DigestUpdateDirect(NativeRef.EVP_MD_CTX ctx, long ptr, int length);
+
+    static native int EVP_DigestFinal_ex(NativeRef.EVP_MD_CTX ctx, byte[] hash, int offset);
+
+    // --- Signature handling functions ----------------------------------------
+
+    static native long EVP_DigestSignInit(
+            NativeRef.EVP_MD_CTX ctx, long evpMdRef, NativeRef.EVP_PKEY key);
+
+    static native long EVP_DigestVerifyInit(
+            NativeRef.EVP_MD_CTX ctx, long evpMdRef, NativeRef.EVP_PKEY key);
+
+    static native void EVP_DigestSignUpdate(
+            NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset, int length);
+
+    static native void EVP_DigestSignUpdateDirect(NativeRef.EVP_MD_CTX ctx, long ptr, int length);
+
+    static native void EVP_DigestVerifyUpdate(
+            NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset, int length);
+
+    static native void EVP_DigestVerifyUpdateDirect(NativeRef.EVP_MD_CTX ctx, long ptr, int length);
+
+    static native byte[] EVP_DigestSignFinal(NativeRef.EVP_MD_CTX ctx);
+
+    static native boolean EVP_DigestVerifyFinal(NativeRef.EVP_MD_CTX ctx, byte[] signature,
+            int offset, int length) throws IndexOutOfBoundsException;
+
+    static native long EVP_PKEY_encrypt_init(NativeRef.EVP_PKEY pkey) throws InvalidKeyException;
+
+    static native int EVP_PKEY_encrypt(NativeRef.EVP_PKEY_CTX ctx, byte[] out, int outOffset,
+            byte[] input, int inOffset, int inLength)
+            throws IndexOutOfBoundsException, BadPaddingException;
+
+    static native long EVP_PKEY_decrypt_init(NativeRef.EVP_PKEY pkey) throws InvalidKeyException;
+
+    static native int EVP_PKEY_decrypt(NativeRef.EVP_PKEY_CTX ctx, byte[] out, int outOffset,
+            byte[] input, int inOffset, int inLength)
+            throws IndexOutOfBoundsException, BadPaddingException;
+
+    static native void EVP_PKEY_CTX_free(long pkeyCtx);
+
+    static native void EVP_PKEY_CTX_set_rsa_padding(long ctx, int pad)
+            throws InvalidAlgorithmParameterException;
+
+    static native void EVP_PKEY_CTX_set_rsa_pss_saltlen(long ctx, int len)
+            throws InvalidAlgorithmParameterException;
+
+    static native void EVP_PKEY_CTX_set_rsa_mgf1_md(long ctx, long evpMdRef)
+            throws InvalidAlgorithmParameterException;
+
+    static native void EVP_PKEY_CTX_set_rsa_oaep_md(long ctx, long evpMdRef)
+            throws InvalidAlgorithmParameterException;
+
+    static native void EVP_PKEY_CTX_set_rsa_oaep_label(long ctx, byte[] label)
+            throws InvalidAlgorithmParameterException;
+
+    // --- Block ciphers -------------------------------------------------------
+
+    // These return const references
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long EVP_get_cipherbyname(String string);
+
+    static native void EVP_CipherInit_ex(NativeRef.EVP_CIPHER_CTX ctx, long evpCipher, byte[] key,
+            byte[] iv, boolean encrypting);
+
+    static native int EVP_CipherUpdate(NativeRef.EVP_CIPHER_CTX ctx, byte[] out, int outOffset,
+            byte[] in, int inOffset, int inLength) throws IndexOutOfBoundsException;
+
+    static native int EVP_CipherFinal_ex(NativeRef.EVP_CIPHER_CTX ctx, byte[] out, int outOffset)
+            throws BadPaddingException, IllegalBlockSizeException;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native int EVP_CIPHER_iv_length(long evpCipher);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long EVP_CIPHER_CTX_new();
+
+    static native int EVP_CIPHER_CTX_block_size(NativeRef.EVP_CIPHER_CTX ctx);
+
+    static native int get_EVP_CIPHER_CTX_buf_len(NativeRef.EVP_CIPHER_CTX ctx);
+
+    static native boolean get_EVP_CIPHER_CTX_final_used(NativeRef.EVP_CIPHER_CTX ctx);
+
+    static native void EVP_CIPHER_CTX_set_padding(
+            NativeRef.EVP_CIPHER_CTX ctx, boolean enablePadding);
+
+    static native void EVP_CIPHER_CTX_set_key_length(NativeRef.EVP_CIPHER_CTX ctx, int keyBitSize);
+
+    static native void EVP_CIPHER_CTX_free(long ctx);
+
+    // --- AEAD ----------------------------------------------------------------
+    static native long EVP_aead_aes_128_gcm();
+
+    static native long EVP_aead_aes_256_gcm();
+
+    static native long EVP_aead_chacha20_poly1305();
+
+    static native long EVP_aead_aes_128_gcm_siv();
+
+    static native long EVP_aead_aes_256_gcm_siv();
+
+    static native int EVP_AEAD_max_overhead(long evpAead);
+
+    static native int EVP_AEAD_nonce_length(long evpAead);
+
+    static native int EVP_AEAD_CTX_seal(long evpAead, byte[] key, int tagLengthInBytes, byte[] out,
+            int outOffset, byte[] nonce, byte[] in, int inOffset, int inLength, byte[] ad)
+            throws ShortBufferException, BadPaddingException, IndexOutOfBoundsException;
+
+    static native int EVP_AEAD_CTX_open(long evpAead, byte[] key, int tagLengthInBytes, byte[] out,
+            int outOffset, byte[] nonce, byte[] in, int inOffset, int inLength, byte[] ad)
+            throws ShortBufferException, BadPaddingException, IndexOutOfBoundsException;
+
+    // --- HMAC functions ------------------------------------------------------
+
+    static native long HMAC_CTX_new();
+
+    static native void HMAC_CTX_free(long ctx);
+
+    static native void HMAC_Init_ex(NativeRef.HMAC_CTX ctx, byte[] key, long evp_md);
+
+    static native void HMAC_Update(NativeRef.HMAC_CTX ctx, byte[] in, int inOffset, int inLength);
+
+    static native void HMAC_UpdateDirect(NativeRef.HMAC_CTX ctx, long inPtr, int inLength);
+
+    static native byte[] HMAC_Final(NativeRef.HMAC_CTX ctx);
+
+    // --- RAND ----------------------------------------------------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void RAND_bytes(byte[] output);
+
+    // --- X509_NAME -----------------------------------------------------------
+
+    static int X509_NAME_hash(X500Principal principal) {
+        return X509_NAME_hash(principal, "SHA1");
+    }
+
+    public static int X509_NAME_hash_old(X500Principal principal) {
+        return X509_NAME_hash(principal, "MD5");
+    }
+    private static int X509_NAME_hash(X500Principal principal, String algorithm) {
+        try {
+            byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
+            int offset = 0;
+            return (((digest[offset++] & 0xff) << 0) | ((digest[offset++] & 0xff) << 8)
+                    | ((digest[offset++] & 0xff) << 16) | ((digest[offset] & 0xff) << 24));
+        } catch (NoSuchAlgorithmException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    // --- X509 ----------------------------------------------------------------
+
+    /** Used to request get_X509_GENERAL_NAME_stack get the "altname" field. */
+    static final int GN_STACK_SUBJECT_ALT_NAME = 1;
+
+    /**
+     * Used to request get_X509_GENERAL_NAME_stack get the issuerAlternativeName
+     * extension.
+     */
+    static final int GN_STACK_ISSUER_ALT_NAME = 2;
+
+    /**
+     * Used to request only non-critical types in get_X509*_ext_oids.
+     */
+    static final int EXTENSION_TYPE_NON_CRITICAL = 0;
+
+    /**
+     * Used to request only critical types in get_X509*_ext_oids.
+     */
+    static final int EXTENSION_TYPE_CRITICAL = 1;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long d2i_X509_bio(long bioCtx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long d2i_X509(byte[] encoded) throws ParsingException;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long PEM_read_bio_X509(long bioCtx);
+
+    static native byte[] i2d_X509(long x509ctx, OpenSSLX509Certificate holder);
+
+    /** Takes an X509 context not an X509_PUBKEY context. */
+    static native byte[] i2d_X509_PUBKEY(long x509ctx, OpenSSLX509Certificate holder);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] ASN1_seq_pack_X509(long[] x509CertRefs);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long[] ASN1_seq_unpack_X509_bio(long bioRef) throws ParsingException;
+
+    static native void X509_free(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native long X509_dup(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native int X509_cmp(long x509ctx1, OpenSSLX509Certificate holder, long x509ctx2, OpenSSLX509Certificate holder2);
+
+    static native void X509_print_ex(long bioCtx, long x509ctx, OpenSSLX509Certificate holder, long nmflag, long certflag);
+
+    static native byte[] X509_get_issuer_name(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native byte[] X509_get_subject_name(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native String get_X509_sig_alg_oid(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native byte[] get_X509_sig_alg_parameter(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native boolean[] get_X509_issuerUID(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native boolean[] get_X509_subjectUID(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native long X509_get_pubkey(long x509ctx, OpenSSLX509Certificate holder)
+            throws NoSuchAlgorithmException, InvalidKeyException;
+
+    static native String get_X509_pubkey_oid(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native byte[] X509_get_ext_oid(long x509ctx, OpenSSLX509Certificate holder, String oid);
+
+    static native String[] get_X509_ext_oids(long x509ctx, OpenSSLX509Certificate holder, int critical);
+
+    static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx, OpenSSLX509Certificate holder, int type)
+            throws CertificateParsingException;
+
+    static native boolean[] get_X509_ex_kusage(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native String[] get_X509_ex_xkusage(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native int get_X509_ex_pathlen(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native long X509_get_notBefore(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native long X509_get_notAfter(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native long X509_get_version(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native byte[] X509_get_serialNumber(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, NativeRef.EVP_PKEY pkeyCtx)
+            throws BadPaddingException;
+
+    static native byte[] get_X509_cert_info_enc(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native byte[] get_X509_signature(long x509ctx, OpenSSLX509Certificate holder);
+
+    static native int get_X509_ex_flags(long x509ctx, OpenSSLX509Certificate holder);
+
+    // Used by Android platform TrustedCertificateStore.
+    @SuppressWarnings("unused")
+    static native int X509_check_issued(long ctx, OpenSSLX509Certificate holder, long ctx2, OpenSSLX509Certificate holder2);
+
+    // --- PKCS7 ---------------------------------------------------------------
+
+    /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
+    static final int PKCS7_CERTS = 1;
+
+    /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
+    static final int PKCS7_CRLS = 2;
+
+    /** Returns an array of X509 or X509_CRL pointers. */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long[] d2i_PKCS7_bio(long bioCtx, int which) throws ParsingException;
+
+    /** Returns an array of X509 or X509_CRL pointers. */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] i2d_PKCS7(long[] certs);
+
+    /** Returns an array of X509 or X509_CRL pointers. */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long[] PEM_read_bio_PKCS7(long bioCtx, int which);
+
+    // --- X509_CRL ------------------------------------------------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long d2i_X509_CRL_bio(long bioCtx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long PEM_read_bio_X509_CRL(long bioCtx);
+
+    static native byte[] i2d_X509_CRL(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native void X509_CRL_free(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native void X509_CRL_print(long bioCtx, long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native String get_X509_CRL_sig_alg_oid(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native byte[] get_X509_CRL_sig_alg_parameter(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native byte[] X509_CRL_get_issuer_name(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    /** Returns X509_REVOKED reference that is not duplicated! */
+    static native long X509_CRL_get0_by_cert(long x509CrlCtx, OpenSSLX509CRL holder, long x509Ctx, OpenSSLX509Certificate holder2);
+
+    /** Returns X509_REVOKED reference that is not duplicated! */
+    static native long X509_CRL_get0_by_serial(long x509CrlCtx, OpenSSLX509CRL holder, byte[] serial);
+
+    /** Returns an array of X509_REVOKED that are owned by the caller. */
+    static native long[] X509_CRL_get_REVOKED(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native String[] get_X509_CRL_ext_oids(long x509Crlctx, OpenSSLX509CRL holder, int critical);
+
+    static native byte[] X509_CRL_get_ext_oid(long x509CrlCtx, OpenSSLX509CRL holder, String oid);
+
+    static native void X509_delete_ext(long x509, OpenSSLX509Certificate holder, String oid);
+
+    static native long X509_CRL_get_version(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native long X509_CRL_get_ext(long x509CrlCtx, OpenSSLX509CRL holder, String oid);
+
+    static native byte[] get_X509_CRL_signature(long x509ctx, OpenSSLX509CRL holder);
+
+    static native void X509_CRL_verify(long x509CrlCtx, OpenSSLX509CRL holder, NativeRef.EVP_PKEY pkeyCtx);
+
+    static native byte[] get_X509_CRL_crl_enc(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native long X509_CRL_get_lastUpdate(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    static native long X509_CRL_get_nextUpdate(long x509CrlCtx, OpenSSLX509CRL holder);
+
+    // --- X509_REVOKED --------------------------------------------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long X509_REVOKED_dup(long x509RevokedCtx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] i2d_X509_REVOKED(long x509RevokedCtx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native String[] get_X509_REVOKED_ext_oids(long x509ctx, int critical);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] X509_REVOKED_get_ext_oid(long x509RevokedCtx, String oid);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] X509_REVOKED_get_serialNumber(long x509RevokedCtx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long X509_REVOKED_get_ext(long x509RevokedCtx, String oid);
+
+    /** Returns ASN1_TIME reference. */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long get_X509_REVOKED_revocationDate(long x509RevokedCtx);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void X509_REVOKED_print(long bioRef, long x509RevokedCtx);
+
+    // --- X509_EXTENSION ------------------------------------------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native int X509_supported_extension(long x509ExtensionRef);
+
+    // --- ASN1_TIME -----------------------------------------------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal) throws ParsingException;
+
+    // --- ASN1 Encoding -------------------------------------------------------
+
+    /**
+     * Allocates and returns an opaque reference to an object that can be used with other
+     * asn1_read_* functions to read the ASN.1-encoded data in val.  The returned object must
+     * be freed after use by calling asn1_read_free.
+     */
+    static native long asn1_read_init(byte[] val) throws IOException;
+
+    /**
+     * Allocates and returns an opaque reference to an object that can be used with other
+     * asn1_read_* functions to read the ASN.1 sequence pointed to by cbsRef.  The returned
+     * object must be freed after use by calling asn1_read_free.
+     */
+    static native long asn1_read_sequence(long cbsRef) throws IOException;
+
+    /**
+     * Returns whether the next object in the given reference is explicitly tagged with the
+     * given tag number.
+     */
+    static native boolean asn1_read_next_tag_is(long cbsRef, int tag) throws IOException;
+
+    /**
+     * Allocates and returns an opaque reference to an object that can be used with
+     * other asn1_read_* functions to read the ASN.1 data pointed to by cbsRef.  The returned
+     * object must be freed after use by calling asn1_read_free.
+     */
+    static native long asn1_read_tagged(long cbsRef) throws IOException;
+
+    /**
+     * Returns the contents of an ASN.1 octet string from the given reference.
+     */
+    static native byte[] asn1_read_octetstring(long cbsRef) throws IOException;
+
+    /**
+     * Returns an ASN.1 integer from the given reference.  If the integer doesn't fit
+     * in a uint64, this method will throw an IOException.
+     */
+    static native long asn1_read_uint64(long cbsRef) throws IOException;
+
+    /**
+     * Consumes an ASN.1 NULL from the given reference.
+     */
+    static native void asn1_read_null(long cbsRef) throws IOException;
+
+    /**
+     * Returns an ASN.1 OID in dotted-decimal notation (eg, "1.3.14.3.2.26" for SHA-1) from the
+     * given reference.
+     */
+    static native String asn1_read_oid(long cbsRef) throws IOException;
+
+    /**
+     * Returns whether or not the given reference has been read completely.
+     */
+    static native boolean asn1_read_is_empty(long cbsRef);
+
+    /**
+     * Frees any resources associated with the given reference.  After calling, the reference
+     * must not be used again.  This may be called with a zero reference, in which case nothing
+     * will be done.
+     */
+    static native void asn1_read_free(long cbsRef);
+
+    /**
+     * Allocates and returns an opaque reference to an object that can be used with other
+     * asn1_write_* functions to write ASN.1-encoded data.  The returned object must be finalized
+     * after use by calling either asn1_write_finish or asn1_write_cleanup, and its resources
+     * must be freed by calling asn1_write_free.
+     */
+    static native long asn1_write_init() throws IOException;
+
+    /**
+     * Allocates and returns an opaque reference to an object that can be used with other
+     * asn1_write_* functions to write an ASN.1 sequence into the given reference.  The returned
+     * reference may only be used until the next call on the parent reference.  The returned
+     * object must be freed after use by calling asn1_write_free.
+     */
+    static native long asn1_write_sequence(long cbbRef) throws IOException;
+
+    /**
+     * Allocates and returns an opaque reference to an object that can be used with other
+     * asn1_write_* functions to write a explicitly-tagged ASN.1 object with the given tag
+     * into the given reference. The returned reference may only be used until the next
+     * call on the parent reference.  The returned object must be freed after use by
+     * calling asn1_write_free.
+     */
+    static native long asn1_write_tag(long cbbRef, int tag) throws IOException;
+
+    /**
+     * Writes the given data into the given reference as an ASN.1-encoded octet string.
+     */
+    static native void asn1_write_octetstring(long cbbRef, byte[] data) throws IOException;
+
+    /**
+     * Writes the given value into the given reference as an ASN.1-encoded integer.
+     */
+    static native void asn1_write_uint64(long cbbRef, long value) throws IOException;
+
+    /**
+     * Writes a NULL value into the given reference.
+     */
+    static native void asn1_write_null(long cbbRef) throws IOException;
+
+    /**
+     * Writes the given OID (which must be in dotted-decimal notation) into the given reference.
+     */
+    static native void asn1_write_oid(long cbbRef, String oid) throws IOException;
+
+    /**
+     * Flushes the given reference, invalidating any child references and completing their
+     * operations.  This must be called if the child references are to be freed before
+     * asn1_write_finish is called on the ultimate parent.  The child references must still
+     * be freed.
+     */
+    static native void asn1_write_flush(long cbbRef) throws IOException;
+
+    /**
+     * Completes any in-progress operations and returns the ASN.1-encoded data.  Either this
+     * or asn1_write_cleanup must be called on any reference returned from asn1_write_init
+     * before it is freed.
+     */
+    static native byte[] asn1_write_finish(long cbbRef) throws IOException;
+
+    /**
+     * Cleans up intermediate state in the given reference.  Either this or asn1_write_finish
+     * must be called on any reference returned from asn1_write_init before it is freed.
+     */
+    static native void asn1_write_cleanup(long cbbRef);
+
+    /**
+     * Frees resources associated with the given reference.  After calling, the reference
+     * must not be used again.  This may be called with a zero reference, in which case nothing
+     * will be done.
+     */
+    static native void asn1_write_free(long cbbRef);
+
+    // --- BIO stream creation -------------------------------------------------
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long create_BIO_InputStream(OpenSSLBIOInputStream is, boolean isFinite);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long create_BIO_OutputStream(OutputStream os);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void BIO_free_all(long bioRef);
+
+    // --- SSL handling --------------------------------------------------------
+
+    static final String OBSOLETE_PROTOCOL_SSLV3 = "SSLv3";
+    private static final String SUPPORTED_PROTOCOL_TLSV1 = "TLSv1";
+    private static final String SUPPORTED_PROTOCOL_TLSV1_1 = "TLSv1.1";
+    private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
+    static final String SUPPORTED_PROTOCOL_TLSV1_3 = "TLSv1.3";
+
+    static final String[] SUPPORTED_TLS_1_3_CIPHER_SUITES = new String[] {
+            "TLS_AES_128_GCM_SHA256",
+            "TLS_AES_256_GCM_SHA384",
+            "TLS_CHACHA20_POLY1305_SHA256",
+    };
+
+    // SUPPORTED_TLS_1_2_CIPHER_SUITES_SET contains all the supported cipher suites for TLS 1.2,
+    // using their Java names.
+    static final Set<String> SUPPORTED_TLS_1_2_CIPHER_SUITES_SET = new HashSet<String>();
+
+    // SUPPORTED_LEGACY_CIPHER_SUITES_SET contains all the supported cipher suites using the legacy
+    // OpenSSL-style names.
+    private static final Set<String> SUPPORTED_LEGACY_CIPHER_SUITES_SET = new HashSet<String>();
+
+    static final Set<String> SUPPORTED_TLS_1_3_CIPHER_SUITES_SET = new HashSet<String>(
+            Arrays.asList(SUPPORTED_TLS_1_3_CIPHER_SUITES));
+
+    /**
+     * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation
+     * indication signaling cipher suite value. It is not a real
+     * cipher suite. It is just an indication in the default and
+     * supported cipher suite lists indicates that the implementation
+     * supports secure renegotiation.
+     * <p>
+     * In the RI, its presence means that the SCSV is sent in the
+     * cipher suite list to indicate secure renegotiation support and
+     * its absense means to send an empty TLS renegotiation info
+     * extension instead.
+     * <p>
+     * However, OpenSSL doesn't provide an API to give this level of
+     * control, instead always sending the SCSV and always including
+     * the empty renegotiation info if TLS is used (as opposed to
+     * SSL). So we simply allow TLS_EMPTY_RENEGOTIATION_INFO_SCSV to
+     * be passed for compatibility as to provide the hint that we
+     * support secure renegotiation.
+     */
+    static final String TLS_EMPTY_RENEGOTIATION_INFO_SCSV = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
+
+    static String cipherSuiteToJava(String cipherSuite) {
+        // For historical reasons, Java uses a different name for TLS_RSA_WITH_3DES_EDE_CBC_SHA.
+        if ("TLS_RSA_WITH_3DES_EDE_CBC_SHA".equals(cipherSuite)) {
+            return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
+        }
+        return cipherSuite;
+    }
+
+    static String cipherSuiteFromJava(String javaCipherSuite) {
+        if ("SSL_RSA_WITH_3DES_EDE_CBC_SHA".equals(javaCipherSuite)) {
+            return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+        }
+        return javaCipherSuite;
+    }
+
+    /**
+     * TLS_FALLBACK_SCSV is from
+     * https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
+     * to indicate to the server that this is a fallback protocol
+     * request.
+     */
+    private static final String TLS_FALLBACK_SCSV = "TLS_FALLBACK_SCSV";
+
+    private static final boolean HAS_AES_HARDWARE;
+    private static final String[] SUPPORTED_TLS_1_2_CIPHER_SUITES;
+    static {
+        if (loadError == null) {
+            // If loadError is not null, it means the native code was not loaded, so
+            // get_cipher_names will throw UnsatisfiedLinkError.
+            String[] allCipherSuites = get_cipher_names("ALL:!DHE");
+
+            // get_cipher_names returns an array where even indices are the standard name and odd
+            // indices are the OpenSSL name.
+            int size = allCipherSuites.length;
+            if (size % 2 != 0) {
+                throw new IllegalArgumentException(
+                        "Invalid cipher list returned by get_cipher_names");
+            }
+            SUPPORTED_TLS_1_2_CIPHER_SUITES = new String[size / 2 + 2];
+            for (int i = 0; i < size; i += 2) {
+                String cipherSuite = cipherSuiteToJava(allCipherSuites[i]);
+                SUPPORTED_TLS_1_2_CIPHER_SUITES[i / 2] = cipherSuite;
+                SUPPORTED_TLS_1_2_CIPHER_SUITES_SET.add(cipherSuite);
+
+                SUPPORTED_LEGACY_CIPHER_SUITES_SET.add(allCipherSuites[i + 1]);
+            }
+            SUPPORTED_TLS_1_2_CIPHER_SUITES[size / 2] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
+            SUPPORTED_TLS_1_2_CIPHER_SUITES[size / 2 + 1] = TLS_FALLBACK_SCSV;
+
+            HAS_AES_HARDWARE = EVP_has_aes_hardware() == 1;
+        } else {
+            HAS_AES_HARDWARE = false;
+            SUPPORTED_TLS_1_2_CIPHER_SUITES = new String[0];
+        }
+    }
+
+    /**
+     * Returns 1 if the BoringSSL believes the CPU has AES accelerated hardware
+     * instructions. Used to determine cipher suite ordering.
+     */
+    static native int EVP_has_aes_hardware();
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long SSL_CTX_new();
+
+    // IMPLEMENTATION NOTE: The default list of cipher suites is a trade-off between what we'd like
+    // to use and what servers currently support. We strive to be secure enough by default. We thus
+    // avoid unacceptably weak suites (e.g., those with bulk cipher secret key shorter than 128
+    // bits), while maintaining the capability to connect to the majority of servers.
+    //
+    // Cipher suites are listed in preference order (favorite choice first) of the client. However,
+    // servers are not required to honor the order. The key rules governing the preference order
+    // are:
+    // * Prefer Forward Secrecy (i.e., cipher suites that use ECDHE and DHE for key agreement).
+    // * Prefer ChaCha20-Poly1305 to AES-GCM unless hardware support for AES is available.
+    // * Prefer AES-GCM to AES-CBC whose MAC-pad-then-encrypt approach leads to weaknesses (e.g.,
+    //   Lucky 13).
+    // * Prefer 128-bit bulk encryption to 256-bit one, because 128-bit is safe enough while
+    //   consuming less CPU/time/energy.
+    //
+    // NOTE: Removing cipher suites from this list needs to be done with caution, because this may
+    // prevent apps from connecting to servers they were previously able to connect to.
+
+    /** X.509 based cipher suites enabled by default (if requested), in preference order. */
+    static final String[] DEFAULT_X509_CIPHER_SUITES = HAS_AES_HARDWARE ?
+            new String[] {
+                    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+                    "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+                    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+                    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+                    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+                    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+                    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+                    "TLS_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_RSA_WITH_AES_256_GCM_SHA384",
+                    "TLS_RSA_WITH_AES_128_CBC_SHA",
+                    "TLS_RSA_WITH_AES_256_CBC_SHA",
+            } :
+            new String[] {
+                    "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+                    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+                    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+                    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+                    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+                    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+                    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+                    "TLS_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_RSA_WITH_AES_256_GCM_SHA384",
+                    "TLS_RSA_WITH_AES_128_CBC_SHA",
+                    "TLS_RSA_WITH_AES_256_CBC_SHA",
+            };
+
+    /** TLS-PSK cipher suites enabled by default (if requested), in preference order. */
+    static final String[] DEFAULT_PSK_CIPHER_SUITES = new String[] {
+            "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+            "TLS_PSK_WITH_AES_128_CBC_SHA",
+            "TLS_PSK_WITH_AES_256_CBC_SHA",
+    };
+
+    static String[] getSupportedCipherSuites() {
+        return SSLUtils.concat(SUPPORTED_TLS_1_3_CIPHER_SUITES, SUPPORTED_TLS_1_2_CIPHER_SUITES.clone());
+    }
+
+    static native void SSL_CTX_free(long ssl_ctx, AbstractSessionContext holder);
+
+    static native void SSL_CTX_set_session_id_context(long ssl_ctx, AbstractSessionContext holder, byte[] sid_ctx);
+
+    static native long SSL_CTX_set_timeout(long ssl_ctx, AbstractSessionContext holder, long seconds);
+
+    static native long SSL_new(long ssl_ctx, AbstractSessionContext holder) throws SSLException;
+
+    static native void SSL_enable_tls_channel_id(long ssl, NativeSsl ssl_holder) throws SSLException;
+
+    static native byte[] SSL_get_tls_channel_id(long ssl, NativeSsl ssl_holder) throws SSLException;
+
+    static native void SSL_set1_tls_channel_id(long ssl, NativeSsl ssl_holder, NativeRef.EVP_PKEY pkey);
+
+    /**
+     * Sets the local certificates and private key.
+     *
+     * @param ssl the SSL reference.
+     * @param encodedCertificates the encoded form of the local certificate chain.
+     * @param pkey a reference to the private key.
+     * @throws SSLException if a problem occurs setting the cert/key.
+     */
+    static native void setLocalCertsAndPrivateKey(long ssl, NativeSsl ssl_holder, byte[][] encodedCertificates,
+        NativeRef.EVP_PKEY pkey) throws SSLException;
+
+    static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, byte[][] asn1DerEncodedX500Principals)
+            throws SSLException;
+
+    static native long SSL_set_mode(long ssl, NativeSsl ssl_holder, long mode);
+
+    static native long SSL_set_options(long ssl, NativeSsl ssl_holder, long options);
+
+    static native long SSL_clear_options(long ssl, NativeSsl ssl_holder, long options);
+
+    static native int SSL_set_protocol_versions(long ssl, NativeSsl ssl_holder, int min_version, int max_version);
+
+    static native void SSL_enable_signed_cert_timestamps(long ssl, NativeSsl ssl_holder);
+
+    static native byte[] SSL_get_signed_cert_timestamp_list(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_set_signed_cert_timestamp_list(long ssl, NativeSsl ssl_holder, byte[] list);
+
+    static native void SSL_enable_ocsp_stapling(long ssl, NativeSsl ssl_holder);
+
+    static native byte[] SSL_get_ocsp_response(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_set_ocsp_response(long ssl, NativeSsl ssl_holder, byte[] response);
+
+    static native byte[] SSL_get_tls_unique(long ssl, NativeSsl ssl_holder);
+
+    static native byte[] SSL_export_keying_material(long ssl, NativeSsl ssl_holder, byte[] label, byte[] context, int num_bytes) throws SSLException;
+
+    static native void SSL_use_psk_identity_hint(long ssl, NativeSsl ssl_holder, String identityHint) throws SSLException;
+
+    static native void set_SSL_psk_client_callback_enabled(long ssl, NativeSsl ssl_holder, boolean enabled);
+
+    static native void set_SSL_psk_server_callback_enabled(long ssl, NativeSsl ssl_holder, boolean enabled);
+
+    /** Protocols to enable by default when "TLSv1.3" is requested. */
+    static final String[] TLSV13_PROTOCOLS = new String[] {
+            SUPPORTED_PROTOCOL_TLSV1,
+            SUPPORTED_PROTOCOL_TLSV1_1,
+            SUPPORTED_PROTOCOL_TLSV1_2,
+            SUPPORTED_PROTOCOL_TLSV1_3,
+    };
+
+    /** Protocols to enable by default when "TLSv1.2" is requested. */
+    static final String[] TLSV12_PROTOCOLS = new String[] {
+            SUPPORTED_PROTOCOL_TLSV1,
+            SUPPORTED_PROTOCOL_TLSV1_1,
+            SUPPORTED_PROTOCOL_TLSV1_2,
+    };
+
+    /** Protocols to enable by default when "TLSv1.1" is requested. */
+    static final String[] TLSV11_PROTOCOLS = TLSV12_PROTOCOLS;
+
+    /** Protocols to enable by default when "TLSv1" is requested. */
+    static final String[] TLSV1_PROTOCOLS = TLSV11_PROTOCOLS;
+
+    static final String[] DEFAULT_PROTOCOLS = TLSV13_PROTOCOLS;
+    private static final String[] SUPPORTED_PROTOCOLS = new String[] {
+            SUPPORTED_PROTOCOL_TLSV1,
+            SUPPORTED_PROTOCOL_TLSV1_1,
+            SUPPORTED_PROTOCOL_TLSV1_2,
+            SUPPORTED_PROTOCOL_TLSV1_3,
+    };;
+
+    static String[] getSupportedProtocols() {
+        return SUPPORTED_PROTOCOLS.clone();
+    }
+
+    private static class Range {
+        public final String min;
+        public final String max;
+        public Range(String min, String max) {
+            this.min = min;
+            this.max = max;
+        }
+    }
+
+    private static Range getProtocolRange(String[] protocols) {
+        // TLS protocol negotiation only allows a min and max version
+        // to be set, despite the Java API allowing a sparse set of
+        // protocols to be enabled.  Use the lowest contiguous range
+        // of protocols provided by the caller, which is what we've
+        // done historically.
+        List<String> protocolsList = Arrays.asList(protocols);
+        String min = null;
+        String max = null;
+        for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
+            String protocol = SUPPORTED_PROTOCOLS[i];
+            if (protocolsList.contains(protocol)) {
+                if (min == null) {
+                    min = protocol;
+                }
+                max = protocol;
+            } else if (min != null) {
+                break;
+            }
+        }
+        if ((min == null) || (max == null)) {
+            throw new IllegalArgumentException("No protocols enabled.");
+        }
+        return new Range(min, max);
+    }
+
+    static void setEnabledProtocols(long ssl, NativeSsl ssl_holder, String[] protocols) {
+        checkEnabledProtocols(protocols);
+        Range range = getProtocolRange(protocols);
+        SSL_set_protocol_versions(
+                ssl, ssl_holder, getProtocolConstant(range.min), getProtocolConstant(range.max));
+    }
+
+    private static int getProtocolConstant(String protocol) {
+        if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1)) {
+            return NativeConstants.TLS1_VERSION;
+        } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1)) {
+            return NativeConstants.TLS1_1_VERSION;
+        } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)) {
+            return NativeConstants.TLS1_2_VERSION;
+        } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_3)) {
+            return NativeConstants.TLS1_3_VERSION;
+        } else {
+            throw new AssertionError("Unknown protocol encountered: " + protocol);
+        }
+    }
+
+    static String[] checkEnabledProtocols(String[] protocols) {
+        if (protocols == null) {
+            throw new IllegalArgumentException("protocols == null");
+        }
+        for (String protocol : protocols) {
+            if (protocol == null) {
+                throw new IllegalArgumentException("protocols contains null");
+            }
+            if (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1)
+                    && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1)
+                    && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)
+                    && !protocol.equals(SUPPORTED_PROTOCOL_TLSV1_3)
+                    && !protocol.equals(OBSOLETE_PROTOCOL_SSLV3)) {
+                throw new IllegalArgumentException("protocol " + protocol + " is not supported");
+            }
+        }
+        return protocols;
+    }
+
+    static native void SSL_set_cipher_lists(long ssl, NativeSsl ssl_holder, String[] ciphers);
+
+    /**
+     * Gets the list of cipher suites enabled for the provided {@code SSL} instance.
+     *
+     * @return array of {@code SSL_CIPHER} references.
+     */
+    static native long[] SSL_get_ciphers(long ssl, NativeSsl ssl_holder);
+
+    static void setEnabledCipherSuites(
+            long ssl, NativeSsl ssl_holder, String[] cipherSuites, String[] protocols) {
+        checkEnabledCipherSuites(cipherSuites);
+        String maxProtocol = getProtocolRange(protocols).max;
+        List<String> opensslSuites = new ArrayList<String>();
+        for (int i = 0; i < cipherSuites.length; i++) {
+            String cipherSuite = cipherSuites[i];
+            if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
+                continue;
+            }
+            // Only send TLS_FALLBACK_SCSV if max version >= 1.2 to prevent inadvertent connection
+            // problems when servers upgrade.  See https://github.com/google/conscrypt/issues/574
+            // for more discussion.
+            if (cipherSuite.equals(TLS_FALLBACK_SCSV)
+                    && (maxProtocol.equals(SUPPORTED_PROTOCOL_TLSV1)
+                            || maxProtocol.equals(SUPPORTED_PROTOCOL_TLSV1_1))) {
+                SSL_set_mode(ssl, ssl_holder, NativeConstants.SSL_MODE_SEND_FALLBACK_SCSV);
+                continue;
+            }
+            opensslSuites.add(cipherSuiteFromJava(cipherSuite));
+        }
+        SSL_set_cipher_lists(ssl, ssl_holder, opensslSuites.toArray(new String[opensslSuites.size()]));
+    }
+
+    static String[] checkEnabledCipherSuites(String[] cipherSuites) {
+        if (cipherSuites == null) {
+            throw new IllegalArgumentException("cipherSuites == null");
+        }
+        // makes sure all suites are valid, throwing on error
+        for (int i = 0; i < cipherSuites.length; i++) {
+            if (cipherSuites[i] == null) {
+                throw new IllegalArgumentException("cipherSuites[" + i + "] == null");
+            }
+            if (cipherSuites[i].equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
+                    || cipherSuites[i].equals(TLS_FALLBACK_SCSV)) {
+                continue;
+            }
+            if (SUPPORTED_TLS_1_2_CIPHER_SUITES_SET.contains(cipherSuites[i])) {
+                continue;
+            }
+
+            // For backwards compatibility, it's allowed for |cipherSuite| to
+            // be an OpenSSL-style cipher-suite name.
+            if (SUPPORTED_LEGACY_CIPHER_SUITES_SET.contains(cipherSuites[i])) {
+                // TODO log warning about using backward compatability
+                continue;
+            }
+            throw new IllegalArgumentException(
+                    "cipherSuite " + cipherSuites[i] + " is not supported.");
+        }
+        return cipherSuites;
+    }
+
+    static native void SSL_set_accept_state(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_set_connect_state(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_set_verify(long ssl, NativeSsl ssl_holder, int mode);
+
+    static native void SSL_set_session(long ssl, NativeSsl ssl_holder, long sslSessionNativePointer)
+            throws SSLException;
+
+    static native void SSL_set_session_creation_enabled(
+            long ssl, NativeSsl ssl_holder, boolean creationEnabled) throws SSLException;
+
+    static native boolean SSL_session_reused(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_accept_renegotiations(long ssl, NativeSsl ssl_holder) throws SSLException;
+
+    static native void SSL_set_tlsext_host_name(long ssl, NativeSsl ssl_holder, String hostname)
+            throws SSLException;
+    static native String SSL_get_servername(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_do_handshake(
+            long ssl, NativeSsl ssl_holder, FileDescriptor fd, SSLHandshakeCallbacks shc, int timeoutMillis)
+            throws SSLException, SocketTimeoutException, CertificateException;
+
+    public static native String SSL_get_current_cipher(long ssl, NativeSsl ssl_holder);
+
+    public static native String SSL_get_version(long ssl, NativeSsl ssl_holder);
+
+    /**
+     * Returns the peer certificate chain.
+     */
+    static native byte[][] SSL_get0_peer_certificates(long ssl, NativeSsl ssl_holder);
+
+    /**
+     * Reads with the native SSL_read function from the encrypted data stream
+     * @return -1 if error or the end of the stream is reached.
+     */
+    static native int SSL_read(long ssl, NativeSsl ssl_holder, FileDescriptor fd, SSLHandshakeCallbacks shc,
+            byte[] b, int off, int len, int readTimeoutMillis) throws IOException;
+
+    /**
+     * Writes with the native SSL_write function to the encrypted data stream.
+     */
+    static native void SSL_write(long ssl, NativeSsl ssl_holder, FileDescriptor fd,
+            SSLHandshakeCallbacks shc, byte[] b, int off, int len, int writeTimeoutMillis)
+            throws IOException;
+
+    static native void SSL_interrupt(long ssl, NativeSsl ssl_holder);
+    static native void SSL_shutdown(
+            long ssl, NativeSsl ssl_holder, FileDescriptor fd, SSLHandshakeCallbacks shc) throws IOException;
+
+    static native int SSL_get_shutdown(long ssl, NativeSsl ssl_holder);
+
+    static native void SSL_free(long ssl, NativeSsl ssl_holder);
+
+    static native long SSL_get_time(long ssl, NativeSsl ssl_holder);
+
+    static native long SSL_set_timeout(long ssl, NativeSsl ssl_holder, long millis);
+
+    static native long SSL_get_timeout(long ssl, NativeSsl ssl_holder);
+
+    static native int SSL_get_signature_algorithm_key_type(int signatureAlg);
+
+    static native byte[] SSL_session_id(long ssl, NativeSsl ssl_holder);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] SSL_SESSION_session_id(long sslSessionNativePointer);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long SSL_SESSION_get_time(long sslSessionNativePointer);
+
+    static native long SSL_SESSION_get_timeout(long sslSessionNativePointer);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native String SSL_SESSION_get_version(long sslSessionNativePointer);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native String SSL_SESSION_cipher(long sslSessionNativePointer);
+
+    static native boolean SSL_SESSION_should_be_single_use(long sslSessionNativePointer);
+
+    static native void SSL_SESSION_up_ref(long sslSessionNativePointer);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native void SSL_SESSION_free(long sslSessionNativePointer);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native byte[] i2d_SSL_SESSION(long sslSessionNativePointer);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static native long d2i_SSL_SESSION(byte[] data) throws IOException;
+
+    /**
+     * A collection of callbacks from the native OpenSSL code that are
+     * related to the SSL handshake initiated by SSL_do_handshake.
+     */
+    interface SSLHandshakeCallbacks {
+        /**
+         * Verify that the certificate chain is trusted.
+         *
+         * @param certificateChain chain of X.509 certificates in their encoded form
+         * @param authMethod auth algorithm name
+         *
+         * @throws CertificateException if the certificate is untrusted
+         */
+        @SuppressWarnings("unused")
+        void verifyCertificateChain(byte[][] certificateChain, String authMethod)
+                throws CertificateException;
+
+        /**
+         * Called on an SSL client when the server requests (or
+         * requires a certificate). The client can respond by using
+         * SSL_use_certificate and SSL_use_PrivateKey to set a
+         * certificate if has an appropriate one available, similar to
+         * how the server provides its certificate.
+         *
+         * @param keyTypes key types supported by the server,
+         * convertible to strings with #keyType
+         * @param asn1DerEncodedX500Principals CAs known to the server
+         */
+        @SuppressWarnings("unused")
+        void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs,
+                byte[][] asn1DerEncodedX500Principals)
+                throws CertificateEncodingException, SSLException;
+
+        /**
+         * Gets the key to be used in client mode for this connection in Pre-Shared Key (PSK) key
+         * exchange.
+         *
+         * @param identityHint PSK identity hint provided by the server or {@code null} if no hint
+         *        provided.
+         * @param identity buffer to be populated with PSK identity (NULL-terminated modified UTF-8)
+         *        by this method. This identity will be provided to the server.
+         * @param key buffer to be populated with key material by this method.
+         *
+         * @return number of bytes this method stored in the {@code key} buffer or {@code 0} if an
+         *         error occurred in which case the handshake will be aborted.
+         */
+        int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key);
+
+        /**
+         * Gets the key to be used in server mode for this connection in Pre-Shared Key (PSK) key
+         * exchange.
+         *
+         * @param identityHint PSK identity hint provided by this server to the client or
+         *        {@code null} if no hint was provided.
+         * @param identity PSK identity provided by the client.
+         * @param key buffer to be populated with key material by this method.
+         *
+         * @return number of bytes this method stored in the {@code key} buffer or {@code 0} if an
+         *         error occurred in which case the handshake will be aborted.
+         */
+        int serverPSKKeyRequested(String identityHint, String identity, byte[] key);
+
+        /**
+         * Called when SSL state changes. This could be handshake completion.
+         */
+        @SuppressWarnings("unused")
+        void onSSLStateChange(int type, int val);
+
+        /**
+         * Called when a new session has been established and may be added to the session cache.
+         * The callee is responsible for incrementing the reference count on the returned session.
+         */
+        @SuppressWarnings("unused")
+        void onNewSessionEstablished(long sslSessionNativePtr);
+
+        /**
+         * Called for servers where TLS < 1.3 (TLS 1.3 uses session tickets rather than
+         * application session caches).
+         *
+         * <p/>Looks up the session by ID in the application's session cache. If a valid session
+         * is returned, this callback is responsible for incrementing the reference count (and any
+         * required synchronization).
+         *
+         * @param id the ID of the session to find.
+         * @return the cached session or {@code 0} if no session was found matching the given ID.
+         */
+        @SuppressWarnings("unused")
+        long serverSessionRequested(byte[] id);
+    }
+
+    static native String SSL_CIPHER_get_kx_name(long cipherAddress);
+
+    static native String[] get_cipher_names(String selection);
+
+    public static native byte[] get_ocsp_single_extension(
+            byte[] ocspResponse, String oid, long x509Ref, OpenSSLX509Certificate holder, long issuerX509Ref, OpenSSLX509Certificate holder2);
+
+    /**
+     * Returns the starting address of the memory region referenced by the provided direct
+     * {@link Buffer} or {@code 0} if the provided buffer is not direct or if such access to direct
+     * buffers is not supported by the platform.
+     *
+     * <p>NOTE: This method ignores the buffer's current {@code position}.
+     */
+    static native long getDirectBufferAddress(Buffer buf);
+
+    static native long SSL_BIO_new(long ssl, NativeSsl ssl_holder) throws SSLException;
+
+    static native int SSL_get_error(long ssl, NativeSsl ssl_holder, int ret);
+
+    static native void SSL_clear_error();
+
+    static native int SSL_pending_readable_bytes(long ssl, NativeSsl ssl_holder);
+
+    static native int SSL_pending_written_bytes_in_BIO(long bio);
+
+    /**
+     * Returns the maximum overhead, in bytes, of sealing a record with SSL.
+     */
+    static native int SSL_max_seal_overhead(long ssl, NativeSsl ssl_holder);
+
+    /**
+     * Enables ALPN for this TLS endpoint and sets the list of supported ALPN protocols in
+     * wire-format (length-prefixed 8-bit strings).
+     */
+    static native void setApplicationProtocols(
+            long ssl, NativeSsl ssl_holder, boolean client, byte[] protocols) throws IOException;
+
+    /**
+     * Called for a server endpoint only. Enables ALPN and sets a BiFunction that will
+     * be called to delegate protocol selection to the application. Calling this method overrides
+     * {@link #setApplicationProtocols(long, NativeSsl, boolean, byte[])}.
+     */
+    static native void setApplicationProtocolSelector(
+            long ssl, NativeSsl ssl_holder, ApplicationProtocolSelectorAdapter selector) throws IOException;
+
+    /**
+     * Returns the selected ALPN protocol. If the server did not select a
+     * protocol, {@code null} will be returned.
+     */
+    static native byte[] getApplicationProtocol(long ssl, NativeSsl ssl_holder);
+
+    /**
+     * Variant of the {@link #SSL_do_handshake} used by {@link ConscryptEngine}. This differs
+     * slightly from the raw BoringSSL API in that it returns the SSL error code from the
+     * operation, rather than the return value from {@code SSL_do_handshake}. This is done in
+     * order to allow to properly handle SSL errors and propagate useful exceptions.
+     *
+     * @return Returns the SSL error code for the operation when the error was {@code
+     * SSL_ERROR_NONE}, {@code SSL_ERROR_WANT_READ}, or {@code SSL_ERROR_WANT_WRITE}.
+     * @throws IOException when the error code is anything except those returned by this method.
+     */
+    static native int ENGINE_SSL_do_handshake(long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc)
+            throws IOException;
+
+    /**
+     * Variant of the {@link #SSL_read} for a direct {@link java.nio.ByteBuffer} used by {@link
+     * ConscryptEngine}.
+     *
+     * @return if positive, represents the number of bytes read into the given buffer.
+     * Returns {@code -SSL_ERROR_WANT_READ} if more data is needed. Returns
+     * {@code -SSL_ERROR_WANT_WRITE} if data needs to be written out to flush the BIO.
+     *
+     * @throws java.io.InterruptedIOException if the read was interrupted.
+     * @throws java.io.EOFException if the end of stream has been reached.
+     * @throws CertificateException if the application's certificate verification callback failed.
+     * Only occurs during handshake processing.
+     * @throws SSLException if any other error occurs.
+     */
+    static native int ENGINE_SSL_read_direct(long ssl, NativeSsl ssl_holder, long address, int length,
+            SSLHandshakeCallbacks shc) throws IOException, CertificateException;
+
+    /**
+     * Variant of the {@link #SSL_write} for a direct {@link java.nio.ByteBuffer} used by {@link
+     * ConscryptEngine}. This version does not lock or and does no error pre-processing.
+     */
+    static native int ENGINE_SSL_write_direct(long ssl, NativeSsl ssl_holder, long address, int length,
+            SSLHandshakeCallbacks shc) throws IOException;
+
+    /**
+     * Writes data from the given direct {@link java.nio.ByteBuffer} to the BIO.
+     */
+    static native int ENGINE_SSL_write_BIO_direct(long ssl, NativeSsl ssl_holder, long bioRef, long pos, int length,
+            SSLHandshakeCallbacks shc) throws IOException;
+
+    /**
+     * Writes data from the given array to the BIO.
+     */
+    static native int ENGINE_SSL_write_BIO_heap(long ssl, NativeSsl ssl_holder, long bioRef, byte[] sourceJava,
+            int sourceOffset, int sourceLength, SSLHandshakeCallbacks shc)
+            throws IOException, IndexOutOfBoundsException;
+
+    /**
+     * Reads data from the given BIO into a direct {@link java.nio.ByteBuffer}.
+     */
+    static native int ENGINE_SSL_read_BIO_direct(long ssl, NativeSsl ssl_holder, long bioRef, long address, int len,
+            SSLHandshakeCallbacks shc) throws IOException;
+
+    /**
+     * Reads data from the given BIO into an array.
+     */
+    static native int ENGINE_SSL_read_BIO_heap(long ssl, NativeSsl ssl_holder, long bioRef, byte[] destJava,
+            int destOffset, int destLength, SSLHandshakeCallbacks shc)
+            throws IOException, IndexOutOfBoundsException;
+
+    /**
+     * Forces the SSL object to process any data pending in the BIO.
+     */
+    static native void ENGINE_SSL_force_read(long ssl, NativeSsl ssl_holder,
+            SSLHandshakeCallbacks shc) throws IOException;
+
+    /**
+     * Variant of the {@link #SSL_shutdown} used by {@link ConscryptEngine}. This version does not
+     * lock.
+     */
+    static native void ENGINE_SSL_shutdown(long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc)
+            throws IOException;
+
+    /**
+     * Used for testing only.
+     */
+    static native int BIO_read(long bioRef, byte[] buffer) throws IOException;
+    static native void BIO_write(long bioRef, byte[] buffer, int offset, int length)
+            throws IOException, IndexOutOfBoundsException;
+    static native long SSL_clear_mode(long ssl, NativeSsl ssl_holder, long mode);
+    static native long SSL_get_mode(long ssl, NativeSsl ssl_holder);
+    static native long SSL_get_options(long ssl, NativeSsl ssl_holder);
+    static native long SSL_get1_session(long ssl, NativeSsl ssl_holder);
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeRef.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeRef.java
new file mode 100644
index 0000000..cc981c2
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeRef.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+/**
+ * Used to hold onto native OpenSSL references and run finalization on those
+ * objects. Individual types must subclass this and implement finalizer.
+ */
+abstract class NativeRef {
+    final long address;
+
+    NativeRef(long address) {
+        if (address == 0) {
+            throw new NullPointerException("address == 0");
+        }
+
+        this.address = address;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof NativeRef)) {
+            return false;
+        }
+
+        return ((NativeRef) o).address == address;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) (address ^ (address >>> 32));
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (address != 0) {
+                doFree(address);
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+
+    abstract void doFree(long context);
+
+    static final class EC_GROUP extends NativeRef {
+        EC_GROUP(long ctx) {
+            super(ctx);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.EC_GROUP_clear_free(context);
+        }
+    }
+
+    static final class EC_POINT extends NativeRef {
+        EC_POINT(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.EC_POINT_clear_free(context);
+        }
+    }
+
+    static final class EVP_CIPHER_CTX extends NativeRef {
+        EVP_CIPHER_CTX(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.EVP_CIPHER_CTX_free(context);
+        }
+    }
+
+    static final class EVP_MD_CTX extends NativeRef {
+        EVP_MD_CTX(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.EVP_MD_CTX_destroy(context);
+        }
+    }
+
+    static final class EVP_PKEY extends NativeRef {
+        EVP_PKEY(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.EVP_PKEY_free(context);
+        }
+    }
+
+    static final class EVP_PKEY_CTX extends NativeRef {
+        EVP_PKEY_CTX(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.EVP_PKEY_CTX_free(context);
+        }
+    }
+
+    static final class HMAC_CTX extends NativeRef {
+        HMAC_CTX(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.HMAC_CTX_free(context);
+        }
+    }
+
+    static final class SSL_SESSION extends NativeRef {
+        SSL_SESSION(long nativePointer) {
+            super(nativePointer);
+        }
+
+        @Override
+        void doFree(long context) {
+            NativeCrypto.SSL_SESSION_free(context);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java
new file mode 100644
index 0000000..a6d5a32
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSsl.java
@@ -0,0 +1,662 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.NativeConstants.SSL_MODE_CBC_RECORD_SPLITTING;
+import static com.android.org.conscrypt.NativeConstants.SSL_OP_CIPHER_SERVER_PREFERENCE;
+import static com.android.org.conscrypt.NativeConstants.SSL_OP_NO_TICKET;
+import static com.android.org.conscrypt.NativeConstants.SSL_RECEIVED_SHUTDOWN;
+import static com.android.org.conscrypt.NativeConstants.SSL_SENT_SHUTDOWN;
+import static com.android.org.conscrypt.NativeConstants.SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+import static com.android.org.conscrypt.NativeConstants.SSL_VERIFY_NONE;
+import static com.android.org.conscrypt.NativeConstants.SSL_VERIFY_PEER;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.SocketException;
+import java.nio.charset.Charset;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import javax.crypto.SecretKey;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.NativeCrypto.SSLHandshakeCallbacks;
+import com.android.org.conscrypt.SSLParametersImpl.AliasChooser;
+import com.android.org.conscrypt.SSLParametersImpl.PSKCallbacks;
+
+/**
+ * A utility wrapper that abstracts operations on the underlying native SSL instance.
+ */
+final class NativeSsl {
+    private final SSLParametersImpl parameters;
+    private final SSLHandshakeCallbacks handshakeCallbacks;
+    private final AliasChooser aliasChooser;
+    private final PSKCallbacks pskCallbacks;
+    private X509Certificate[] localCertificates;
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+    private volatile long ssl;
+
+    private NativeSsl(long ssl, SSLParametersImpl parameters,
+            SSLHandshakeCallbacks handshakeCallbacks, AliasChooser aliasChooser,
+            PSKCallbacks pskCallbacks) {
+        this.ssl = ssl;
+        this.parameters = parameters;
+        this.handshakeCallbacks = handshakeCallbacks;
+        this.aliasChooser = aliasChooser;
+        this.pskCallbacks = pskCallbacks;
+    }
+
+    static NativeSsl newInstance(SSLParametersImpl parameters,
+            SSLHandshakeCallbacks handshakeCallbacks, AliasChooser chooser,
+            PSKCallbacks pskCallbacks) throws SSLException {
+        AbstractSessionContext ctx = parameters.getSessionContext();
+        long ssl = NativeCrypto.SSL_new(ctx.sslCtxNativePointer, ctx);
+        return new NativeSsl(ssl, parameters, handshakeCallbacks, chooser, pskCallbacks);
+    }
+
+    BioWrapper newBio() {
+        try {
+            return new BioWrapper();
+        } catch (SSLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    void offerToResumeSession(long sslSessionNativePointer) throws SSLException {
+        NativeCrypto.SSL_set_session(ssl, this, sslSessionNativePointer);
+    }
+
+    byte[] getSessionId() {
+        return NativeCrypto.SSL_session_id(ssl, this);
+    }
+
+    long getTime() {
+        return NativeCrypto.SSL_get_time(ssl, this);
+    }
+
+    long getTimeout() {
+        return NativeCrypto.SSL_get_timeout(ssl, this);
+    }
+
+    void setTimeout(long millis) {
+        NativeCrypto.SSL_set_timeout(ssl, this, millis);
+    }
+
+    String getCipherSuite() {
+        return NativeCrypto.cipherSuiteToJava(NativeCrypto.SSL_get_current_cipher(ssl, this));
+    }
+
+    X509Certificate[] getPeerCertificates() throws CertificateException {
+        byte[][] encoded = NativeCrypto.SSL_get0_peer_certificates(ssl, this);
+        return encoded == null ? null : SSLUtils.decodeX509CertificateChain(encoded);
+    }
+
+    X509Certificate[] getLocalCertificates() {
+        return localCertificates;
+    }
+
+    byte[] getPeerCertificateOcspData() {
+        return NativeCrypto.SSL_get_ocsp_response(ssl, this);
+    }
+
+    byte[] getTlsUnique() {
+        return NativeCrypto.SSL_get_tls_unique(ssl, this);
+    }
+
+    byte[] exportKeyingMaterial(String label, byte[] context, int length) throws SSLException {
+        if (label == null) {
+            throw new NullPointerException("Label is null");
+        }
+        byte[] labelBytes = label.getBytes(Charset.forName("US-ASCII"));
+        return NativeCrypto.SSL_export_keying_material(ssl, this, labelBytes, context, length);
+    }
+
+    byte[] getPeerTlsSctData() {
+        return NativeCrypto.SSL_get_signed_cert_timestamp_list(ssl, this);
+    }
+
+    /**
+     * @see NativeCrypto.SSLHandshakeCallbacks#clientPSKKeyRequested(String, byte[], byte[])
+     */
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    int clientPSKKeyRequested(String identityHint, byte[] identityBytesOut, byte[] key) {
+        PSKKeyManager pskKeyManager = parameters.getPSKKeyManager();
+        if (pskKeyManager == null) {
+            return 0;
+        }
+
+        String identity = pskCallbacks.chooseClientPSKIdentity(pskKeyManager, identityHint);
+        // Store identity in NULL-terminated modified UTF-8 representation into ientityBytesOut
+        byte[] identityBytes;
+        if (identity == null) {
+            identity = "";
+            identityBytes = EmptyArray.BYTE;
+        } else if (identity.isEmpty()) {
+            identityBytes = EmptyArray.BYTE;
+        } else {
+            try {
+                identityBytes = identity.getBytes("UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException("UTF-8 encoding not supported", e);
+            }
+        }
+        if (identityBytes.length + 1 > identityBytesOut.length) {
+            // Insufficient space in the output buffer
+            return 0;
+        }
+        if (identityBytes.length > 0) {
+            System.arraycopy(identityBytes, 0, identityBytesOut, 0, identityBytes.length);
+        }
+        identityBytesOut[identityBytes.length] = 0;
+
+        SecretKey secretKey = pskCallbacks.getPSKKey(pskKeyManager, identityHint, identity);
+        byte[] secretKeyBytes = secretKey.getEncoded();
+        if (secretKeyBytes == null) {
+            return 0;
+        } else if (secretKeyBytes.length > key.length) {
+            // Insufficient space in the output buffer
+            return 0;
+        }
+        System.arraycopy(secretKeyBytes, 0, key, 0, secretKeyBytes.length);
+        return secretKeyBytes.length;
+    }
+
+    /**
+     * @see NativeCrypto.SSLHandshakeCallbacks#serverPSKKeyRequested(String, String, byte[])
+     */
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    int serverPSKKeyRequested(String identityHint, String identity, byte[] key) {
+        PSKKeyManager pskKeyManager = parameters.getPSKKeyManager();
+        if (pskKeyManager == null) {
+            return 0;
+        }
+        SecretKey secretKey = pskCallbacks.getPSKKey(pskKeyManager, identityHint, identity);
+        byte[] secretKeyBytes = secretKey.getEncoded();
+        if (secretKeyBytes == null) {
+            return 0;
+        } else if (secretKeyBytes.length > key.length) {
+            return 0;
+        }
+        System.arraycopy(secretKeyBytes, 0, key, 0, secretKeyBytes.length);
+        return secretKeyBytes.length;
+    }
+
+    void chooseClientCertificate(byte[] keyTypeBytes, int[] signatureAlgs,
+            byte[][] asn1DerEncodedPrincipals)
+            throws SSLException, CertificateEncodingException {
+        Set<String> keyTypesSet = SSLUtils.getSupportedClientKeyTypes(keyTypeBytes, signatureAlgs);
+        String[] keyTypes = keyTypesSet.toArray(new String[keyTypesSet.size()]);
+
+        X500Principal[] issuers;
+        if (asn1DerEncodedPrincipals == null) {
+            issuers = null;
+        } else {
+            issuers = new X500Principal[asn1DerEncodedPrincipals.length];
+            for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) {
+                issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]);
+            }
+        }
+        X509KeyManager keyManager = parameters.getX509KeyManager();
+        String alias = (keyManager != null)
+                ? aliasChooser.chooseClientAlias(keyManager, issuers, keyTypes)
+                : null;
+        setCertificate(alias);
+    }
+
+    void setCertificate(String alias) throws CertificateEncodingException, SSLException {
+        if (alias == null) {
+            return;
+        }
+        X509KeyManager keyManager = parameters.getX509KeyManager();
+        if (keyManager == null) {
+            return;
+        }
+        PrivateKey privateKey = keyManager.getPrivateKey(alias);
+        if (privateKey == null) {
+            return;
+        }
+        localCertificates = keyManager.getCertificateChain(alias);
+        if (localCertificates == null) {
+            return;
+        }
+        int numLocalCerts = localCertificates.length;
+        PublicKey publicKey = (numLocalCerts > 0) ? localCertificates[0].getPublicKey() : null;
+
+        // Encode the local certificates.
+        byte[][] encodedLocalCerts = new byte[numLocalCerts][];
+        for (int i = 0; i < numLocalCerts; ++i) {
+            encodedLocalCerts[i] = localCertificates[i].getEncoded();
+        }
+
+        // Convert the key so we can access a native reference.
+        final OpenSSLKey key;
+        try {
+            key = OpenSSLKey.fromPrivateKeyForTLSStackOnly(privateKey, publicKey);
+        } catch (InvalidKeyException e) {
+            throw new SSLException(e);
+        }
+
+        // Set the local certs and private key.
+        NativeCrypto.setLocalCertsAndPrivateKey(ssl, this, encodedLocalCerts, key.getNativeRef());
+    }
+
+    String getVersion() {
+        return NativeCrypto.SSL_get_version(ssl, this);
+    }
+
+    String getRequestedServerName() {
+        return NativeCrypto.SSL_get_servername(ssl, this);
+    }
+
+    byte[] getTlsChannelId() throws SSLException {
+        return NativeCrypto.SSL_get_tls_channel_id(ssl, this);
+    }
+
+    void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOException {
+        boolean enableSessionCreation = parameters.getEnableSessionCreation();
+        if (!enableSessionCreation) {
+            NativeCrypto.SSL_set_session_creation_enabled(ssl, this, false);
+        }
+
+        // Allow servers to trigger renegotiation. Some inadvisable server
+        // configurations cause them to attempt to renegotiate during
+        // certain protocols.
+        NativeCrypto.SSL_accept_renegotiations(ssl, this);
+
+        if (isClient()) {
+            NativeCrypto.SSL_set_connect_state(ssl, this);
+
+            // Configure OCSP and CT extensions for client
+            NativeCrypto.SSL_enable_ocsp_stapling(ssl, this);
+            if (parameters.isCTVerificationEnabled(hostname)) {
+                NativeCrypto.SSL_enable_signed_cert_timestamps(ssl, this);
+            }
+        } else {
+            NativeCrypto.SSL_set_accept_state(ssl, this);
+
+            // Configure OCSP for server
+            if (parameters.getOCSPResponse() != null) {
+                NativeCrypto.SSL_enable_ocsp_stapling(ssl, this);
+            }
+        }
+
+        if (parameters.getEnabledProtocols().length == 0 && parameters.isEnabledProtocolsFiltered) {
+            throw new SSLHandshakeException("No enabled protocols; "
+                    + NativeCrypto.OBSOLETE_PROTOCOL_SSLV3
+                    + " is no longer supported and was filtered from the list");
+        }
+        NativeCrypto.setEnabledProtocols(ssl, this, parameters.enabledProtocols);
+        NativeCrypto.setEnabledCipherSuites(
+                ssl, this, parameters.enabledCipherSuites, parameters.enabledProtocols);
+
+        if (parameters.applicationProtocols.length > 0) {
+            NativeCrypto.setApplicationProtocols(ssl, this, isClient(), parameters.applicationProtocols);
+        }
+        if (!isClient() && parameters.applicationProtocolSelector != null) {
+            NativeCrypto.setApplicationProtocolSelector(ssl, this, parameters.applicationProtocolSelector);
+        }
+
+        // setup server certificates and private keys.
+        // clients will receive a call back to request certificates.
+        if (!isClient()) {
+            Set<String> keyTypes = new HashSet<String>();
+            for (long sslCipherNativePointer : NativeCrypto.SSL_get_ciphers(ssl, this)) {
+                String keyType = SSLUtils.getServerX509KeyType(sslCipherNativePointer);
+                if (keyType != null) {
+                    keyTypes.add(keyType);
+                }
+            }
+            X509KeyManager keyManager = parameters.getX509KeyManager();
+            if (keyManager != null) {
+                for (String keyType : keyTypes) {
+                    try {
+                        setCertificate(aliasChooser.chooseServerAlias(keyManager, keyType));
+                    } catch (CertificateEncodingException e) {
+                        throw new IOException(e);
+                    }
+                }
+            }
+
+            NativeCrypto.SSL_set_options(ssl, this, SSL_OP_CIPHER_SERVER_PREFERENCE);
+
+            if (parameters.sctExtension != null) {
+                NativeCrypto.SSL_set_signed_cert_timestamp_list(ssl, this, parameters.sctExtension);
+            }
+
+            if (parameters.ocspResponse != null) {
+                NativeCrypto.SSL_set_ocsp_response(ssl, this, parameters.ocspResponse);
+            }
+        }
+
+        enablePSKKeyManagerIfRequested();
+
+        if (parameters.useSessionTickets) {
+            NativeCrypto.SSL_clear_options(ssl, this, SSL_OP_NO_TICKET);
+        } else {
+            NativeCrypto.SSL_set_options(
+                    ssl, this, NativeCrypto.SSL_get_options(ssl, this) | SSL_OP_NO_TICKET);
+        }
+
+        if (parameters.getUseSni() && AddressUtils.isValidSniHostname(hostname)) {
+            NativeCrypto.SSL_set_tlsext_host_name(ssl, this, hostname);
+        }
+
+        // BEAST attack mitigation (1/n-1 record splitting for CBC cipher suites
+        // with TLSv1 and SSLv3).
+        NativeCrypto.SSL_set_mode(ssl, this, SSL_MODE_CBC_RECORD_SPLITTING);
+
+        setCertificateValidation();
+        setTlsChannelId(channelIdPrivateKey);
+    }
+
+    // TODO(nathanmittler): Remove once after we switch to the engine socket.
+    void doHandshake(FileDescriptor fd, int timeoutMillis)
+            throws CertificateException, IOException {
+        lock.readLock().lock();
+        try {
+            if (isClosed() || fd == null || !fd.valid()) {
+                throw new SocketException("Socket is closed");
+            }
+            NativeCrypto.SSL_do_handshake(ssl, this, fd, handshakeCallbacks, timeoutMillis);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    int doHandshake() throws IOException {
+        lock.readLock().lock();
+        try {
+            return NativeCrypto.ENGINE_SSL_do_handshake(ssl, this, handshakeCallbacks);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    // TODO(nathanmittler): Remove once after we switch to the engine socket.
+    int read(FileDescriptor fd, byte[] buf, int offset, int len, int timeoutMillis)
+            throws IOException {
+        lock.readLock().lock();
+        try {
+            if (isClosed() || fd == null || !fd.valid()) {
+                throw new SocketException("Socket is closed");
+            }
+            return NativeCrypto
+                    .SSL_read(ssl, this, fd, handshakeCallbacks, buf, offset, len, timeoutMillis);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    // TODO(nathanmittler): Remove once after we switch to the engine socket.
+    void write(FileDescriptor fd, byte[] buf, int offset, int len, int timeoutMillis)
+            throws IOException {
+        lock.readLock().lock();
+        try {
+            if (isClosed() || fd == null || !fd.valid()) {
+                throw new SocketException("Socket is closed");
+            }
+            NativeCrypto
+                    .SSL_write(ssl, this, fd, handshakeCallbacks, buf, offset, len, timeoutMillis);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    private void enablePSKKeyManagerIfRequested() throws SSLException {
+        // Enable Pre-Shared Key (PSK) key exchange if requested
+        PSKKeyManager pskKeyManager = parameters.getPSKKeyManager();
+        if (pskKeyManager != null) {
+            boolean pskEnabled = false;
+            for (String enabledCipherSuite : parameters.enabledCipherSuites) {
+                if ((enabledCipherSuite != null) && enabledCipherSuite.contains("PSK")) {
+                    pskEnabled = true;
+                    break;
+                }
+            }
+            if (pskEnabled) {
+                if (isClient()) {
+                    NativeCrypto.set_SSL_psk_client_callback_enabled(ssl, this, true);
+                } else {
+                    NativeCrypto.set_SSL_psk_server_callback_enabled(ssl, this, true);
+                    String identityHint = pskCallbacks.chooseServerPSKIdentityHint(pskKeyManager);
+                    NativeCrypto.SSL_use_psk_identity_hint(ssl, this, identityHint);
+                }
+            }
+        }
+    }
+
+    private void setTlsChannelId(OpenSSLKey channelIdPrivateKey) throws SSLException {
+        if (!parameters.channelIdEnabled) {
+            return;
+        }
+
+        if (parameters.getUseClientMode()) {
+            // Client-side TLS Channel ID
+            if (channelIdPrivateKey == null) {
+                throw new SSLHandshakeException("Invalid TLS channel ID key specified");
+            }
+            NativeCrypto.SSL_set1_tls_channel_id(ssl, this, channelIdPrivateKey.getNativeRef());
+        } else {
+            // Server-side TLS Channel ID
+            NativeCrypto.SSL_enable_tls_channel_id(ssl, this);
+        }
+    }
+
+    private void setCertificateValidation() throws SSLException {
+        // setup peer certificate verification
+        if (!isClient()) {
+            // needing client auth takes priority...
+            boolean certRequested;
+            if (parameters.getNeedClientAuth()) {
+                NativeCrypto.SSL_set_verify(ssl, this, SSL_VERIFY_PEER
+                                | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
+                certRequested = true;
+                // ... over just wanting it...
+            } else if (parameters.getWantClientAuth()) {
+                NativeCrypto.SSL_set_verify(ssl, this, SSL_VERIFY_PEER);
+                certRequested = true;
+                // ... and we must disable verification if we don't want client auth.
+            } else {
+                NativeCrypto.SSL_set_verify(ssl, this, SSL_VERIFY_NONE);
+                certRequested = false;
+            }
+
+            if (certRequested) {
+                X509TrustManager trustManager = parameters.getX509TrustManager();
+                X509Certificate[] issuers = trustManager.getAcceptedIssuers();
+                if (issuers != null && issuers.length != 0) {
+                    byte[][] issuersBytes;
+                    try {
+                        issuersBytes = SSLUtils.encodeSubjectX509Principals(issuers);
+                    } catch (CertificateEncodingException e) {
+                        throw new SSLException("Problem encoding principals", e);
+                    }
+                    NativeCrypto.SSL_set_client_CA_list(ssl, this, issuersBytes);
+                }
+            }
+        }
+    }
+
+    void interrupt() {
+        NativeCrypto.SSL_interrupt(ssl, this);
+    }
+
+    // TODO(nathanmittler): Remove once after we switch to the engine socket.
+    void shutdown(FileDescriptor fd) throws IOException {
+        NativeCrypto.SSL_shutdown(ssl, this, fd, handshakeCallbacks);
+    }
+
+    void shutdown() throws IOException {
+        lock.readLock().lock();
+        try {
+            NativeCrypto.ENGINE_SSL_shutdown(ssl, this, handshakeCallbacks);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    boolean wasShutdownReceived() {
+        lock.readLock().lock();
+        try {
+            return (NativeCrypto.SSL_get_shutdown(ssl, this) & SSL_RECEIVED_SHUTDOWN) != 0;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    boolean wasShutdownSent() {
+        lock.readLock().lock();
+        try {
+            return (NativeCrypto.SSL_get_shutdown(ssl, this) & SSL_SENT_SHUTDOWN) != 0;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    int readDirectByteBuffer(long destAddress, int destLength)
+            throws IOException, CertificateException {
+        lock.readLock().lock();
+        try {
+            return NativeCrypto.ENGINE_SSL_read_direct(
+                    ssl, this, destAddress, destLength, handshakeCallbacks);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    int writeDirectByteBuffer(long sourceAddress, int sourceLength) throws IOException {
+        lock.readLock().lock();
+        try {
+            return NativeCrypto.ENGINE_SSL_write_direct(
+                    ssl, this, sourceAddress, sourceLength, handshakeCallbacks);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    void forceRead() throws IOException {
+        lock.readLock().lock();
+        try {
+            NativeCrypto.ENGINE_SSL_force_read(ssl, this, handshakeCallbacks);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    int getPendingReadableBytes() {
+        lock.readLock().lock();
+        try {
+            if (!isClosed()) {
+                return NativeCrypto.SSL_pending_readable_bytes(ssl, this);
+            }
+            return 0;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    int getMaxSealOverhead() {
+        return NativeCrypto.SSL_max_seal_overhead(ssl, this);
+    }
+
+    void close() {
+        lock.writeLock().lock();
+        try {
+            if (!isClosed()) {
+                long toFree = ssl;
+                ssl = 0L;
+                NativeCrypto.SSL_free(toFree, this);
+            }
+        } finally {
+            lock.writeLock().unlock();
+        }
+    }
+
+    boolean isClosed() {
+        return ssl == 0L;
+    }
+
+    int getError(int result) {
+        return NativeCrypto.SSL_get_error(ssl, this, result);
+    }
+
+    byte[] getApplicationProtocol() {
+        return NativeCrypto.getApplicationProtocol(ssl, this);
+    }
+
+    private boolean isClient() {
+        return parameters.getUseClientMode();
+    }
+
+    @Override
+    protected final void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * A utility wrapper that abstracts operations on the underlying native BIO instance.
+     */
+    final class BioWrapper {
+        private volatile long bio;
+
+        private BioWrapper() throws SSLException {
+            this.bio = NativeCrypto.SSL_BIO_new(ssl, NativeSsl.this);
+        }
+
+        int getPendingWrittenBytes() {
+            if (bio != 0) {
+                return NativeCrypto.SSL_pending_written_bytes_in_BIO(bio);
+            } else {
+                return 0;
+            }
+        }
+
+        int writeDirectByteBuffer(long address, int length) throws IOException {
+            return NativeCrypto.ENGINE_SSL_write_BIO_direct(
+                    ssl, NativeSsl.this, bio, address, length, handshakeCallbacks);
+        }
+
+        int readDirectByteBuffer(long destAddress, int destLength) throws IOException {
+            return NativeCrypto.ENGINE_SSL_read_BIO_direct(
+                    ssl, NativeSsl.this, bio, destAddress, destLength, handshakeCallbacks);
+        }
+
+        void close() {
+            long toFree = bio;
+            bio = 0L;
+            NativeCrypto.BIO_free_all(toFree);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSslSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSslSession.java
new file mode 100644
index 0000000..5ed56e1
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeSslSession.java
@@ -0,0 +1,485 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License", "www.google.com", 443);
+ * 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.SSLUtils.SessionType.OPEN_SSL_WITH_OCSP;
+import static com.android.org.conscrypt.SSLUtils.SessionType.OPEN_SSL_WITH_TLS_SCT;
+import static com.android.org.conscrypt.SSLUtils.SessionType.isSupportedType;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.X509Certificate;
+
+/**
+ * A utility wrapper that abstracts operations on the underlying native SSL_SESSION instance.
+ *
+ * This is abstract only to support mocking for tests.
+ */
+abstract class NativeSslSession {
+    private static final Logger logger = Logger.getLogger(NativeSslSession.class.getName());
+
+    /**
+     * Creates a new instance. Since BoringSSL does not provide an API to get access to all
+     * session information via the SSL_SESSION, we get some values (e.g. peer certs) from
+     * the {@link ConscryptSession} instead (i.e. the SSL object).
+     */
+    static NativeSslSession newInstance(NativeRef.SSL_SESSION ref, ConscryptSession session)
+            throws SSLPeerUnverifiedException {
+        AbstractSessionContext context = (AbstractSessionContext) session.getSessionContext();
+        if (context instanceof ClientSessionContext) {
+            return new Impl(context, ref, session.getPeerHost(), session.getPeerPort(),
+                session.getPeerCertificates(), getOcspResponse(session),
+                session.getPeerSignedCertificateTimestamp());
+        }
+
+        // Server's will be cached by ID and won't have any of the extra fields.
+        return new Impl(context, ref, null, -1, null, null, null);
+    }
+
+    private static byte[] getOcspResponse(ConscryptSession session) {
+        List<byte[]> ocspResponseList = session.getStatusResponses();
+        if (ocspResponseList.size() >= 1) {
+            return ocspResponseList.get(0);
+        }
+        return null;
+    }
+
+    /**
+     * Creates a new {@link NativeSslSession} instance from the provided serialized bytes, which
+     * were generated by {@link #toBytes()}.
+     *
+     * @return The new instance if successful. If unable to parse the bytes for any reason, returns
+     * {@code null}.
+     */
+    static NativeSslSession newInstance(
+            AbstractSessionContext context, byte[] data, String host, int port) {
+        ByteBuffer buf = ByteBuffer.wrap(data);
+        try {
+            int type = buf.getInt();
+            if (!isSupportedType(type)) {
+                throw new IOException("Unexpected type ID: " + type);
+            }
+
+            int length = buf.getInt();
+            checkRemaining(buf, length);
+
+            byte[] sessionData = new byte[length];
+            buf.get(sessionData);
+
+            int count = buf.getInt();
+            checkRemaining(buf, count);
+
+            java.security.cert.X509Certificate[] peerCerts =
+                    new java.security.cert.X509Certificate[count];
+            for (int i = 0; i < count; i++) {
+                length = buf.getInt();
+                checkRemaining(buf, length);
+
+                byte[] certData = new byte[length];
+                buf.get(certData);
+                try {
+                    peerCerts[i] = OpenSSLX509Certificate.fromX509Der(certData);
+                } catch (Exception e) {
+                    throw new IOException("Can not read certificate " + i + "/" + count);
+                }
+            }
+
+            byte[] ocspData = null;
+            if (type >= OPEN_SSL_WITH_OCSP.value) {
+                // We only support one OCSP response now, but in the future
+                // we may support RFC 6961 which has multiple.
+                int countOcspResponses = buf.getInt();
+                checkRemaining(buf, countOcspResponses);
+
+                if (countOcspResponses >= 1) {
+                    int ocspLength = buf.getInt();
+                    checkRemaining(buf, ocspLength);
+
+                    ocspData = new byte[ocspLength];
+                    buf.get(ocspData);
+
+                    // Skip the rest of the responses.
+                    for (int i = 1; i < countOcspResponses; i++) {
+                        ocspLength = buf.getInt();
+                        checkRemaining(buf, ocspLength);
+                        buf.position(buf.position() + ocspLength);
+                    }
+                }
+            }
+
+            byte[] tlsSctData = null;
+            if (type == OPEN_SSL_WITH_TLS_SCT.value) {
+                int tlsSctDataLength = buf.getInt();
+                checkRemaining(buf, tlsSctDataLength);
+
+                if (tlsSctDataLength > 0) {
+                    tlsSctData = new byte[tlsSctDataLength];
+                    buf.get(tlsSctData);
+                }
+            }
+
+            if (buf.remaining() != 0) {
+                log(new AssertionError("Read entire session, but data still remains; rejecting"));
+                return null;
+            }
+
+            NativeRef.SSL_SESSION ref =
+                    new NativeRef.SSL_SESSION(NativeCrypto.d2i_SSL_SESSION(sessionData));
+            return new Impl(context, ref, host, port, peerCerts, ocspData, tlsSctData);
+        } catch (IOException e) {
+            log(e);
+            return null;
+        } catch (BufferUnderflowException e) {
+            log(e);
+            return null;
+        }
+    }
+
+    abstract byte[] getId();
+
+    abstract boolean isValid();
+
+    /**
+     * Returns whether this session should only ever be used for resumption once.
+     */
+    abstract boolean isSingleUse();
+
+    abstract void offerToResume(NativeSsl ssl) throws SSLException;
+
+    abstract String getCipherSuite();
+
+    abstract String getProtocol();
+
+    abstract String getPeerHost();
+
+    abstract int getPeerPort();
+
+    /**
+     * Returns the OCSP stapled response. The returned array is not copied; the caller must
+     * either not modify the returned array or make a copy.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc6066">RFC 6066</a>
+     * @see <a href="https://tools.ietf.org/html/rfc6961">RFC 6961</a>
+     */
+    abstract byte[] getPeerOcspStapledResponse();
+
+    /**
+     * Returns the signed certificate timestamp (SCT) received from the peer. The returned array
+     * is not copied; the caller must either not modify the returned array or make a copy.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc6962">RFC 6962</a>
+     */
+    abstract byte[] getPeerSignedCertificateTimestamp();
+
+    /**
+     * Converts the given session to bytes.
+     *
+     * @return session data as bytes or null if the session can't be converted
+     */
+    abstract byte[] toBytes();
+
+    /**
+     * Converts this object to a {@link SSLSession}. The returned session will support only a
+     * subset of the {@link SSLSession} API.
+     */
+    abstract SSLSession toSSLSession();
+
+    /**
+     * The session wrapper implementation.
+     */
+    private static final class Impl extends NativeSslSession {
+        private final NativeRef.SSL_SESSION ref;
+
+        // BoringSSL offers no API to obtain these values directly from the SSL_SESSION.
+        private final AbstractSessionContext context;
+        private final String host;
+        private final int port;
+        private final String protocol;
+        private final String cipherSuite;
+        private final java.security.cert.X509Certificate[] peerCertificates;
+        private final byte[] peerOcspStapledResponse;
+        private final byte[] peerSignedCertificateTimestamp;
+
+        private Impl(AbstractSessionContext context, NativeRef.SSL_SESSION ref, String host,
+                int port, java.security.cert.X509Certificate[] peerCertificates,
+                byte[] peerOcspStapledResponse, byte[] peerSignedCertificateTimestamp) {
+            this.context = context;
+            this.host = host;
+            this.port = port;
+            this.peerCertificates = peerCertificates;
+            this.peerOcspStapledResponse = peerOcspStapledResponse;
+            this.peerSignedCertificateTimestamp = peerSignedCertificateTimestamp;
+            this.protocol = NativeCrypto.SSL_SESSION_get_version(ref.address);
+            this.cipherSuite =
+                    NativeCrypto.cipherSuiteToJava(NativeCrypto.SSL_SESSION_cipher(ref.address));
+            this.ref = ref;
+        }
+
+        @Override
+        byte[] getId() {
+            return NativeCrypto.SSL_SESSION_session_id(ref.address);
+        }
+
+        private long getCreationTime() {
+            return NativeCrypto.SSL_SESSION_get_time(ref.address);
+        }
+
+        @Override
+        boolean isValid() {
+            long creationTimeMillis = getCreationTime();
+            // Use the minimum of the timeout from the context and the session.
+            long timeoutMillis = Math.max(0,
+                                         Math.min(context.getSessionTimeout(),
+                                                 NativeCrypto.SSL_SESSION_get_timeout(ref.address)))
+                    * 1000;
+            return (System.currentTimeMillis() - timeoutMillis) < creationTimeMillis;
+        }
+
+        @Override
+        boolean isSingleUse() {
+            return NativeCrypto.SSL_SESSION_should_be_single_use(ref.address);
+        }
+
+        @Override
+        void offerToResume(NativeSsl ssl) throws SSLException {
+            ssl.offerToResumeSession(ref.address);
+        }
+
+        @Override
+        String getCipherSuite() {
+            return cipherSuite;
+        }
+
+        @Override
+        String getProtocol() {
+            return protocol;
+        }
+
+        @Override
+        String getPeerHost() {
+            return host;
+        }
+
+        @Override
+        int getPeerPort() {
+            return port;
+        }
+
+        @Override
+        byte[] getPeerOcspStapledResponse() {
+            return peerOcspStapledResponse;
+        }
+
+        @Override
+        byte[] getPeerSignedCertificateTimestamp() {
+            return peerSignedCertificateTimestamp;
+        }
+
+        @Override
+        byte[] toBytes() {
+            try {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                DataOutputStream daos = new DataOutputStream(baos);
+
+                daos.writeInt(OPEN_SSL_WITH_TLS_SCT.value); // session type ID
+
+                // Session data.
+                byte[] data = NativeCrypto.i2d_SSL_SESSION(ref.address);
+                daos.writeInt(data.length);
+                daos.write(data);
+
+                // Certificates.
+                daos.writeInt(peerCertificates.length);
+
+                for (Certificate cert : peerCertificates) {
+                    data = cert.getEncoded();
+                    daos.writeInt(data.length);
+                    daos.write(data);
+                }
+
+                if (peerOcspStapledResponse != null) {
+                    daos.writeInt(1);
+                    daos.writeInt(peerOcspStapledResponse.length);
+                    daos.write(peerOcspStapledResponse);
+                } else {
+                    daos.writeInt(0);
+                }
+
+                if (peerSignedCertificateTimestamp != null) {
+                    daos.writeInt(peerSignedCertificateTimestamp.length);
+                    daos.write(peerSignedCertificateTimestamp);
+                } else {
+                    daos.writeInt(0);
+                }
+
+                // TODO: local certificates?
+
+                return baos.toByteArray();
+            } catch (IOException e) {
+                // TODO(nathanmittler): Better error handling?
+                logger.log(Level.WARNING, "Failed to convert saved SSL Session: ", e);
+                return null;
+            } catch (CertificateEncodingException e) {
+                log(e);
+                return null;
+            }
+        }
+
+        @Override
+        SSLSession toSSLSession() {
+            return new SSLSession() {
+                @Override
+                public byte[] getId() {
+                    return Impl.this.getId();
+                }
+
+                @Override
+                public String getCipherSuite() {
+                    return Impl.this.getCipherSuite();
+                }
+
+                @Override
+                public String getProtocol() {
+                    return Impl.this.getProtocol();
+                }
+
+                @Override
+                public String getPeerHost() {
+                    return Impl.this.getPeerHost();
+                }
+
+                @Override
+                public int getPeerPort() {
+                    return Impl.this.getPeerPort();
+                }
+
+                @Override
+                public long getCreationTime() {
+                    return Impl.this.getCreationTime();
+                }
+
+                @Override
+                public boolean isValid() {
+                    return Impl.this.isValid();
+                }
+
+                // UNSUPPORTED OPERATIONS
+
+                @Override
+                public SSLSessionContext getSessionContext() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public long getLastAccessedTime() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public void invalidate() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public void putValue(String s, Object o) {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Object getValue(String s) {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public void removeValue(String s) {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public String[] getValueNames() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Certificate[] getLocalCertificates() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public X509Certificate[] getPeerCertificateChain()
+                        throws SSLPeerUnverifiedException {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Principal getLocalPrincipal() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public int getPacketBufferSize() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public int getApplicationBufferSize() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+    }
+
+    private static void log(Throwable t) {
+        // TODO(nathanmittler): Better error handling?
+        logger.log(Level.INFO, "Error inflating SSL session: {0}",
+                (t.getMessage() != null ? t.getMessage() : t.getClass().getName()));
+    }
+
+    private static void checkRemaining(ByteBuffer buf, int length) throws IOException {
+        if (length < 0) {
+            throw new IOException("Length is negative: " + length);
+        }
+        if (length > buf.remaining()) {
+            throw new IOException(
+                    "Length of blob is longer than available: " + length + " > " + buf.remaining());
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OAEPParameters.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OAEPParameters.java
new file mode 100644
index 0000000..02c4acd
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OAEPParameters.java
@@ -0,0 +1,293 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.util.HashMap;
+import java.util.Map;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+/**
+ * AlgorithmParameters implementation for OAEP.  The only supported encoding format is ASN.1,
+ * as specified in RFC 4055 section 4.1.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OAEPParameters extends AlgorithmParametersSpi {
+
+    private static final Map<String, String> OID_TO_NAME = new HashMap<String, String>();
+    private static final Map<String, String> NAME_TO_OID = new HashMap<String, String>();
+    static {
+        OID_TO_NAME.put("1.3.14.3.2.26", "SHA-1");
+        OID_TO_NAME.put("2.16.840.1.101.3.4.2.4", "SHA-224");
+        OID_TO_NAME.put("2.16.840.1.101.3.4.2.1", "SHA-256");
+        OID_TO_NAME.put("2.16.840.1.101.3.4.2.2", "SHA-384");
+        OID_TO_NAME.put("2.16.840.1.101.3.4.2.3", "SHA-512");
+        for (Map.Entry<String, String> entry : OID_TO_NAME.entrySet()) {
+            NAME_TO_OID.put(entry.getValue(), entry.getKey());
+        }
+    }
+    private static final String MGF1_OID = "1.2.840.113549.1.1.8";
+    private static final String PSPECIFIED_OID = "1.2.840.113549.1.1.9";
+
+    private OAEPParameterSpec spec = OAEPParameterSpec.DEFAULT;
+
+    @libcore.api.IntraCoreApi
+    public OAEPParameters() {}
+
+    @Override
+    protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+            throws InvalidParameterSpecException {
+        if (algorithmParameterSpec instanceof OAEPParameterSpec) {
+            this.spec = (OAEPParameterSpec) algorithmParameterSpec;
+        } else {
+            throw new InvalidParameterSpecException("Only OAEPParameterSpec is supported");
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes) throws IOException {
+        long readRef = 0;
+        long seqRef = 0;
+        try {
+            readRef = NativeCrypto.asn1_read_init(bytes);
+            seqRef = NativeCrypto.asn1_read_sequence(readRef);
+            PSource.PSpecified pSpecified = PSource.PSpecified.DEFAULT;
+            String hash = readHash(seqRef);
+            String mgfHash = readMgfHash(seqRef);
+            if (NativeCrypto.asn1_read_next_tag_is(seqRef, 2)) {
+                long pSourceRef = 0;
+                long pSourceSeqRef = 0;
+                try {
+                    pSourceRef = NativeCrypto.asn1_read_tagged(seqRef);
+                    pSourceSeqRef = NativeCrypto.asn1_read_sequence(pSourceRef);
+                    String pSourceOid = NativeCrypto.asn1_read_oid(pSourceSeqRef);
+                    if (!pSourceOid.equals(PSPECIFIED_OID)) {
+                        throw new IOException("Error reading ASN.1 encoding");
+                    }
+                    pSpecified = new PSource.PSpecified(
+                            NativeCrypto.asn1_read_octetstring(pSourceSeqRef));
+                    if (!NativeCrypto.asn1_read_is_empty(pSourceSeqRef)) {
+                        throw new IOException("Error reading ASN.1 encoding");
+                    }
+                } finally {
+                    NativeCrypto.asn1_read_free(pSourceSeqRef);
+                    NativeCrypto.asn1_read_free(pSourceRef);
+                }
+            }
+
+            if (!NativeCrypto.asn1_read_is_empty(seqRef)
+                    || !NativeCrypto.asn1_read_is_empty(readRef)) {
+                throw new IOException("Error reading ASN.1 encoding");
+            }
+            this.spec = new OAEPParameterSpec(hash, "MGF1", new MGF1ParameterSpec(mgfHash),
+                    pSpecified);
+        } finally {
+            NativeCrypto.asn1_read_free(seqRef);
+            NativeCrypto.asn1_read_free(readRef);
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes, String format) throws IOException {
+        if ((format == null) || format.equals("ASN.1")) {
+            engineInit(bytes);
+        } else {
+            throw new IOException("Unsupported format: " + format);
+        }
+    }
+
+    // Shared with PSSParameters, since they share some of their encoded form
+    static String readHash(long seqRef) throws IOException {
+        if (NativeCrypto.asn1_read_next_tag_is(seqRef, 0)) {
+            long hashRef = 0;
+            try {
+                hashRef = NativeCrypto.asn1_read_tagged(seqRef);
+                return getHashName(hashRef);
+            } finally {
+                NativeCrypto.asn1_read_free(hashRef);
+            }
+        }
+        return "SHA-1";
+    }
+
+    // Shared with PSSParameters, since they share some of their encoded form
+    static String readMgfHash(long seqRef) throws IOException {
+        if (NativeCrypto.asn1_read_next_tag_is(seqRef, 1)) {
+            long mgfRef = 0;
+            long mgfSeqRef = 0;
+            try {
+                mgfRef = NativeCrypto.asn1_read_tagged(seqRef);
+                mgfSeqRef = NativeCrypto.asn1_read_sequence(mgfRef);
+                String mgfOid = NativeCrypto.asn1_read_oid(mgfSeqRef);
+                if (!mgfOid.equals(MGF1_OID)) {
+                    throw new IOException("Error reading ASN.1 encoding");
+                }
+                String mgfHash = getHashName(mgfSeqRef);
+                if (!NativeCrypto.asn1_read_is_empty(mgfSeqRef)) {
+                    throw new IOException("Error reading ASN.1 encoding");
+                }
+                return mgfHash;
+            } finally {
+                NativeCrypto.asn1_read_free(mgfSeqRef);
+                NativeCrypto.asn1_read_free(mgfRef);
+            }
+        }
+        return "SHA-1";
+    }
+
+    private static String getHashName(long hashRef) throws IOException {
+        long hashSeqRef = 0;
+        try {
+            hashSeqRef = NativeCrypto.asn1_read_sequence(hashRef);
+            String hashOid = NativeCrypto.asn1_read_oid(hashSeqRef);
+            if (!NativeCrypto.asn1_read_is_empty(hashSeqRef)) {
+                NativeCrypto.asn1_read_null(hashSeqRef);
+            }
+            if (!NativeCrypto.asn1_read_is_empty(hashSeqRef)
+                    || !OID_TO_NAME.containsKey(hashOid)) {
+                throw new IOException("Error reading ASN.1 encoding");
+            }
+            return OID_TO_NAME.get(hashOid);
+        } finally {
+            NativeCrypto.asn1_read_free(hashSeqRef);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> aClass)
+            throws InvalidParameterSpecException {
+        if ((aClass != null) && aClass == OAEPParameterSpec.class) {
+            return (T) spec;
+        } else {
+            throw new InvalidParameterSpecException("Unsupported class: " + aClass);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded() throws IOException {
+        long cbbRef = 0;
+        long seqRef = 0;
+        try {
+            cbbRef = NativeCrypto.asn1_write_init();
+            seqRef = NativeCrypto.asn1_write_sequence(cbbRef);
+            writeHashAndMgfHash(seqRef, spec.getDigestAlgorithm(),
+                    (MGF1ParameterSpec) spec.getMGFParameters());
+            PSource.PSpecified pSource = (PSource.PSpecified) spec.getPSource();
+            // Implementations are prohibited from writing the default value for any of the fields
+            if (pSource.getValue().length != 0) {
+                long pSourceRef = 0;
+                long pSourceParamsRef = 0;
+                try {
+                    pSourceRef = NativeCrypto.asn1_write_tag(seqRef, 2);
+                    pSourceParamsRef = writeAlgorithmIdentifier(pSourceRef, PSPECIFIED_OID);
+                    NativeCrypto.asn1_write_octetstring(pSourceParamsRef, pSource.getValue());
+                } finally {
+                    NativeCrypto.asn1_write_flush(seqRef);
+                    NativeCrypto.asn1_write_free(pSourceParamsRef);
+                    NativeCrypto.asn1_write_free(pSourceRef);
+                }
+            }
+            return NativeCrypto.asn1_write_finish(cbbRef);
+        } catch (IOException e) {
+            NativeCrypto.asn1_write_cleanup(cbbRef);
+            throw e;
+        } finally {
+            NativeCrypto.asn1_write_free(seqRef);
+            NativeCrypto.asn1_write_free(cbbRef);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded(String format) throws IOException {
+        if ((format == null) || format.equals("ASN.1")) {
+            return engineGetEncoded();
+        }
+        throw new IOException("Unsupported format: " + format);
+    }
+
+    // Shared with PSSParameters, since they share some of their encoded form
+    static void writeHashAndMgfHash(long seqRef, String hash, MGF1ParameterSpec mgfSpec) throws IOException {
+        // Implementations are prohibited from writing the default value for any of the fields
+        if (!hash.equals("SHA-1")) {
+            long hashRef = 0;
+            long hashParamsRef = 0;
+            try {
+                hashRef = NativeCrypto.asn1_write_tag(seqRef, 0);
+                hashParamsRef = writeAlgorithmIdentifier(
+                        hashRef, NAME_TO_OID.get(hash));
+                NativeCrypto.asn1_write_null(hashParamsRef);
+            } finally {
+                NativeCrypto.asn1_write_flush(seqRef);
+                NativeCrypto.asn1_write_free(hashParamsRef);
+                NativeCrypto.asn1_write_free(hashRef);
+            }
+        }
+        if (!mgfSpec.getDigestAlgorithm().equals("SHA-1")) {
+            long mgfRef = 0;
+            long mgfParamsRef = 0;
+            long hashParamsRef = 0;
+            try {
+                mgfRef = NativeCrypto.asn1_write_tag(seqRef, 1);
+                mgfParamsRef = writeAlgorithmIdentifier(mgfRef, MGF1_OID);
+                hashParamsRef = writeAlgorithmIdentifier(
+                        mgfParamsRef, NAME_TO_OID.get(mgfSpec.getDigestAlgorithm()));
+                NativeCrypto.asn1_write_null(hashParamsRef);
+            } finally {
+                NativeCrypto.asn1_write_flush(seqRef);
+                NativeCrypto.asn1_write_free(hashParamsRef);
+                NativeCrypto.asn1_write_free(mgfParamsRef);
+                NativeCrypto.asn1_write_free(mgfRef);
+            }
+        }
+    }
+
+    /**
+     * Writes an ASN.1 AlgorithmIdentifier structure into container, which looks like
+     * <pre>
+     * SEQUENCE
+     *   OBJECT IDENTIFIER
+     *   PARAMS (based on the particular algorithm)
+     * </pre>
+     * This method returns a reference to the sequence such that the params may be added to it.
+     * The reference needs to be freed with asn1_write_free once it's used.
+     */
+    private static long writeAlgorithmIdentifier(long container, String oid) throws IOException {
+        long seqRef = 0;
+        try {
+            seqRef = NativeCrypto.asn1_write_sequence(container);
+            NativeCrypto.asn1_write_oid(seqRef, oid);
+        } catch (IOException e) {
+            NativeCrypto.asn1_write_free(seqRef);
+            throw e;
+        }
+        return seqRef;
+    }
+
+    @Override
+    protected String engineToString() {
+        return "Conscrypt OAEP AlgorithmParameters";
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OidData.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OidData.java
new file mode 100644
index 0000000..d84dc4d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OidData.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Data about OIDs.
+ */
+final class OidData {
+
+  private OidData() {}
+
+  private static final Map<String, String> OID_TO_NAME_MAP = new HashMap<>();
+
+  static {
+    // NOTE: For the time being, we only have X509 signature algorithms here, since we only need
+    // them for determining the name of signature algorithms in certs and CRLs.  We can add more in
+    // the future if we need them.
+
+    // Signatures
+
+    // RFC 3279
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.2", "MD2withRSA");
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.4", "MD5withRSA");
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.5", "SHA1withRSA");
+    OID_TO_NAME_MAP.put("1.2.840.10040.4.3", "SHA1withDSA");
+    OID_TO_NAME_MAP.put("1.2.840.10045.4.1", "SHA1withECDSA");
+
+    // RFC 4055
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.14", "SHA224withRSA");
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.11", "SHA256withRSA");
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.12", "SHA384withRSA");
+    OID_TO_NAME_MAP.put("1.2.840.113549.1.1.13", "SHA512withRSA");
+
+    // RFC 5758
+    OID_TO_NAME_MAP.put("2.16.840.1.101.3.4.3.1", "SHA224withDSA");
+    OID_TO_NAME_MAP.put("2.16.840.1.101.3.4.3.2", "SHA256withDSA");
+    OID_TO_NAME_MAP.put("1.2.840.10045.4.3.1", "SHA224withECDSA");
+    OID_TO_NAME_MAP.put("1.2.840.10045.4.3.2", "SHA256withECDSA");
+    OID_TO_NAME_MAP.put("1.2.840.10045.4.3.3", "SHA384withECDSA");
+    OID_TO_NAME_MAP.put("1.2.840.10045.4.3.4", "SHA512withECDSA");
+  }
+
+  public static String oidToAlgorithmName(String oid) {
+    return OID_TO_NAME_MAP.get(oid);
+  }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipher.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipher.java
new file mode 100644
index 0000000..5542eed
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipher.java
@@ -0,0 +1,366 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLAeadCipher extends OpenSSLCipher {
+    /**
+     * The default tag size when one is not specified. Default to
+     * full-length tags (128-bits or 16 octets).
+     */
+    static final int DEFAULT_TAG_SIZE_BITS = 16 * 8;
+
+    /**
+     * Keeps track of the last used block size.
+     */
+    private static int lastGlobalMessageSize = 32;
+
+    /**
+     * The previously used key to prevent key + nonce (IV) reuse.
+     */
+    private byte[] previousKey;
+
+    /**
+     * The previously used nonce (IV) to prevent key + nonce reuse.
+     */
+    private byte[] previousIv;
+
+    /**
+     * When set this instance must be initialized before use again. This prevents key
+     * and IV reuse.
+     */
+    private boolean mustInitialize;
+
+    /**
+     * The byte array containing the bytes written.
+     */
+    byte[] buf;
+
+    /**
+     * The number of bytes written.
+     */
+    int bufCount;
+
+    /**
+     * AEAD cipher reference.
+     */
+    long evpAead;
+
+    /**
+     * Additional authenticated data.
+     */
+    private byte[] aad;
+
+    /**
+     * The length of the AEAD cipher tag in bytes.
+     */
+    int tagLengthInBytes;
+
+    public OpenSSLAeadCipher(Mode mode) {
+        super(mode, Padding.NOPADDING);
+    }
+
+    private void checkInitialization() {
+        if (mustInitialize) {
+            throw new IllegalStateException(
+                    "Cannot re-use same key and IV for multiple encryptions");
+        }
+    }
+
+    /** Constant-time array comparison.  Since we are using this to compare keys, we want to
+     * ensure there's no opportunity for a timing attack. */
+    private boolean arraysAreEqual(byte[] a, byte[] b) {
+        if (a.length != b.length) {
+            return false;
+        }
+
+        int diff = 0;
+        for (int i = 0; i < a.length; i++) {
+            diff |= a[i] ^ b[i];
+        }
+        return diff == 0;
+    }
+
+    private void expand(int i) {
+        /* Can the buffer handle i more bytes, if not expand it */
+        if (bufCount + i <= buf.length) {
+            return;
+        }
+
+        byte[] newbuf = new byte[(bufCount + i) * 2];
+        System.arraycopy(buf, 0, newbuf, 0, bufCount);
+        buf = newbuf;
+    }
+
+    private void reset() {
+        aad = null;
+        final int lastBufSize = lastGlobalMessageSize;
+        if (buf == null) {
+            buf = new byte[lastBufSize];
+        } else if (bufCount > 0 && bufCount != lastBufSize) {
+            lastGlobalMessageSize = bufCount;
+            if (buf.length != bufCount) {
+                buf = new byte[bufCount];
+            }
+        }
+        bufCount = 0;
+    }
+
+    @Override
+    void engineInitInternal(byte[] encodedKey, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException,
+        InvalidAlgorithmParameterException {
+        byte[] iv;
+        final int tagLenBits;
+        if (params == null) {
+            iv = null;
+            tagLenBits = DEFAULT_TAG_SIZE_BITS;
+        } else {
+            GCMParameters gcmParams = Platform.fromGCMParameterSpec(params);
+            if (gcmParams != null) {
+                iv = gcmParams.getIV();
+                tagLenBits = gcmParams.getTLen();
+            } else if (params instanceof IvParameterSpec) {
+                IvParameterSpec ivParams = (IvParameterSpec) params;
+                iv = ivParams.getIV();
+                tagLenBits = DEFAULT_TAG_SIZE_BITS;
+            } else {
+                iv = null;
+                tagLenBits = DEFAULT_TAG_SIZE_BITS;
+            }
+        }
+
+        checkSupportedTagLength(tagLenBits);
+
+        tagLengthInBytes = tagLenBits / 8;
+
+        final boolean encrypting = isEncrypting();
+
+        evpAead = getEVP_AEAD(encodedKey.length);
+
+        final int expectedIvLength = NativeCrypto.EVP_AEAD_nonce_length(evpAead);
+        if (iv == null && expectedIvLength != 0) {
+            if (!encrypting) {
+                throw new InvalidAlgorithmParameterException("IV must be specified in " + mode
+                        + " mode");
+            }
+
+            iv = new byte[expectedIvLength];
+            if (random != null) {
+                random.nextBytes(iv);
+            } else {
+                NativeCrypto.RAND_bytes(iv);
+            }
+        } else if (expectedIvLength == 0 && iv != null) {
+            throw new InvalidAlgorithmParameterException("IV not used in " + mode + " mode");
+        } else if (iv != null && iv.length != expectedIvLength) {
+            throw new InvalidAlgorithmParameterException("Expected IV length of "
+                    + expectedIvLength + " but was " + iv.length);
+        }
+
+        if (isEncrypting() && iv != null && !allowsNonceReuse()) {
+            if (previousKey != null && previousIv != null
+                    && arraysAreEqual(previousKey, encodedKey)
+                    && arraysAreEqual(previousIv, iv)) {
+                mustInitialize = true;
+                throw new InvalidAlgorithmParameterException(
+                        "When using AEAD key and IV must not be re-used");
+            }
+
+            this.previousKey = encodedKey;
+            this.previousIv = iv;
+        }
+        mustInitialize = false;
+        this.iv = iv;
+        reset();
+    }
+
+    void checkSupportedTagLength(int tagLenBits)
+            throws InvalidAlgorithmParameterException {
+        if (tagLenBits % 8 != 0) {
+            throw new InvalidAlgorithmParameterException(
+                    "Tag length must be a multiple of 8; was " + tagLenBits);
+        }
+    }
+
+    /**
+     * Returns whether reusing nonces is allowed (aka, whether this is nonce misuse-resistant).
+     * Most AEAD ciphers are not, but some are specially constructed so that reusing a key/nonce
+     * pair is safe.
+     */
+    boolean allowsNonceReuse() {
+        return false;
+    }
+
+    @Override
+    protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+        BadPaddingException {
+        // Because the EVP_AEAD updateInternal processes input but doesn't create any output
+        // (and thus can't check the output buffer), we need to add this check before the
+        // superclass' processing to ensure that updateInternal is never called if the
+        // output buffer isn't large enough.
+        if (output != null) {
+            if (getOutputSizeForFinal(inputLen) > output.length - outputOffset) {
+                throw new ShortBufferException("Insufficient output space");
+            }
+        }
+        return super.engineDoFinal(input, inputOffset, inputLen, output, outputOffset);
+    }
+
+    @Override
+    int updateInternal(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset, int maximumLen) throws ShortBufferException {
+        checkInitialization();
+        if (buf == null) {
+            throw new IllegalStateException("Cipher not initialized");
+        }
+
+        ArrayUtils.checkOffsetAndCount(input.length, inputOffset, inputLen);
+        if (inputLen > 0) {
+            expand(inputLen);
+            System.arraycopy(input, inputOffset, buf, this.bufCount, inputLen);
+            this.bufCount += inputLen;
+        }
+        return 0;
+    }
+
+    @SuppressWarnings("LiteralClassName")
+    private void throwAEADBadTagExceptionIfAvailable(String message, Throwable cause)
+            throws BadPaddingException {
+        Constructor<?> aeadBadTagConstructor;
+        try {
+            aeadBadTagConstructor = Class.forName("javax.crypto.AEADBadTagException")
+                                            .getConstructor(String.class);
+        } catch (Exception ignored) {
+            return;
+        }
+
+        BadPaddingException badTagException = null;
+        try {
+            badTagException = (BadPaddingException) aeadBadTagConstructor.newInstance(message);
+            badTagException.initCause(cause);
+        } catch (IllegalAccessException e2) {
+            // Fall through
+        } catch (InstantiationException e2) {
+            // Fall through
+        } catch (InvocationTargetException e2) {
+            throw(BadPaddingException) new BadPaddingException().initCause(
+                    e2.getTargetException());
+        }
+        if (badTagException != null) {
+            throw badTagException;
+        }
+    }
+
+    @Override
+    int doFinalInternal(byte[] output, int outputOffset, int maximumLen)
+            throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+        checkInitialization();
+        final int bytesWritten;
+        try {
+            if (isEncrypting()) {
+                bytesWritten = NativeCrypto.EVP_AEAD_CTX_seal(evpAead, encodedKey,
+                        tagLengthInBytes, output, outputOffset, iv, buf, 0, bufCount, aad);
+            } else {
+                bytesWritten = NativeCrypto.EVP_AEAD_CTX_open(evpAead, encodedKey,
+                        tagLengthInBytes, output, outputOffset, iv, buf, 0, bufCount, aad);
+            }
+        } catch (BadPaddingException e) {
+            throwAEADBadTagExceptionIfAvailable(e.getMessage(), e.getCause());
+            throw e;
+        }
+        if (isEncrypting()) {
+            mustInitialize = true;
+        }
+        reset();
+        return bytesWritten;
+    }
+
+    @Override
+    void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
+        if (padding != Padding.NOPADDING) {
+            throw new NoSuchPaddingException("Must be NoPadding for AEAD ciphers");
+        }
+    }
+
+    /**
+     * AEAD buffers everything until a final output.
+     */
+    @Override
+    int getOutputSizeForUpdate(int inputLen) {
+        return 0;
+    }
+
+    @Override
+    int getOutputSizeForFinal(int inputLen) {
+        return bufCount + inputLen
+                + (isEncrypting() ? NativeCrypto.EVP_AEAD_max_overhead(evpAead) : 0);
+    }
+
+    // Intentionally missing Override to compile on old versions of Android
+    @SuppressWarnings("MissingOverride")
+    protected void engineUpdateAAD(byte[] input, int inputOffset, int inputLen) {
+        checkInitialization();
+        if (aad == null) {
+            aad = Arrays.copyOfRange(input, inputOffset, inputOffset + inputLen);
+        } else {
+            int newSize = aad.length + inputLen;
+            byte[] newaad = new byte[newSize];
+            System.arraycopy(aad, 0, newaad, 0, aad.length);
+            System.arraycopy(input, inputOffset, newaad, aad.length, inputLen);
+            aad = newaad;
+        }
+    }
+
+    // Intentionally missing Override to compile on old versions of Android
+    @SuppressWarnings("MissingOverride")
+    protected void engineUpdateAAD(ByteBuffer buf) {
+        checkInitialization();
+        if (aad == null) {
+            aad = new byte[buf.remaining()];
+            buf.get(aad);
+        } else {
+            int newSize = aad.length + buf.remaining();
+            byte[] newaad = new byte[newSize];
+            System.arraycopy(aad, 0, newaad, 0, aad.length);
+            buf.get(newaad, aad.length, buf.remaining());
+            aad = newaad;
+        }
+    }
+
+    abstract long getEVP_AEAD(int keyLength) throws InvalidKeyException;
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipherAES.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipherAES.java
new file mode 100644
index 0000000..59c59e9
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipherAES.java
@@ -0,0 +1,256 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLAeadCipherAES extends OpenSSLAeadCipher {
+    private static final int AES_BLOCK_SIZE = 16;
+
+    OpenSSLAeadCipherAES(Mode mode) {
+        super(mode);
+    }
+
+    @Override
+    void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+        switch (keyLength) {
+            case 16: // AES 128
+            case 32: // AES 256
+                return;
+            default:
+                throw new InvalidKeyException("Unsupported key size: " + keyLength
+                    + " bytes (must be 16 or 32)");
+        }
+    }
+
+    @Override
+    String getBaseCipherName() {
+        return "AES";
+    }
+
+    @Override
+    int getCipherBlockSize() {
+        return AES_BLOCK_SIZE;
+    }
+
+    @Override
+    protected AlgorithmParameterSpec getParameterSpec(AlgorithmParameters params)
+        throws InvalidAlgorithmParameterException {
+        if (params != null) {
+            AlgorithmParameterSpec spec = Platform.fromGCMParameters(params);
+            if (spec != null) {
+                return spec;
+            }
+            return super.getParameterSpec(params);
+        }
+        return null;
+    }
+
+    @Override
+    protected AlgorithmParameters engineGetParameters() {
+        // iv will be non-null after initialization.
+        if (iv == null) {
+            return null;
+        }
+
+        AlgorithmParameterSpec spec = Platform.toGCMParameterSpec(
+            tagLengthInBytes * 8, iv);
+        if (spec == null) {
+            // The platform doesn't support GCMParameterSpec. Fall back to
+            // the generic AES parameters so at least the caller can get the
+            // IV.
+            return super.engineGetParameters();
+        }
+
+        try {
+            AlgorithmParameters params = AlgorithmParameters.getInstance("GCM");
+            params.init(spec);
+            return params;
+        } catch (NoSuchAlgorithmException e) {
+            // We should not get here.
+            throw (Error) new AssertionError("GCM not supported").initCause(e);
+        } catch (InvalidParameterSpecException e) {
+            // This may happen since Conscrypt doesn't provide this itself.
+            return null;
+        }
+    }
+
+    @Override
+    int getOutputSizeForFinal(int inputLen) {
+        // For GCM, the tag is a fixed length and there is no padding or other
+        // concerns, so we can calculate the exact length required without a
+        // native call
+        if (isEncrypting()) {
+            return bufCount + inputLen + tagLengthInBytes;
+        } else {
+            return Math.max(0, bufCount + inputLen - tagLengthInBytes);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class GCM extends OpenSSLAeadCipherAES {
+
+        @libcore.api.IntraCoreApi
+        public GCM() {
+            super(Mode.GCM);
+        }
+
+        @Override
+        void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+            if (mode != Mode.GCM) {
+                throw new NoSuchAlgorithmException("Mode must be GCM");
+            }
+        }
+
+        @Override
+        long getEVP_AEAD(int keyLength) throws InvalidKeyException {
+            if (keyLength == 16) {
+                return NativeCrypto.EVP_aead_aes_128_gcm();
+            } else if (keyLength == 32) {
+                return NativeCrypto.EVP_aead_aes_256_gcm();
+            } else {
+                throw new RuntimeException("Unexpected key length: " + keyLength);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class AES_128 extends GCM {
+            @libcore.api.IntraCoreApi
+            public AES_128() {}
+
+            @Override
+            void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+                if (keyLength != 16) { // 128 bits
+                    throw new InvalidKeyException(
+                        "Unsupported key size: " + keyLength + " bytes (must be 16)");
+                }
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class AES_256 extends GCM {
+            @libcore.api.IntraCoreApi
+            public AES_256() {}
+
+            @Override
+            void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+                if (keyLength != 32) { // 256 bits
+                    throw new InvalidKeyException(
+                        "Unsupported key size: " + keyLength + " bytes (must be 32)");
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class GCM_SIV extends OpenSSLAeadCipherAES {
+        @libcore.api.IntraCoreApi
+        public GCM_SIV() {
+            super(Mode.GCM_SIV);
+        }
+
+        @Override
+        void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+            if (mode != Mode.GCM_SIV) {
+                throw new NoSuchAlgorithmException("Mode must be GCM-SIV");
+            }
+        }
+
+        @Override
+        boolean allowsNonceReuse() {
+            return true;
+        }
+
+        @Override
+        void checkSupportedTagLength(int tagLengthInBits)
+            throws InvalidAlgorithmParameterException {
+            // GCM_SIV only supports full-size tags
+            if (tagLengthInBits != DEFAULT_TAG_SIZE_BITS) {
+                throw new InvalidAlgorithmParameterException(
+                    "Tag length must be " + DEFAULT_TAG_SIZE_BITS + " bits");
+            }
+        }
+
+        @Override
+        long getEVP_AEAD(int keyLength) throws InvalidKeyException {
+            if (keyLength == 16) {
+                return NativeCrypto.EVP_aead_aes_128_gcm_siv();
+            } else if (keyLength == 32) {
+                return NativeCrypto.EVP_aead_aes_256_gcm_siv();
+            } else {
+                throw new RuntimeException("Unexpected key length: " + keyLength);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class AES_128 extends GCM_SIV {
+            @libcore.api.IntraCoreApi
+            public AES_128() {}
+
+            @Override
+            void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+                if (keyLength != 16) { // 128 bits
+                    throw new InvalidKeyException(
+                        "Unsupported key size: " + keyLength + " bytes (must be 16)");
+                }
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class AES_256 extends GCM_SIV {
+            @libcore.api.IntraCoreApi
+            public AES_256() {}
+
+            @Override
+            void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+                if (keyLength != 32) { // 256 bits
+                    throw new InvalidKeyException(
+                        "Unsupported key size: " + keyLength + " bytes (must be 32)");
+                }
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipherChaCha20.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipherChaCha20.java
new file mode 100644
index 0000000..3d753eb
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLAeadCipherChaCha20.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLAeadCipherChaCha20 extends OpenSSLAeadCipher {
+    @libcore.api.IntraCoreApi
+    public OpenSSLAeadCipherChaCha20() {
+        super(Mode.POLY1305);
+    }
+
+    @Override
+    void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+        if (keyLength != 32) {
+            throw new InvalidKeyException("Unsupported key size: " + keyLength
+                    + " bytes (must be 32)");
+        }
+    }
+
+    @Override
+    String getBaseCipherName() {
+        return "ChaCha20";
+    }
+
+    @Override
+    int getCipherBlockSize() {
+        return 0;
+    }
+
+    @Override
+    void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+        if (mode != Mode.POLY1305) {
+            throw new NoSuchAlgorithmException("Mode must be Poly1305");
+        }
+    }
+
+    @Override
+    long getEVP_AEAD(int keyLength) throws InvalidKeyException {
+        if (keyLength == 32) {
+            return NativeCrypto.EVP_aead_chacha20_poly1305();
+        } else {
+            throw new RuntimeException("Unexpected key length: " + keyLength);
+        }
+    }
+
+    @Override
+    int getOutputSizeForFinal(int inputLen) {
+        // For ChaCha20+Poly1305, the tag is always 16 bytes long and there is no
+        // padding or other concerns, so we can calculate the exact length required
+        // without a native call
+        if (isEncrypting()) {
+            return bufCount + inputLen + 16;
+        } else {
+            return Math.max(0, bufCount + inputLen - 16);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOInputStream.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOInputStream.java
new file mode 100644
index 0000000..6a14d01
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOInputStream.java
@@ -0,0 +1,111 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Provides an interface to OpenSSL's BIO system directly from a Java
+ * InputStream. It allows an OpenSSL API to read directly from something more
+ * flexible interface than a byte array.
+ */
+class OpenSSLBIOInputStream extends FilterInputStream {
+    private long ctx;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    OpenSSLBIOInputStream(InputStream is, boolean isFinite) {
+        super(is);
+
+        ctx = NativeCrypto.create_BIO_InputStream(this, isFinite);
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    long getBioContext() {
+        return ctx;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    void release() {
+        NativeCrypto.BIO_free_all(ctx);
+    }
+
+    /**
+     * Similar to a {@code readLine} method, but matches what OpenSSL expects
+     * from a {@code BIO_gets} method.
+     */
+    int gets(byte[] buffer) throws IOException {
+        if (buffer == null || buffer.length == 0) {
+            return 0;
+        }
+
+        int offset = 0;
+        int inputByte = 0;
+        while (offset < buffer.length) {
+            inputByte = read();
+            if (inputByte == -1) {
+                // EOF
+                break;
+            }
+            if (inputByte == '\n') {
+                if (offset == 0) {
+                    // If we haven't read anything yet, ignore CRLF.
+                    continue;
+                } else {
+                    break;
+                }
+            }
+
+            buffer[offset++] = (byte) inputByte;
+        }
+
+        return offset;
+    }
+
+    @Override
+    public int read(byte[] buffer) throws IOException {
+        return read(buffer, 0, buffer.length);
+    }
+
+    // InputStream.read() is allowed to return less than len bytes, and the socket InputStreams
+    // that are used with this class typically do so when the length requested is more than what
+    // is already buffered, but some users of BoringSSL's BIO APIs expect that any read call either
+    // fills the buffer completely, fails, or reaches EOF.  We patch over this difference by
+    // repeatedly calling super.read() until it indicates EOF or we fill the buffer.
+    @Override
+    public int read(byte[] buffer, int offset, int len) throws IOException {
+        if (offset < 0 || len < 0 || len > buffer.length - offset) {
+            throw new IndexOutOfBoundsException("Invalid bounds");
+        }
+        if (len == 0) {
+            return 0;
+        }
+        int totalRead = 0;
+        int read;
+        do {
+            read = super.read(buffer, offset + totalRead, len - totalRead - offset);
+            if (read == -1) {
+                break;
+            }
+            totalRead += read;
+        } while (offset + totalRead < len);
+
+        return totalRead == 0 ? -1 : totalRead;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOSink.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOSink.java
new file mode 100644
index 0000000..76fc6e1
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOSink.java
@@ -0,0 +1,78 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Wraps a BoringSSL BIO to act as a place to write out data.
+ */
+final class OpenSSLBIOSink {
+    private final long ctx;
+    private final ByteArrayOutputStream buffer;
+    private int position;
+
+    static OpenSSLBIOSink create() {
+        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        return new OpenSSLBIOSink(buffer);
+    }
+
+    private OpenSSLBIOSink(ByteArrayOutputStream buffer) {
+        ctx = NativeCrypto.create_BIO_OutputStream(buffer);
+        this.buffer = buffer;
+    }
+
+    int available() {
+        return buffer.size() - position;
+    }
+
+    void reset() {
+        buffer.reset();
+        position = 0;
+    }
+
+    long skip(long byteCount) {
+        int maxLength = Math.min(available(), (int) byteCount);
+        position += maxLength;
+        if (position == buffer.size()) {
+            reset();
+        }
+        return maxLength;
+    }
+
+    long getContext() {
+        return ctx;
+    }
+
+    byte[] toByteArray() {
+        return buffer.toByteArray();
+    }
+
+    int position() {
+        return position;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            NativeCrypto.BIO_free_all(ctx);
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOSource.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOSource.java
new file mode 100644
index 0000000..dbbd985
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLBIOSource.java
@@ -0,0 +1,107 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Wrapped by a BoringSSL BIO to act as a source of bytes.
+ */
+final class OpenSSLBIOSource {
+    private OpenSSLBIOInputStream source;
+
+    static OpenSSLBIOSource wrap(ByteBuffer buffer) {
+        return new OpenSSLBIOSource(
+            new OpenSSLBIOInputStream(new ByteBufferInputStream(buffer), false));
+    }
+
+    private OpenSSLBIOSource(OpenSSLBIOInputStream source) {
+        this.source = source;
+    }
+
+    long getContext() {
+        return source.getBioContext();
+    }
+
+    private synchronized void release() {
+        if (source != null) {
+            NativeCrypto.BIO_free_all(source.getBioContext());
+            source = null;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            release();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private static class ByteBufferInputStream extends InputStream {
+        private final ByteBuffer source;
+
+        ByteBufferInputStream(ByteBuffer source) {
+            this.source = source;
+        }
+
+        @Override
+        public int read() throws IOException {
+            if (source.remaining() > 0) {
+                return source.get();
+            } else {
+                return -1;
+            }
+        }
+
+        @Override
+        public int available() throws IOException {
+            return source.limit() - source.position();
+        }
+
+        @Override
+        public int read(byte[] buffer) throws IOException {
+            int originalPosition = source.position();
+            source.get(buffer);
+            return source.position() - originalPosition;
+        }
+
+        @Override
+        public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
+            int toRead = Math.min(source.remaining(), byteCount);
+            int originalPosition = source.position();
+            source.get(buffer, byteOffset, toRead);
+            return source.position() - originalPosition;
+        }
+
+        @Override
+        public void reset() throws IOException {
+            source.reset();
+        }
+
+        @Override
+        public long skip(long byteCount) throws IOException {
+            long originalPosition = source.position();
+            source.position((int) (originalPosition + byteCount));
+            return source.position() - originalPosition;
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipher.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipher.java
new file mode 100644
index 0000000..b80803a
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipher.java
@@ -0,0 +1,490 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Locale;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * An implementation of {@link Cipher} using BoringSSL as the backing library.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLCipher extends CipherSpi {
+
+    /**
+     * Modes that a block cipher may support.
+     */
+    enum Mode {
+        NONE,
+        CBC,
+        CTR,
+        ECB,
+        GCM,
+        GCM_SIV,
+        POLY1305,
+        ;
+
+        public static Mode getNormalized(String modeString) {
+            modeString = modeString.toUpperCase(Locale.US);
+            // We use GCM-SIV as the mode string, but - isn't a valid identifier character, so
+            // we need to ensure GCM-SIV is recognized and GCM_SIV isn't.
+            if (modeString.equals("GCM-SIV")) {
+                return GCM_SIV;
+            } else if (modeString.equals("GCM_SIV")) {
+                throw new IllegalArgumentException("Invalid mode");
+            } else {
+                return Mode.valueOf(modeString);
+            }
+        }
+    }
+
+    /**
+     * Paddings that a block cipher may support.
+     */
+    enum Padding {
+        NOPADDING,
+        PKCS5PADDING,
+        PKCS7PADDING,
+        ;
+
+        public static Padding getNormalized(String value) {
+            Padding p = Padding.valueOf(value.toUpperCase(Locale.US));
+            if (p == PKCS7PADDING) {
+                return PKCS5PADDING;
+            }
+            return p;
+        }
+    }
+
+    /**
+     * The current cipher mode.
+     */
+    Mode mode = Mode.ECB;
+
+    /**
+     * The current cipher padding.
+     */
+    private Padding padding = Padding.PKCS5PADDING;
+
+    /**
+     * May be used when reseting the cipher instance after calling
+     * {@code doFinal}.
+     */
+    byte[] encodedKey;
+
+    /**
+     * The Initial Vector (IV) used for the current cipher.
+     */
+    byte[] iv;
+
+    /**
+     * Current cipher mode: encrypting or decrypting.
+     */
+    private boolean encrypting;
+
+    /**
+     * The block size of the current cipher.
+     */
+    private int blockSize;
+
+    OpenSSLCipher() {
+    }
+
+    OpenSSLCipher(Mode mode, Padding padding) {
+        this.mode = mode;
+        this.padding = padding;
+        blockSize = getCipherBlockSize();
+    }
+
+    /**
+     * API-specific implementation of initializing the cipher. The
+     * {@link #isEncrypting()} function will tell whether it should be
+     * initialized for encryption or decryption. The {@code encodedKey} will be
+     * the bytes of a supported key size.
+     */
+    abstract void engineInitInternal(byte[] encodedKey, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+    /**
+     * API-specific implementation of updating the cipher. The
+     * {@code maximumLen} will be the maximum length of the output as returned
+     * by {@link #getOutputSizeForUpdate(int)}. The return value must be the
+     * number of bytes processed and placed into {@code output}. On error, an
+     * exception must be thrown.
+     */
+    abstract int updateInternal(byte[] input, int inputOffset, int inputLen,
+            byte[] output, int outputOffset, int maximumLen) throws ShortBufferException;
+
+    /**
+     * API-specific implementation of the final block. The {@code maximumLen}
+     * will be the maximum length of the possible output as returned by
+     * {@link #getOutputSizeForFinal(int)}. The return value must be the number
+     * of bytes processed and placed into {@code output}. On error, an exception
+     * must be thrown.
+     */
+    abstract int doFinalInternal(byte[] output, int outputOffset, int maximumLen)
+            throws IllegalBlockSizeException, BadPaddingException, ShortBufferException;
+
+    /**
+     * Returns the standard name for the particular algorithm.
+     */
+    abstract String getBaseCipherName();
+
+    /**
+     * Checks whether the cipher supports this particular {@code keySize} (in
+     * bytes) and throws {@code InvalidKeyException} if it doesn't.
+     */
+    abstract void checkSupportedKeySize(int keySize) throws InvalidKeyException;
+
+    /**
+     * Checks whether the cipher supports this particular cipher {@code mode}
+     * and throws {@code NoSuchAlgorithmException} if it doesn't.
+     */
+    abstract void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException;
+
+    /**
+     * Checks whether the cipher supports this particular cipher {@code padding}
+     * and throws {@code NoSuchPaddingException} if it doesn't.
+     */
+    abstract void checkSupportedPadding(Padding padding) throws NoSuchPaddingException;
+
+    abstract int getCipherBlockSize();
+
+    boolean supportsVariableSizeKey() {
+        return false;
+    }
+
+    boolean supportsVariableSizeIv() {
+        return false;
+    }
+
+    @Override
+    protected void engineSetMode(String modeStr) throws NoSuchAlgorithmException {
+        final Mode mode;
+        try {
+            mode = Mode.getNormalized(modeStr);
+        } catch (IllegalArgumentException e) {
+            NoSuchAlgorithmException newE = new NoSuchAlgorithmException("No such mode: " + modeStr);
+            newE.initCause(e);
+            throw newE;
+        }
+        checkSupportedMode(mode);
+        this.mode = mode;
+    }
+
+    @Override
+    protected void engineSetPadding(String paddingStr) throws NoSuchPaddingException {
+        final Padding padding;
+        try {
+            padding = Padding.getNormalized(paddingStr);
+        } catch (IllegalArgumentException e) {
+            NoSuchPaddingException newE = new NoSuchPaddingException("No such padding: "
+                    + paddingStr);
+            newE.initCause(e);
+            throw newE;
+        }
+        checkSupportedPadding(padding);
+        this.padding = padding;
+    }
+
+    /**
+     * Returns the padding type for which this cipher is initialized.
+     */
+    Padding getPadding() {
+        return padding;
+    }
+
+    @Override
+    protected int engineGetBlockSize() {
+        return blockSize;
+    }
+
+    /**
+     * The size of output if {@code doFinal()} is called with this
+     * {@code inputLen}. If padding is enabled and the size of the input puts it
+     * right at the block size, it will add another block for the padding.
+     */
+    abstract int getOutputSizeForFinal(int inputLen);
+
+    /**
+     * The size of output if {@code update()} is called with this
+     * {@code inputLen}. If padding is enabled and the size of the input puts it
+     * right at the block size, it will add another block for the padding.
+     */
+    abstract int getOutputSizeForUpdate(int inputLen);
+
+    @Override
+    protected int engineGetOutputSize(int inputLen) {
+        return Math.max(getOutputSizeForUpdate(inputLen), getOutputSizeForFinal(inputLen));
+    }
+
+    @Override
+    protected byte[] engineGetIV() {
+        return iv;
+    }
+
+    @Override
+    protected AlgorithmParameters engineGetParameters() {
+        if (iv != null && iv.length > 0) {
+            try {
+                AlgorithmParameters params = AlgorithmParameters.getInstance(getBaseCipherName());
+                params.init(new IvParameterSpec(iv));
+                return params;
+            } catch (NoSuchAlgorithmException e) {
+                return null;
+            } catch (InvalidParameterSpecException e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    protected AlgorithmParameterSpec getParameterSpec(AlgorithmParameters params)
+            throws InvalidAlgorithmParameterException {
+        if (params != null) {
+            try {
+                return params.getParameterSpec(IvParameterSpec.class);
+            } catch (InvalidParameterSpecException e) {
+                throw new InvalidAlgorithmParameterException(
+                        "Params must be convertible to IvParameterSpec", e);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
+        checkAndSetEncodedKey(opmode, key);
+        try {
+            engineInitInternal(this.encodedKey, null, random);
+        } catch (InvalidAlgorithmParameterException e) {
+            // This can't actually happen since we pass in null.
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+        checkAndSetEncodedKey(opmode, key);
+        engineInitInternal(this.encodedKey, params, random);
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        AlgorithmParameterSpec spec = getParameterSpec(params);
+        engineInit(opmode, key, spec, random);
+    }
+
+    @Override
+    protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+        final int maximumLen = getOutputSizeForUpdate(inputLen);
+
+        /* See how large our output buffer would need to be. */
+        final byte[] output;
+        if (maximumLen > 0) {
+            output = new byte[maximumLen];
+        } else {
+            output = EmptyArray.BYTE;
+        }
+
+        final int bytesWritten;
+        try {
+            bytesWritten = updateInternal(input, inputOffset, inputLen, output, 0, maximumLen);
+        } catch (ShortBufferException e) {
+            /* This shouldn't happen. */
+            throw new RuntimeException("calculated buffer size was wrong: " + maximumLen);
+        }
+
+        if (output.length == bytesWritten) {
+            return output;
+        } else if (bytesWritten == 0) {
+            return EmptyArray.BYTE;
+        } else {
+            return Arrays.copyOfRange(output, 0, bytesWritten);
+        }
+    }
+
+    @Override
+    protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset) throws ShortBufferException {
+        final int maximumLen = getOutputSizeForUpdate(inputLen);
+        return updateInternal(input, inputOffset, inputLen, output, outputOffset, maximumLen);
+    }
+
+    @Override
+    protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+            throws IllegalBlockSizeException, BadPaddingException {
+        final int maximumLen = getOutputSizeForFinal(inputLen);
+        /* Assume that we'll output exactly on a byte boundary. */
+        final byte[] output = new byte[maximumLen];
+
+        int bytesWritten;
+        if (inputLen > 0) {
+            try {
+                bytesWritten = updateInternal(input, inputOffset, inputLen, output, 0, maximumLen);
+            } catch (ShortBufferException e) {
+                /* This should not happen since we sized our own buffer. */
+                throw new RuntimeException("our calculated buffer was too small", e);
+            }
+        } else {
+            bytesWritten = 0;
+        }
+
+        try {
+            bytesWritten += doFinalInternal(output, bytesWritten, maximumLen - bytesWritten);
+        } catch (ShortBufferException e) {
+            /* This should not happen since we sized our own buffer. */
+            throw new RuntimeException("our calculated buffer was too small", e);
+        }
+
+        if (bytesWritten == output.length) {
+            return output;
+        } else if (bytesWritten == 0) {
+            return EmptyArray.BYTE;
+        } else {
+            return Arrays.copyOfRange(output, 0, bytesWritten);
+        }
+    }
+
+    @Override
+    protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        if (output == null) {
+            throw new NullPointerException("output == null");
+        }
+
+        int maximumLen = getOutputSizeForFinal(inputLen);
+
+        final int bytesWritten;
+        if (inputLen > 0) {
+            bytesWritten = updateInternal(input, inputOffset, inputLen, output, outputOffset,
+                    maximumLen);
+            outputOffset += bytesWritten;
+            maximumLen -= bytesWritten;
+        } else {
+            bytesWritten = 0;
+        }
+
+        return bytesWritten + doFinalInternal(output, outputOffset, maximumLen);
+    }
+
+    @Override
+    protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
+        try {
+            byte[] encoded = key.getEncoded();
+            return engineDoFinal(encoded, 0, encoded.length);
+        } catch (BadPaddingException e) {
+            IllegalBlockSizeException newE = new IllegalBlockSizeException();
+            newE.initCause(e);
+            throw newE;
+        }
+    }
+
+    @Override
+    protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
+            throws InvalidKeyException, NoSuchAlgorithmException {
+        try {
+            byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
+            if (wrappedKeyType == Cipher.PUBLIC_KEY) {
+                KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
+                return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
+            } else if (wrappedKeyType == Cipher.PRIVATE_KEY) {
+                KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
+                return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+            } else if (wrappedKeyType == Cipher.SECRET_KEY) {
+                return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
+            } else {
+                throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);
+            }
+        } catch (IllegalBlockSizeException e) {
+            throw new InvalidKeyException(e);
+        } catch (BadPaddingException e) {
+            throw new InvalidKeyException(e);
+        } catch (InvalidKeySpecException e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    @Override
+    protected int engineGetKeySize(Key key) throws InvalidKeyException {
+        if (!(key instanceof SecretKey)) {
+            throw new InvalidKeyException("Only SecretKey is supported");
+        }
+        byte[] encodedKey = key.getEncoded();
+        if (encodedKey == null) {
+            throw new InvalidKeyException("key.getEncoded() == null");
+        }
+        checkSupportedKeySize(encodedKey.length);
+        // The return value is in bits
+        return encodedKey.length * 8;
+    }
+
+    private byte[] checkAndSetEncodedKey(int opmode, Key key) throws InvalidKeyException {
+        if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
+            encrypting = true;
+        } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
+            encrypting = false;
+        } else {
+            throw new InvalidParameterException("Unsupported opmode " + opmode);
+        }
+
+        if (!(key instanceof SecretKey)) {
+            throw new InvalidKeyException("Only SecretKey is supported");
+        }
+
+        final byte[] encodedKey = key.getEncoded();
+        if (encodedKey == null) {
+            throw new InvalidKeyException("key.getEncoded() == null");
+        }
+        checkSupportedKeySize(encodedKey.length);
+        this.encodedKey = encodedKey;
+        return encodedKey;
+    }
+
+    boolean isEncrypting() {
+        return encrypting;
+    }
+
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipherChaCha20.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipherChaCha20.java
new file mode 100644
index 0000000..77dcbeb
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipherChaCha20.java
@@ -0,0 +1,164 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * Implementation of the ChaCha20 stream cipher.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLCipherChaCha20 extends OpenSSLCipher {
+
+    private static final int BLOCK_SIZE_BYTES = 64;
+    private static final int NONCE_SIZE_BYTES = 12;
+
+    // BoringSSL's interface encrypts by the block, so we need to keep track of whether we
+    // had unused keystream bytes at the end of the previous encryption operation, so that
+    // we can use them before moving on to the next block.
+    private int currentBlockConsumedBytes = 0;
+    private int blockCounter = 0;
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLCipherChaCha20() {}
+
+    @Override
+    void engineInitInternal(byte[] encodedKey, AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (params instanceof IvParameterSpec) {
+            IvParameterSpec ivParams = (IvParameterSpec) params;
+            if (ivParams.getIV().length != NONCE_SIZE_BYTES) {
+                throw new InvalidAlgorithmParameterException("IV must be 12 bytes long");
+            }
+            iv = ivParams.getIV();
+        } else {
+            if (!isEncrypting()) {
+                throw new InvalidAlgorithmParameterException(
+                        "IV must be specified when decrypting");
+            }
+            iv = new byte[NONCE_SIZE_BYTES];
+            if (random != null) {
+                random.nextBytes(iv);
+            } else {
+                NativeCrypto.RAND_bytes(iv);
+            }
+        }
+    }
+
+    @Override
+    int updateInternal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset,
+            int maximumLen) throws ShortBufferException {
+        if (inputLen > output.length - outputOffset) {
+            throw new ShortBufferException("Insufficient output space");
+        }
+        int inputLenRemaining = inputLen;
+        if (currentBlockConsumedBytes > 0) {
+            // A previous operation ended with a partial block, so we need to encrypt using
+            // the remainder of that block before beginning to use the next block
+            int len = Math.min(BLOCK_SIZE_BYTES - currentBlockConsumedBytes, inputLenRemaining);
+            byte[] singleBlock = new byte[BLOCK_SIZE_BYTES];
+            byte[] singleBlockOut = new byte[BLOCK_SIZE_BYTES];
+            System.arraycopy(input, inputOffset, singleBlock, currentBlockConsumedBytes, len);
+            NativeCrypto.chacha20_encrypt_decrypt(singleBlock, 0, singleBlockOut, 0,
+                    BLOCK_SIZE_BYTES, encodedKey, iv, blockCounter);
+            System.arraycopy(singleBlockOut, currentBlockConsumedBytes, output, outputOffset, len);
+            currentBlockConsumedBytes += len;
+            if (currentBlockConsumedBytes < BLOCK_SIZE_BYTES) {
+                // We still didn't finish this block, so we're done.
+                return len;
+            }
+            assert currentBlockConsumedBytes == BLOCK_SIZE_BYTES;
+            currentBlockConsumedBytes = 0;
+            inputOffset += len;
+            outputOffset += len;
+            inputLenRemaining -= len;
+            blockCounter++;
+        }
+        NativeCrypto.chacha20_encrypt_decrypt(input, inputOffset, output,
+                outputOffset, inputLenRemaining, encodedKey, iv, blockCounter);
+        currentBlockConsumedBytes = inputLenRemaining % BLOCK_SIZE_BYTES;
+        blockCounter += inputLenRemaining / BLOCK_SIZE_BYTES;
+        return inputLen;
+    }
+
+    @Override
+    int doFinalInternal(byte[] output, int outputOffset, int maximumLen)
+            throws IllegalBlockSizeException, BadPaddingException, ShortBufferException {
+        reset();
+        return 0;
+    }
+
+    private void reset() {
+        blockCounter = 0;
+        currentBlockConsumedBytes = 0;
+    }
+
+    @Override
+    String getBaseCipherName() {
+        return "ChaCha20";
+    }
+
+    @Override
+    void checkSupportedKeySize(int keySize) throws InvalidKeyException {
+        if (keySize != 32) {
+            throw new InvalidKeyException("Unsupported key size: " + keySize
+                    + " bytes (must be 32)");
+        }
+    }
+
+    @Override
+    void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+        if (mode != Mode.NONE) {
+            throw new NoSuchAlgorithmException("Mode must be NONE");
+        }
+    }
+
+    @Override
+    void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
+        if (padding != Padding.NOPADDING) {
+            throw new NoSuchPaddingException("Must be NoPadding");
+        }
+    }
+
+    @Override
+    int getCipherBlockSize() {
+        return 0;
+    }
+
+    @Override
+    int getOutputSizeForFinal(int inputLen) {
+        return inputLen;
+    }
+
+    @Override
+    int getOutputSizeForUpdate(int inputLen) {
+        return inputLen;
+    }
+
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipherRSA.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipherRSA.java
new file mode 100644
index 0000000..ed6ecb5
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLCipherRSA.java
@@ -0,0 +1,675 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Locale;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLCipherRSA extends CipherSpi {
+    /**
+     * The current OpenSSL key we're operating on.
+     */
+    OpenSSLKey key;
+
+    /**
+     * Current key type: private or public.
+     */
+    boolean usingPrivateKey;
+
+    /**
+     * Current cipher mode: encrypting or decrypting.
+     */
+    boolean encrypting;
+
+    /**
+     * Buffer for operations
+     */
+    private byte[] buffer;
+
+    /**
+     * Current offset in the buffer.
+     */
+    private int bufferOffset;
+
+    /**
+     * Flag that indicates an exception should be thrown when the input is too
+     * large during doFinal.
+     */
+    private boolean inputTooLarge;
+
+    /**
+     * Current padding mode
+     */
+    int padding = NativeConstants.RSA_PKCS1_PADDING;
+
+    OpenSSLCipherRSA(int padding) {
+        this.padding = padding;
+    }
+
+    @Override
+    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+        final String modeUpper = mode.toUpperCase(Locale.ROOT);
+        if ("NONE".equals(modeUpper) || "ECB".equals(modeUpper)) {
+            return;
+        }
+
+        throw new NoSuchAlgorithmException("mode not supported: " + mode);
+    }
+
+    @Override
+    protected void engineSetPadding(String padding) throws NoSuchPaddingException {
+        final String paddingUpper = padding.toUpperCase(Locale.ROOT);
+        if ("PKCS1PADDING".equals(paddingUpper)) {
+            this.padding = NativeConstants.RSA_PKCS1_PADDING;
+            return;
+        }
+        if ("NOPADDING".equals(paddingUpper)) {
+            this.padding = NativeConstants.RSA_NO_PADDING;
+            return;
+        }
+
+        throw new NoSuchPaddingException("padding not supported: " + padding);
+    }
+
+    @Override
+    protected int engineGetBlockSize() {
+        if (encrypting) {
+            return paddedBlockSizeBytes();
+        }
+        return keySizeBytes();
+    }
+
+    @Override
+    protected int engineGetOutputSize(int inputLen) {
+        if (encrypting) {
+            return keySizeBytes();
+        }
+        return paddedBlockSizeBytes();
+    }
+
+    int paddedBlockSizeBytes() {
+        int paddedBlockSizeBytes = keySizeBytes();
+        if (padding == NativeConstants.RSA_PKCS1_PADDING) {
+            paddedBlockSizeBytes--;  // for 0 prefix
+            paddedBlockSizeBytes -= 10;  // PKCS1 padding header length
+        }
+        return paddedBlockSizeBytes;
+    }
+
+    int keySizeBytes() {
+        if (!isInitialized()) {
+            throw new IllegalStateException("cipher is not initialized");
+        }
+        return NativeCrypto.RSA_size(this.key.getNativeRef());
+    }
+
+    /**
+     * Returns {@code true} if the cipher has been initialized.
+     */
+    boolean isInitialized() {
+        return key != null;
+    }
+
+    @Override
+    protected byte[] engineGetIV() {
+        return null;
+    }
+
+    @Override
+    protected AlgorithmParameters engineGetParameters() {
+        return null;
+    }
+
+    void doCryptoInit(AlgorithmParameterSpec spec)
+        throws InvalidAlgorithmParameterException, InvalidKeyException {}
+
+    void engineInitInternal(int opmode, Key key, AlgorithmParameterSpec spec)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
+            encrypting = true;
+        } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
+            encrypting = false;
+        } else {
+            throw new InvalidParameterException("Unsupported opmode " + opmode);
+        }
+
+        if (key instanceof OpenSSLRSAPrivateKey) {
+            OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) key;
+            usingPrivateKey = true;
+            this.key = rsaPrivateKey.getOpenSSLKey();
+        } else if (key instanceof RSAPrivateCrtKey) {
+            RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) key;
+            usingPrivateKey = true;
+            this.key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
+        } else if (key instanceof RSAPrivateKey) {
+            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) key;
+            usingPrivateKey = true;
+            this.key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
+        } else if (key instanceof OpenSSLRSAPublicKey) {
+            OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) key;
+            usingPrivateKey = false;
+            this.key = rsaPublicKey.getOpenSSLKey();
+        } else if (key instanceof RSAPublicKey) {
+            RSAPublicKey rsaPublicKey = (RSAPublicKey) key;
+            usingPrivateKey = false;
+            this.key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
+        } else {
+            if (null == key) {
+                throw new InvalidKeyException("RSA private or public key is null");
+            }
+
+            throw new InvalidKeyException("Need RSA private or public key");
+        }
+
+        buffer = new byte[NativeCrypto.RSA_size(this.key.getNativeRef())];
+        bufferOffset = 0;
+        inputTooLarge = false;
+
+        doCryptoInit(spec);
+    }
+
+    @Override
+    protected int engineGetKeySize(Key key) throws InvalidKeyException {
+        if (key instanceof OpenSSLRSAPrivateKey) {
+            return ((OpenSSLRSAPrivateKey) key).getModulus().bitLength();
+        }
+        if (key instanceof RSAPrivateCrtKey) {
+            return ((RSAPrivateCrtKey) key).getModulus().bitLength();
+        }
+        if (key instanceof RSAPrivateKey) {
+            return ((RSAPrivateKey) key).getModulus().bitLength();
+        }
+        if (key instanceof OpenSSLRSAPublicKey) {
+            return ((OpenSSLRSAPublicKey) key).getModulus().bitLength();
+        }
+        if (key instanceof RSAPublicKey) {
+            return ((RSAPublicKey) key).getModulus().bitLength();
+        }
+        if (null == key) {
+            throw new InvalidKeyException("RSA private or public key is null");
+        }
+        throw new InvalidKeyException("Need RSA private or public key");
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
+        try {
+            engineInitInternal(opmode, key, null);
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new InvalidKeyException("Algorithm parameters rejected when none supplied", e);
+        }
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException("unknown param type: "
+                    + params.getClass().getName());
+        }
+
+        engineInitInternal(opmode, key, params);
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException("unknown param type: "
+                    + params.getClass().getName());
+        }
+
+        engineInitInternal(opmode, key, null);
+    }
+
+    @Override
+    protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+        if (bufferOffset + inputLen > buffer.length) {
+            inputTooLarge = true;
+            return EmptyArray.BYTE;
+        }
+
+        System.arraycopy(input, inputOffset, buffer, bufferOffset, inputLen);
+        bufferOffset += inputLen;
+        return EmptyArray.BYTE;
+    }
+
+    @Override
+    protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset) throws ShortBufferException {
+        engineUpdate(input, inputOffset, inputLen);
+        return 0;
+    }
+
+    @Override
+    protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+            throws IllegalBlockSizeException, BadPaddingException {
+        if (input != null) {
+            engineUpdate(input, inputOffset, inputLen);
+        }
+
+        if (inputTooLarge) {
+            throw new IllegalBlockSizeException("input must be under " + buffer.length + " bytes");
+        }
+
+        final byte[] tmpBuf;
+        if (bufferOffset != buffer.length) {
+            if (padding == NativeConstants.RSA_NO_PADDING) {
+                tmpBuf = new byte[buffer.length];
+                System.arraycopy(buffer, 0, tmpBuf, buffer.length - bufferOffset, bufferOffset);
+            } else {
+                tmpBuf = Arrays.copyOf(buffer, bufferOffset);
+            }
+        } else {
+            tmpBuf = buffer;
+        }
+
+        byte[] output = new byte[buffer.length];
+        int resultSize = doCryptoOperation(tmpBuf, output);
+        if (!encrypting && resultSize != output.length) {
+            output = Arrays.copyOf(output, resultSize);
+        }
+
+        bufferOffset = 0;
+        return output;
+    }
+
+    abstract int doCryptoOperation(final byte[] tmpBuf, byte[] output)
+            throws BadPaddingException, IllegalBlockSizeException;
+
+    @Override
+    protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        byte[] b = engineDoFinal(input, inputOffset, inputLen);
+
+        final int lastOffset = outputOffset + b.length;
+        if (lastOffset > output.length) {
+            throw new ShortBufferException("output buffer is too small " + output.length + " < "
+                    + lastOffset);
+        }
+
+        System.arraycopy(b, 0, output, outputOffset, b.length);
+        return b.length;
+    }
+
+    @Override
+    protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
+        try {
+            byte[] encoded = key.getEncoded();
+            return engineDoFinal(encoded, 0, encoded.length);
+        } catch (BadPaddingException e) {
+            IllegalBlockSizeException newE = new IllegalBlockSizeException();
+            newE.initCause(e);
+            throw newE;
+        }
+    }
+
+    @Override
+    protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+            int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
+        try {
+            byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
+            if (wrappedKeyType == Cipher.PUBLIC_KEY) {
+                KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
+                return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
+            } else if (wrappedKeyType == Cipher.PRIVATE_KEY) {
+                KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
+                return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
+            } else if (wrappedKeyType == Cipher.SECRET_KEY) {
+                return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
+            } else {
+                throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);
+            }
+        } catch (IllegalBlockSizeException e) {
+            throw new InvalidKeyException(e);
+        } catch (BadPaddingException e) {
+            throw new InvalidKeyException(e);
+        } catch (InvalidKeySpecException e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public abstract static class DirectRSA extends OpenSSLCipherRSA {
+        public DirectRSA(int padding) {
+            super(padding);
+        }
+
+        @Override
+        int doCryptoOperation(final byte[] tmpBuf, byte[] output)
+                throws BadPaddingException, IllegalBlockSizeException {
+            int resultSize;
+            if (encrypting) {
+                if (usingPrivateKey) {
+                    resultSize = NativeCrypto.RSA_private_encrypt(
+                            tmpBuf.length, tmpBuf, output, key.getNativeRef(), padding);
+                } else {
+                    resultSize = NativeCrypto.RSA_public_encrypt(
+                            tmpBuf.length, tmpBuf, output, key.getNativeRef(), padding);
+                }
+            } else {
+                try {
+                    if (usingPrivateKey) {
+                        resultSize = NativeCrypto.RSA_private_decrypt(
+                                tmpBuf.length, tmpBuf, output, key.getNativeRef(), padding);
+                    } else {
+                        resultSize = NativeCrypto.RSA_public_decrypt(
+                                tmpBuf.length, tmpBuf, output, key.getNativeRef(), padding);
+                    }
+                } catch (SignatureException e) {
+                    IllegalBlockSizeException newE = new IllegalBlockSizeException();
+                    newE.initCause(e);
+                    throw newE;
+                }
+            }
+            return resultSize;
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class PKCS1 extends DirectRSA {
+        @libcore.api.IntraCoreApi
+        public PKCS1() {
+            super(NativeConstants.RSA_PKCS1_PADDING);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class Raw extends DirectRSA {
+        @libcore.api.IntraCoreApi
+        public Raw() {
+            super(NativeConstants.RSA_NO_PADDING);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class OAEP extends OpenSSLCipherRSA {
+        private long oaepMd;
+        private int oaepMdSizeBytes;
+
+        private long mgf1Md;
+
+        private byte[] label;
+
+        private NativeRef.EVP_PKEY_CTX pkeyCtx;
+
+        public OAEP(long defaultMd, int defaultMdSizeBytes) {
+            super(NativeConstants.RSA_PKCS1_OAEP_PADDING);
+            oaepMd = mgf1Md = defaultMd;
+            oaepMdSizeBytes = defaultMdSizeBytes;
+        }
+
+        @Override
+        protected AlgorithmParameters engineGetParameters() {
+            if (!isInitialized()) {
+                return null;
+            }
+
+            try {
+                AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
+
+                final PSource pSrc;
+                if (label == null) {
+                    pSrc = PSource.PSpecified.DEFAULT;
+                } else {
+                    pSrc = new PSource.PSpecified(label);
+                }
+
+                params.init(new OAEPParameterSpec(
+                        EvpMdRef.getJcaDigestAlgorithmStandardNameFromEVP_MD(oaepMd),
+                        EvpMdRef.MGF1_ALGORITHM_NAME,
+                        new MGF1ParameterSpec(
+                                EvpMdRef.getJcaDigestAlgorithmStandardNameFromEVP_MD(mgf1Md)),
+                        pSrc));
+                return params;
+            } catch (NoSuchAlgorithmException e) {
+                // We should not get here.
+                throw (Error) new AssertionError("OAEP not supported").initCause(e);
+            } catch (InvalidParameterSpecException e) {
+                throw new RuntimeException("No providers of AlgorithmParameters.OAEP available");
+            }
+        }
+
+        @Override
+        protected void engineSetPadding(String padding) throws NoSuchPaddingException {
+            String paddingUpper = padding.toUpperCase(Locale.US);
+            if (paddingUpper.equals("OAEPPADDING")) {
+                this.padding = NativeConstants.RSA_PKCS1_OAEP_PADDING;
+                return;
+            }
+
+            throw new NoSuchPaddingException("Only OAEP padding is supported");
+        }
+
+        @Override
+        protected void engineInit(
+                int opmode, Key key, AlgorithmParameterSpec spec, SecureRandom random)
+                throws InvalidKeyException, InvalidAlgorithmParameterException {
+            if (spec != null && !(spec instanceof OAEPParameterSpec)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Only OAEPParameterSpec accepted in OAEP mode");
+            }
+
+            engineInitInternal(opmode, key, spec);
+        }
+
+        @Override
+        protected void engineInit(
+                int opmode, Key key, AlgorithmParameters params, SecureRandom random)
+                throws InvalidKeyException, InvalidAlgorithmParameterException {
+            OAEPParameterSpec spec = null;
+            if (params != null) {
+                try {
+                    spec = params.getParameterSpec(OAEPParameterSpec.class);
+                } catch (InvalidParameterSpecException e) {
+                    throw new InvalidAlgorithmParameterException(
+                            "Only OAEP parameters are supported", e);
+                }
+            }
+
+            engineInitInternal(opmode, key, spec);
+        }
+
+        @Override
+        void engineInitInternal(int opmode, Key key, AlgorithmParameterSpec spec)
+                throws InvalidKeyException, InvalidAlgorithmParameterException {
+            if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
+                if (!(key instanceof PublicKey)) {
+                    throw new InvalidKeyException("Only public keys may be used to encrypt");
+                }
+            } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
+                if (!(key instanceof PrivateKey)) {
+                    throw new InvalidKeyException("Only private keys may be used to decrypt");
+                }
+            }
+            super.engineInitInternal(opmode, key, spec);
+        }
+
+        @Override
+        void doCryptoInit(AlgorithmParameterSpec spec)
+            throws InvalidAlgorithmParameterException, InvalidKeyException {
+            pkeyCtx = new NativeRef.EVP_PKEY_CTX(encrypting
+                            ? NativeCrypto.EVP_PKEY_encrypt_init(key.getNativeRef())
+                            : NativeCrypto.EVP_PKEY_decrypt_init(key.getNativeRef()));
+
+            if (spec instanceof OAEPParameterSpec) {
+                readOAEPParameters((OAEPParameterSpec) spec);
+            }
+
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_padding(
+                    pkeyCtx.address, NativeConstants.RSA_PKCS1_OAEP_PADDING);
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_oaep_md(pkeyCtx.address, oaepMd);
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx.address, mgf1Md);
+            if (label != null && label.length > 0) {
+                NativeCrypto.EVP_PKEY_CTX_set_rsa_oaep_label(pkeyCtx.address, label);
+            }
+        }
+
+        @Override
+        int paddedBlockSizeBytes() {
+            int paddedBlockSizeBytes = keySizeBytes();
+            // Size described in step 2 of decoding algorithm, but extra byte
+            // needed to make sure it's smaller than the RSA key modulus size.
+            // https://tools.ietf.org/html/rfc2437#section-9.1.1.2
+            return paddedBlockSizeBytes - (2 * oaepMdSizeBytes + 2);
+        }
+
+        private void readOAEPParameters(OAEPParameterSpec spec)
+                throws InvalidAlgorithmParameterException {
+            String mgfAlgUpper = spec.getMGFAlgorithm().toUpperCase(Locale.US);
+            AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
+            if ((!EvpMdRef.MGF1_ALGORITHM_NAME.equals(mgfAlgUpper)
+                        && !EvpMdRef.MGF1_OID.equals(mgfAlgUpper))
+                    || !(mgfSpec instanceof MGF1ParameterSpec)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Only MGF1 supported as mask generation function");
+            }
+
+            MGF1ParameterSpec mgf1spec = (MGF1ParameterSpec) mgfSpec;
+            String oaepAlgUpper = spec.getDigestAlgorithm().toUpperCase(Locale.US);
+            try {
+                oaepMd = EvpMdRef.getEVP_MDByJcaDigestAlgorithmStandardName(oaepAlgUpper);
+                oaepMdSizeBytes =
+                        EvpMdRef.getDigestSizeBytesByJcaDigestAlgorithmStandardName(oaepAlgUpper);
+                mgf1Md = EvpMdRef.getEVP_MDByJcaDigestAlgorithmStandardName(
+                        mgf1spec.getDigestAlgorithm());
+            } catch (NoSuchAlgorithmException e) {
+                throw new InvalidAlgorithmParameterException(e);
+            }
+
+            PSource pSource = spec.getPSource();
+            if (!"PSpecified".equals(pSource.getAlgorithm())
+                    || !(pSource instanceof PSource.PSpecified)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Only PSpecified accepted for PSource");
+            }
+            label = ((PSource.PSpecified) pSource).getValue();
+        }
+
+        @Override
+        int doCryptoOperation(byte[] tmpBuf, byte[] output)
+                throws BadPaddingException, IllegalBlockSizeException {
+            if (encrypting) {
+                return NativeCrypto.EVP_PKEY_encrypt(pkeyCtx, output, 0, tmpBuf, 0, tmpBuf.length);
+            } else {
+                return NativeCrypto.EVP_PKEY_decrypt(pkeyCtx, output, 0, tmpBuf, 0, tmpBuf.length);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static final class SHA1 extends OAEP {
+            @libcore.api.IntraCoreApi
+            public SHA1() {
+                super(EvpMdRef.SHA1.EVP_MD, EvpMdRef.SHA1.SIZE_BYTES);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static final class SHA224 extends OAEP {
+            @libcore.api.IntraCoreApi
+            public SHA224() {
+                super(EvpMdRef.SHA224.EVP_MD, EvpMdRef.SHA224.SIZE_BYTES);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static final class SHA256 extends OAEP {
+            @libcore.api.IntraCoreApi
+            public SHA256() {
+                super(EvpMdRef.SHA256.EVP_MD, EvpMdRef.SHA256.SIZE_BYTES);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static final class SHA384 extends OAEP {
+            @libcore.api.IntraCoreApi
+            public SHA384() {
+                super(EvpMdRef.SHA384.EVP_MD, EvpMdRef.SHA384.SIZE_BYTES);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static final class SHA512 extends OAEP {
+            @libcore.api.IntraCoreApi
+            public SHA512() {
+                super(EvpMdRef.SHA512.EVP_MD, EvpMdRef.SHA512.SIZE_BYTES);
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLContextImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLContextImpl.java
new file mode 100644
index 0000000..7f5cabc
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLContextImpl.java
@@ -0,0 +1,209 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Platform.wrapEngine;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.SecureRandom;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ * OpenSSL-backed SSLContext service provider interface.
+ *
+ * <p>Public to allow contruction via the provider framework.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLContextImpl extends SSLContextSpi {
+    /**
+     * The default SSLContextImpl for use with
+     * SSLContext.getInstance("Default"). Protected by the
+     * DefaultSSLContextImpl.class monitor.
+     */
+    private static DefaultSSLContextImpl defaultSslContextImpl;
+
+    /** TLS algorithm to initialize all sockets. */
+    private final String[] algorithms;
+
+    /** Client session cache. */
+    private final ClientSessionContext clientSessionContext;
+
+    /** Server session cache. */
+    private final ServerSessionContext serverSessionContext;
+
+    SSLParametersImpl sslParameters;
+
+    /** Allows outside callers to get the preferred SSLContext. */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static OpenSSLContextImpl getPreferred() {
+        return new TLSv13();
+    }
+
+    OpenSSLContextImpl(String[] algorithms) {
+        this.algorithms = algorithms;
+        clientSessionContext = new ClientSessionContext();
+        serverSessionContext = new ServerSessionContext();
+    }
+
+    /**
+     * Constuctor for the DefaultSSLContextImpl.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    OpenSSLContextImpl() throws GeneralSecurityException, IOException {
+        synchronized (DefaultSSLContextImpl.class) {
+            this.algorithms = null;
+            if (defaultSslContextImpl == null) {
+                clientSessionContext = new ClientSessionContext();
+                serverSessionContext = new ServerSessionContext();
+                defaultSslContextImpl = (DefaultSSLContextImpl) this;
+            } else {
+                clientSessionContext =
+                        (ClientSessionContext)
+                                defaultSslContextImpl.engineGetClientSessionContext();
+                serverSessionContext =
+                        (ServerSessionContext)
+                                defaultSslContextImpl.engineGetServerSessionContext();
+            }
+            sslParameters = new SSLParametersImpl(defaultSslContextImpl.getKeyManagers(),
+                    defaultSslContextImpl.getTrustManagers(), null, clientSessionContext,
+                    serverSessionContext, algorithms);
+        }
+    }
+
+    /**
+     * Initializes this {@code SSLContext} instance. All of the arguments are
+     * optional, and the security providers will be searched for the required
+     * implementations of the needed algorithms.
+     *
+     * @param kms the key sources or {@code null}
+     * @param tms the trust decision sources or {@code null}
+     * @param sr the randomness source or {@code null}
+     * @throws KeyManagementException if initializing this instance fails
+     */
+    @Override
+    public void engineInit(KeyManager[] kms, TrustManager[] tms, SecureRandom sr)
+            throws KeyManagementException {
+        sslParameters = new SSLParametersImpl(
+                kms, tms, sr, clientSessionContext, serverSessionContext, algorithms);
+    }
+
+    @Override
+    public SSLSocketFactory engineGetSocketFactory() {
+        if (sslParameters == null) {
+            throw new IllegalStateException("SSLContext is not initialized.");
+        }
+        return Platform.wrapSocketFactoryIfNeeded(new OpenSSLSocketFactoryImpl(sslParameters));
+    }
+
+    @Override
+    public SSLServerSocketFactory engineGetServerSocketFactory() {
+        if (sslParameters == null) {
+            throw new IllegalStateException("SSLContext is not initialized.");
+        }
+        return new OpenSSLServerSocketFactoryImpl(sslParameters);
+    }
+
+    @Override
+    public SSLEngine engineCreateSSLEngine(String host, int port) {
+        if (sslParameters == null) {
+            throw new IllegalStateException("SSLContext is not initialized.");
+        }
+        SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
+        p.setUseClientMode(false);
+        return wrapEngine(new ConscryptEngine(host, port, p));
+    }
+
+    @Override
+    public SSLEngine engineCreateSSLEngine() {
+        if (sslParameters == null) {
+            throw new IllegalStateException("SSLContext is not initialized.");
+        }
+        SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
+        p.setUseClientMode(false);
+        return wrapEngine(new ConscryptEngine(p));
+    }
+
+    @Override
+    public SSLSessionContext engineGetServerSessionContext() {
+        return serverSessionContext;
+    }
+
+    @Override
+    public SSLSessionContext engineGetClientSessionContext() {
+        return clientSessionContext;
+    }
+
+    /**
+     * Public to allow construction via the provider framework.
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class TLSv13 extends OpenSSLContextImpl {
+        @libcore.api.IntraCoreApi
+        public TLSv13() {
+            super(NativeCrypto.TLSV13_PROTOCOLS);
+        }
+    }
+
+    /**
+     * Public to allow construction via the provider framework.
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class TLSv12 extends OpenSSLContextImpl {
+        @dalvik.annotation.compat.UnsupportedAppUsage
+        @libcore.api.IntraCoreApi
+        public TLSv12() {
+            super(NativeCrypto.TLSV12_PROTOCOLS);
+        }
+    }
+
+    /**
+     * Public to allow construction via the provider framework.
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class TLSv11 extends OpenSSLContextImpl {
+        @libcore.api.IntraCoreApi
+        public TLSv11() {
+            super(NativeCrypto.TLSV11_PROTOCOLS);
+        }
+    }
+
+    /**
+     * Public to allow construction via the provider framework.
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class TLSv1 extends OpenSSLContextImpl {
+        @libcore.api.IntraCoreApi
+        public TLSv1() {
+            super(NativeCrypto.TLSV1_PROTOCOLS);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECDHKeyAgreement.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECDHKeyAgreement.java
new file mode 100644
index 0000000..7b11d8c
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECDHKeyAgreement.java
@@ -0,0 +1,155 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Elliptic Curve Diffie-Hellman key agreement backed by the OpenSSL engine.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLECDHKeyAgreement extends KeyAgreementSpi {
+
+    /** OpenSSL handle of the private key. Only available after the engine has been initialized. */
+    private OpenSSLKey mOpenSslPrivateKey;
+
+    /**
+     * Expected length (in bytes) of the agreed key ({@link #mResult}). Only available after the
+     * engine has been initialized.
+     */
+    private int mExpectedResultLength;
+
+    /** Agreed key. Only available after {@link #engineDoPhase(Key, boolean)} completes. */
+    private byte[] mResult;
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLECDHKeyAgreement() {}
+
+    @Override
+    public Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException {
+        if (mOpenSslPrivateKey == null) {
+            throw new IllegalStateException("Not initialized");
+        }
+        if (!lastPhase) {
+            throw new IllegalStateException("ECDH only has one phase");
+        }
+
+        if (key == null) {
+            throw new InvalidKeyException("key == null");
+        }
+        if (!(key instanceof PublicKey)) {
+            throw new InvalidKeyException("Not a public key: " + key.getClass());
+        }
+        OpenSSLKey openSslPublicKey = OpenSSLKey.fromPublicKey((PublicKey) key);
+
+        byte[] buffer = new byte[mExpectedResultLength];
+        int actualResultLength = NativeCrypto.ECDH_compute_key(
+                buffer,
+                0,
+                openSslPublicKey.getNativeRef(),
+                mOpenSslPrivateKey.getNativeRef());
+        byte[] result;
+        if (actualResultLength == -1) {
+            throw new RuntimeException("Engine returned " + actualResultLength);
+        } else if (actualResultLength == mExpectedResultLength) {
+            // The output is as long as expected -- use the whole buffer
+            result = buffer;
+        } else if (actualResultLength < mExpectedResultLength) {
+            // The output is shorter than expected -- use only what's produced by the engine
+            result = new byte[actualResultLength];
+            System.arraycopy(buffer, 0, mResult, 0, mResult.length);
+        } else {
+            // The output is longer than expected
+            throw new RuntimeException("Engine produced a longer than expected result. Expected: "
+                + mExpectedResultLength + ", actual: " + actualResultLength);
+        }
+        mResult = result;
+
+        return null; // No intermediate key
+    }
+
+    @Override
+    protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+            throws ShortBufferException {
+        checkCompleted();
+        int available = sharedSecret.length - offset;
+        if (mResult.length > available) {
+            throw new ShortBufferException(
+                    "Needed: " + mResult.length + ", available: " + available);
+        }
+
+        System.arraycopy(mResult, 0, sharedSecret, offset, mResult.length);
+        return mResult.length;
+    }
+
+    @Override
+    protected byte[] engineGenerateSecret() {
+        checkCompleted();
+        return mResult;
+    }
+
+    @Override
+    protected SecretKey engineGenerateSecret(String algorithm) {
+        checkCompleted();
+        return new SecretKeySpec(engineGenerateSecret(), algorithm);
+    }
+
+    @Override
+    protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+        if (key == null) {
+            throw new InvalidKeyException("key == null");
+        }
+        if (!(key instanceof PrivateKey)) {
+            throw new InvalidKeyException("Not a private key: " + key.getClass());
+        }
+
+        OpenSSLKey openSslKey = OpenSSLKey.fromPrivateKey((PrivateKey) key);
+        int fieldSizeBits = NativeCrypto.EC_GROUP_get_degree(new NativeRef.EC_GROUP(
+                NativeCrypto.EC_KEY_get1_group(openSslKey.getNativeRef())));
+        mExpectedResultLength = (fieldSizeBits + 7) / 8;
+        mOpenSslPrivateKey = openSslKey;
+    }
+
+    @Override
+    protected void engineInit(Key key, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+        // ECDH doesn't need an AlgorithmParameterSpec
+        if (params != null) {
+          throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
+        }
+        engineInit(key, random);
+    }
+
+    private void checkCompleted() {
+        if (mResult == null) {
+            throw new IllegalStateException("Key agreement not completed");
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECGroupContext.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECGroupContext.java
new file mode 100644
index 0000000..6774258
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECGroupContext.java
@@ -0,0 +1,181 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+
+/**
+ * Represents a BoringSSL EC_GROUP object.
+ */
+final class OpenSSLECGroupContext {
+    private final NativeRef.EC_GROUP groupCtx;
+
+    OpenSSLECGroupContext(NativeRef.EC_GROUP groupCtx) {
+        this.groupCtx = groupCtx;
+    }
+
+    static OpenSSLECGroupContext getCurveByName(String curveName) {
+        // Workaround for OpenSSL not supporting SECG names for NIST P-256 (aka
+        // ANSI X9.62 prime256v1).
+        if ("secp256r1".equals(curveName)) {
+            curveName = "prime256v1";
+        }
+
+        final long ctx = NativeCrypto.EC_GROUP_new_by_curve_name(curveName);
+        if (ctx == 0) {
+            return null;
+        }
+        NativeRef.EC_GROUP groupRef = new NativeRef.EC_GROUP(ctx);
+
+        return new OpenSSLECGroupContext(groupRef);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        throw new IllegalArgumentException("OpenSSLECGroupContext.equals is not defined");
+    }
+
+    @Override
+    public int hashCode() {
+        // TODO Auto-generated method stub
+        return super.hashCode();
+    }
+
+    NativeRef.EC_GROUP getNativeRef() {
+        return groupCtx;
+    }
+
+    static OpenSSLECGroupContext getInstance(ECParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+        String curveName = Platform.getCurveName(params);
+        if (curveName != null) {
+            return OpenSSLECGroupContext.getCurveByName(curveName);
+        }
+
+        // Try to find recognise the underlying curve from the parameters.
+        final EllipticCurve curve = params.getCurve();
+        final ECField field = curve.getField();
+
+        final BigInteger p;
+        if (field instanceof ECFieldFp) {
+            p = ((ECFieldFp) field).getP();
+        } else {
+            throw new InvalidParameterException("unhandled field class "
+                    + field.getClass().getName());
+        }
+
+        final ECPoint generator = params.getGenerator();
+        final BigInteger b = curve.getB();
+        final BigInteger x = generator.getAffineX();
+        final BigInteger y = generator.getAffineY();
+
+        // The 'a' value isn't checked in the following because it's unclear
+        // whether users would set it to -3 or p-3.
+        switch (p.bitLength()) {
+            case 224:
+                if (p.toString(16).equals("ffffffffffffffffffffffffffffffff000000000000000000000001") &&
+                    b.toString(16).equals("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4") &&
+                    x.toString(16).equals("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21") &&
+                    y.toString(16).equals("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34")) {
+                    curveName = "secp224r1";
+                }
+                break;
+            case 256:
+                if (p.toString(16).equals("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff") &&
+                    b.toString(16).equals("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b") &&
+                    x.toString(16).equals("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296") &&
+                    y.toString(16).equals("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5")) {
+                    curveName = "prime256v1";
+                }
+                break;
+            case 384:
+                if (p.toString(16).equals("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff") &&
+                    b.toString(16).equals("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef") &&
+                    x.toString(16).equals("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7") &&
+                    y.toString(16).equals("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f")) {
+                    curveName = "secp384r1";
+                }
+                break;
+            case 521:
+                if (p.toString(16).equals("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") &&
+                    b.toString(16).equals("51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00") &&
+                    x.toString(16).equals("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66") &&
+                    y.toString(16).equals("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650")) {
+                    curveName = "secp521r1";
+                }
+                break;
+        }
+
+        if (curveName != null) {
+            return OpenSSLECGroupContext.getCurveByName(curveName);
+        }
+
+        final BigInteger a = curve.getA();
+        final BigInteger order = params.getOrder();
+        final int cofactor = params.getCofactor();
+
+        long group;
+        try {
+            group = NativeCrypto.EC_GROUP_new_arbitrary(
+                        p.toByteArray(), a.toByteArray(), b.toByteArray(), x.toByteArray(),
+                        y.toByteArray(), order.toByteArray(), cofactor);
+        } catch (Throwable exception) {
+            throw new InvalidAlgorithmParameterException("EC_GROUP_new_arbitrary failed",
+                                                         exception);
+        }
+
+        if (group == 0) {
+            throw new InvalidAlgorithmParameterException("EC_GROUP_new_arbitrary returned NULL");
+        }
+
+        NativeRef.EC_GROUP groupRef = new NativeRef.EC_GROUP(group);
+
+        return new OpenSSLECGroupContext(groupRef);
+    }
+
+    ECParameterSpec getECParameterSpec() {
+        final String curveName = NativeCrypto.EC_GROUP_get_curve_name(groupCtx);
+
+        final byte[][] curveParams = NativeCrypto.EC_GROUP_get_curve(groupCtx);
+        final BigInteger p = new BigInteger(curveParams[0]);
+        final BigInteger a = new BigInteger(curveParams[1]);
+        final BigInteger b = new BigInteger(curveParams[2]);
+
+        final ECField field = new ECFieldFp(p);
+
+        final EllipticCurve curve = new EllipticCurve(field, a, b);
+
+        final OpenSSLECPointContext generatorCtx = new OpenSSLECPointContext(this,
+                new NativeRef.EC_POINT(NativeCrypto.EC_GROUP_get_generator(groupCtx)));
+        final ECPoint generator = generatorCtx.getECPoint();
+
+        final BigInteger order = new BigInteger(NativeCrypto.EC_GROUP_get_order(groupCtx));
+        final BigInteger cofactor = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(groupCtx));
+
+        ECParameterSpec spec = new ECParameterSpec(curve, generator, order, cofactor.intValue());
+        Platform.setCurveName(spec, curveName);
+        return spec;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECKeyFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECKeyFactory.java
new file mode 100644
index 0000000..4891b50
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECKeyFactory.java
@@ -0,0 +1,207 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactorySpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * An implementation of a {@link KeyFactorySpi} for EC keys based on BoringSSL.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLECKeyFactory extends KeyFactorySpi {
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLECKeyFactory() {}
+
+    @Override
+    protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("keySpec == null");
+        }
+
+        if (keySpec instanceof ECPublicKeySpec) {
+            return new OpenSSLECPublicKey((ECPublicKeySpec) keySpec);
+        } else if (keySpec instanceof X509EncodedKeySpec) {
+            return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeConstants.EVP_PKEY_EC);
+        }
+        throw new InvalidKeySpecException("Must use ECPublicKeySpec or X509EncodedKeySpec; was "
+                + keySpec.getClass().getName());
+    }
+
+    @Override
+    protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("keySpec == null");
+        }
+
+        if (keySpec instanceof ECPrivateKeySpec) {
+            return new OpenSSLECPrivateKey((ECPrivateKeySpec) keySpec);
+        } else if (keySpec instanceof PKCS8EncodedKeySpec) {
+            return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
+                    NativeConstants.EVP_PKEY_EC);
+        }
+        throw new InvalidKeySpecException("Must use ECPrivateKeySpec or PKCS8EncodedKeySpec; was "
+                + keySpec.getClass().getName());
+    }
+
+    @Override
+    protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
+            throws InvalidKeySpecException {
+        if (key == null) {
+            throw new InvalidKeySpecException("key == null");
+        }
+
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("keySpec == null");
+        }
+
+        if (!"EC".equals(key.getAlgorithm())) {
+            throw new InvalidKeySpecException("Key must be an EC key");
+        }
+
+        if (key instanceof ECPublicKey && ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            ECPublicKey ecKey = (ECPublicKey) key;
+            @SuppressWarnings("unchecked")
+            T result = (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
+            return result;
+        } else if (key instanceof PublicKey && ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"X.509".equals(key.getFormat()) || encoded == null) {
+                throw new InvalidKeySpecException("Not a valid X.509 encoding");
+            }
+            ECPublicKey ecKey = (ECPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
+            @SuppressWarnings("unchecked")
+            T result = (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
+            return result;
+        } else if (key instanceof ECPrivateKey
+                && ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            ECPrivateKey ecKey = (ECPrivateKey) key;
+            @SuppressWarnings("unchecked")
+            T result = (T) new ECPrivateKeySpec(ecKey.getS(), ecKey.getParams());
+            return result;
+        } else if (key instanceof PrivateKey && ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
+                throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
+            }
+            ECPrivateKey ecKey =
+                    (ECPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
+            @SuppressWarnings("unchecked")
+            T result = (T) new ECPrivateKeySpec(ecKey.getS(), ecKey.getParams());
+            return result;
+        } else if (key instanceof PrivateKey
+                && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"PKCS#8".equals(key.getFormat())) {
+                throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
+                        + key.getFormat());
+            } else if (encoded == null) {
+                throw new InvalidKeySpecException("Key is not encodable");
+            }
+            @SuppressWarnings("unchecked") T result = (T) new PKCS8EncodedKeySpec(encoded);
+            return result;
+        } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"X.509".equals(key.getFormat())) {
+                throw new InvalidKeySpecException("Encoding type must be X.509; was "
+                        + key.getFormat());
+            } else if (encoded == null) {
+                throw new InvalidKeySpecException("Key is not encodable");
+            }
+            @SuppressWarnings("unchecked") T result = (T) new X509EncodedKeySpec(encoded);
+            return result;
+        } else {
+            throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
+                    + key.getClass().getName() + ", keySpec=" + keySpec.getName());
+        }
+    }
+
+    @Override
+    protected Key engineTranslateKey(Key key) throws InvalidKeyException {
+        if (key == null) {
+            throw new InvalidKeyException("key == null");
+        }
+        if ((key instanceof OpenSSLECPublicKey) || (key instanceof OpenSSLECPrivateKey)) {
+            return key;
+        } else if (key instanceof ECPublicKey) {
+            ECPublicKey ecKey = (ECPublicKey) key;
+
+            ECPoint w = ecKey.getW();
+
+            ECParameterSpec params = ecKey.getParams();
+
+            try {
+                return engineGeneratePublic(new ECPublicKeySpec(w, params));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if (key instanceof ECPrivateKey) {
+            ECPrivateKey ecKey = (ECPrivateKey) key;
+
+            BigInteger s = ecKey.getS();
+
+            ECParameterSpec params = ecKey.getParams();
+
+            try {
+                return engineGeneratePrivate(new ECPrivateKeySpec(s, params));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
+            byte[] encoded = key.getEncoded();
+            if (encoded == null) {
+                throw new InvalidKeyException("Key does not support encoding");
+            }
+            try {
+                return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if ((key instanceof PublicKey) && "X.509".equals(key.getFormat())) {
+            byte[] encoded = key.getEncoded();
+            if (encoded == null) {
+                throw new InvalidKeyException("Key does not support encoding");
+            }
+            try {
+                return engineGeneratePublic(new X509EncodedKeySpec(encoded));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else {
+            throw new InvalidKeyException("Key must be EC public or private key; was "
+                    + key.getClass().getName());
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECKeyPairGenerator.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECKeyPairGenerator.java
new file mode 100644
index 0000000..59e2ec0
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECKeyPairGenerator.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An implementation of {@link KeyPairGenerator} for EC keys which uses BoringSSL to perform all the
+ * operations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLECKeyPairGenerator extends KeyPairGenerator {
+    private static final String ALGORITHM = "EC";
+
+    private static final int DEFAULT_KEY_SIZE = 256;
+
+    private static final Map<Integer, String> SIZE_TO_CURVE_NAME = new HashMap<Integer, String>();
+
+    static {
+        /* NIST curves */
+        SIZE_TO_CURVE_NAME.put(224, "secp224r1");
+        SIZE_TO_CURVE_NAME.put(256, "prime256v1");
+        SIZE_TO_CURVE_NAME.put(384, "secp384r1");
+        SIZE_TO_CURVE_NAME.put(521, "secp521r1");
+    }
+
+    private OpenSSLECGroupContext group;
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLECKeyPairGenerator() {
+        super(ALGORITHM);
+    }
+
+    @Override
+    public KeyPair generateKeyPair() {
+        if (group == null) {
+            final String curveName = SIZE_TO_CURVE_NAME.get(DEFAULT_KEY_SIZE);
+            group = OpenSSLECGroupContext.getCurveByName(curveName);
+            if (group == null) {
+                throw new RuntimeException("Curve not recognized: " + curveName);
+            }
+        }
+
+        final OpenSSLKey key = new OpenSSLKey(
+                NativeCrypto.EC_KEY_generate_key(group.getNativeRef()));
+        return new KeyPair(new OpenSSLECPublicKey(group, key), new OpenSSLECPrivateKey(group, key));
+    }
+
+    @Override
+    public void initialize(int keysize, SecureRandom random) {
+        final String name = SIZE_TO_CURVE_NAME.get(keysize);
+        if (name == null) {
+            throw new InvalidParameterException("unknown key size " + keysize);
+        }
+
+        /*
+         * Store the group in a temporary variable until we know this is a valid
+         * group.
+         */
+        final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext.getCurveByName(name);
+        if (possibleGroup == null) {
+            throw new InvalidParameterException("unknown curve " + name);
+        }
+
+        group = possibleGroup;
+    }
+
+    @Override
+    public void initialize(AlgorithmParameterSpec param, SecureRandom random)
+            throws InvalidAlgorithmParameterException {
+        if (param instanceof ECParameterSpec) {
+            ECParameterSpec ecParam = (ECParameterSpec) param;
+
+            group = OpenSSLECGroupContext.getInstance(ecParam);
+        } else if (param instanceof ECGenParameterSpec) {
+            ECGenParameterSpec ecParam = (ECGenParameterSpec) param;
+
+            final String curveName = ecParam.getName();
+
+            /*
+             * Store the group in a temporary variable until we know this is a
+             * valid group.
+             */
+            final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext
+                    .getCurveByName(curveName);
+            if (possibleGroup == null) {
+                throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
+            }
+
+            group = possibleGroup;
+        } else {
+            throw new InvalidAlgorithmParameterException(
+                    "parameter must be ECParameterSpec or ECGenParameterSpec");
+        }
+    }
+
+    /** For testing. */
+    public static void assertCurvesAreValid() {
+        ArrayList<String> invalidCurves = new ArrayList<String>();
+        for (String curveName : SIZE_TO_CURVE_NAME.values()) {
+            if (OpenSSLECGroupContext.getCurveByName(curveName) == null) {
+                invalidCurves.add(curveName);
+            }
+        }
+        if (invalidCurves.size() > 0) {
+            throw new AssertionError("Invalid curve names: "
+                    + Arrays.toString(invalidCurves.toArray()));
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPointContext.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPointContext.java
new file mode 100644
index 0000000..8a6824d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPointContext.java
@@ -0,0 +1,64 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.math.BigInteger;
+import java.security.spec.ECPoint;
+
+final class OpenSSLECPointContext {
+    private final OpenSSLECGroupContext group;
+    private final NativeRef.EC_POINT pointCtx;
+
+    OpenSSLECPointContext(OpenSSLECGroupContext group, NativeRef.EC_POINT pointCtx) {
+        this.group = group;
+        this.pointCtx = pointCtx;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        throw new IllegalArgumentException("OpenSSLECPointContext.equals is not defined.");
+    }
+
+    ECPoint getECPoint() {
+        final byte[][] generatorCoords = NativeCrypto.EC_POINT_get_affine_coordinates(
+                group.getNativeRef(), pointCtx);
+        final BigInteger x = new BigInteger(generatorCoords[0]);
+        final BigInteger y = new BigInteger(generatorCoords[1]);
+        return new ECPoint(x, y);
+    }
+
+    @Override
+    public int hashCode() {
+        // TODO Auto-generated method stub
+        return super.hashCode();
+    }
+
+    NativeRef.EC_POINT getNativeRef() {
+        return pointCtx;
+    }
+
+    static OpenSSLECPointContext getInstance(OpenSSLECGroupContext group,
+            ECPoint javaPoint) {
+        OpenSSLECPointContext point = new OpenSSLECPointContext(group, new NativeRef.EC_POINT(
+                NativeCrypto.EC_POINT_new(group.getNativeRef())));
+        NativeCrypto.EC_POINT_set_affine_coordinates(group.getNativeRef(),
+                point.getNativeRef(), javaPoint.getAffineX().toByteArray(),
+                javaPoint.getAffineY().toByteArray());
+        return point;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPrivateKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPrivateKey.java
new file mode 100644
index 0000000..433ebc4
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPrivateKey.java
@@ -0,0 +1,249 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * An implementation of a {@link PrivateKey} for EC keys based on BoringSSL.
+ */
+final class OpenSSLECPrivateKey implements ECPrivateKey, OpenSSLKeyHolder {
+    private static final long serialVersionUID = -4036633595001083922L;
+
+    private static final String ALGORITHM = "EC";
+
+    protected transient OpenSSLKey key;
+
+    protected transient OpenSSLECGroupContext group;
+
+    OpenSSLECPrivateKey(OpenSSLECGroupContext group, OpenSSLKey key) {
+        this.group = group;
+        this.key = key;
+    }
+
+    OpenSSLECPrivateKey(OpenSSLKey key) {
+        this.group = new OpenSSLECGroupContext(new NativeRef.EC_GROUP(
+                NativeCrypto.EC_KEY_get1_group(key.getNativeRef())));
+        this.key = key;
+    }
+
+    OpenSSLECPrivateKey(ECPrivateKeySpec ecKeySpec) throws InvalidKeySpecException {
+        try {
+            group = OpenSSLECGroupContext.getInstance(ecKeySpec.getParams());
+            final BigInteger privKey = ecKeySpec.getS();
+            key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getNativeRef(), null,
+                    privKey.toByteArray()));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    static OpenSSLKey wrapPlatformKey(ECPrivateKey ecPrivateKey) throws InvalidKeyException {
+        OpenSSLECGroupContext group;
+        try {
+            group = OpenSSLECGroupContext.getInstance(ecPrivateKey.getParams());
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new InvalidKeyException("Unknown group parameters", e);
+        }
+        return wrapPlatformKey(ecPrivateKey, group);
+    }
+
+    /**
+     * Wraps the provided private key for use in the TLS/SSL stack only. Sign/decrypt operations
+     * using the key will be delegated to the {@code Signature}/{@code Cipher} implementation of the
+     * provider which accepts the key.
+     */
+    static OpenSSLKey wrapJCAPrivateKeyForTLSStackOnly(PrivateKey privateKey,
+            PublicKey publicKey) throws InvalidKeyException {
+        ECParameterSpec params = null;
+        if (privateKey instanceof ECKey) {
+            params = ((ECKey) privateKey).getParams();
+        } else if (publicKey instanceof ECKey) {
+            params = ((ECKey) publicKey).getParams();
+        }
+        if (params == null) {
+            throw new InvalidKeyException("EC parameters not available. Private: " + privateKey
+                    + ", public: " + publicKey);
+        }
+        return wrapJCAPrivateKeyForTLSStackOnly(privateKey, params);
+    }
+
+    /**
+     * Wraps the provided private key for use in the TLS/SSL stack only. Sign/decrypt operations
+     * using the key will be delegated to the {@code Signature}/{@code Cipher} implementation of the
+     * provider which accepts the key.
+     */
+    static OpenSSLKey wrapJCAPrivateKeyForTLSStackOnly(PrivateKey privateKey,
+            ECParameterSpec params) throws InvalidKeyException {
+        if (params == null) {
+            if (privateKey instanceof ECKey) {
+                params = ((ECKey) privateKey).getParams();
+            }
+        }
+        if (params == null) {
+            throw new InvalidKeyException("EC parameters not available: " + privateKey);
+        }
+
+        OpenSSLECGroupContext group;
+        try {
+            group = OpenSSLECGroupContext.getInstance(params);
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new InvalidKeyException("Invalid EC parameters: " + params);
+        }
+
+        return new OpenSSLKey(
+                NativeCrypto.getECPrivateKeyWrapper(privateKey, group.getNativeRef()), true);
+    }
+
+    private static OpenSSLKey wrapPlatformKey(ECPrivateKey ecPrivateKey,
+            OpenSSLECGroupContext group) throws InvalidKeyException {
+        return new OpenSSLKey(NativeCrypto.getECPrivateKeyWrapper(ecPrivateKey,
+                group.getNativeRef()), true);
+    }
+
+    static OpenSSLKey getInstance(ECPrivateKey ecPrivateKey) throws InvalidKeyException {
+        try {
+            OpenSSLECGroupContext group = OpenSSLECGroupContext.getInstance(ecPrivateKey
+                    .getParams());
+
+            /*
+             * If the key is not encodable (PKCS11-like key), then wrap it and
+             * use JNI upcalls to satisfy requests.
+             */
+            if (ecPrivateKey.getFormat() == null) {
+                return wrapPlatformKey(ecPrivateKey, group);
+            }
+
+            final BigInteger privKey = ecPrivateKey.getS();
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getNativeRef(), null,
+                    privKey.toByteArray()));
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return ALGORITHM;
+    }
+
+    @Override
+    public String getFormat() {
+        return "PKCS#8";
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return NativeCrypto.EVP_marshal_private_key(key.getNativeRef());
+    }
+
+    @Override
+    public ECParameterSpec getParams() {
+        return group.getECParameterSpec();
+    }
+
+    @Override
+    public BigInteger getS() {
+        return getPrivateKey();
+    }
+
+    private BigInteger getPrivateKey() {
+        return new BigInteger(NativeCrypto.EC_KEY_get_private_key(key.getNativeRef()));
+    }
+
+    @Override
+    public OpenSSLKey getOpenSSLKey() {
+        return key;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (o instanceof OpenSSLECPrivateKey) {
+            OpenSSLECPrivateKey other = (OpenSSLECPrivateKey) o;
+            return key.equals(other.key);
+        }
+
+        if (!(o instanceof ECPrivateKey)) {
+            return false;
+        }
+
+        final ECPrivateKey other = (ECPrivateKey) o;
+        if (!getPrivateKey().equals(other.getS())) {
+            return false;
+        }
+
+        final ECParameterSpec spec = getParams();
+        final ECParameterSpec otherSpec = other.getParams();
+
+        return spec.getCurve().equals(otherSpec.getCurve())
+                && spec.getGenerator().equals(otherSpec.getGenerator())
+                && spec.getOrder().equals(otherSpec.getOrder())
+                && spec.getCofactor() == otherSpec.getCofactor();
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(NativeCrypto.EVP_marshal_private_key(key.getNativeRef()));
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("OpenSSLECPrivateKey{");
+        sb.append("params={");
+        sb.append(NativeCrypto.EVP_PKEY_print_params(key.getNativeRef()));
+        sb.append("}}");
+        return sb.toString();
+    }
+
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+
+        byte[] encoded = (byte[]) stream.readObject();
+
+        try {
+            key = new OpenSSLKey(NativeCrypto.EVP_parse_private_key(encoded));
+        } catch (ParsingException e) {
+            throw new IOException(e);
+        }
+        group = new OpenSSLECGroupContext(new NativeRef.EC_GROUP(
+                NativeCrypto.EC_KEY_get1_group(key.getNativeRef())));
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+        stream.writeObject(getEncoded());
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPublicKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPublicKey.java
new file mode 100644
index 0000000..0476493
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLECPublicKey.java
@@ -0,0 +1,174 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.InvalidKeyException;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * An implementation of a {@link java.security.PublicKey} for EC keys based on BoringSSL.
+ */
+final class OpenSSLECPublicKey implements ECPublicKey, OpenSSLKeyHolder {
+    private static final long serialVersionUID = 3215842926808298020L;
+
+    private static final String ALGORITHM = "EC";
+
+    protected transient OpenSSLKey key;
+
+    protected transient OpenSSLECGroupContext group;
+
+    OpenSSLECPublicKey(OpenSSLECGroupContext group, OpenSSLKey key) {
+        this.group = group;
+        this.key = key;
+    }
+
+    OpenSSLECPublicKey(OpenSSLKey key) {
+        this.group = new OpenSSLECGroupContext(new NativeRef.EC_GROUP(
+                NativeCrypto.EC_KEY_get1_group(key.getNativeRef())));
+        this.key = key;
+    }
+
+    OpenSSLECPublicKey(ECPublicKeySpec ecKeySpec) throws InvalidKeySpecException {
+        try {
+            group = OpenSSLECGroupContext.getInstance(ecKeySpec.getParams());
+            OpenSSLECPointContext pubKey = OpenSSLECPointContext.getInstance(group,
+                    ecKeySpec.getW());
+            key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getNativeRef(),
+                    pubKey.getNativeRef(), null));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    static OpenSSLKey getInstance(ECPublicKey ecPublicKey) throws InvalidKeyException {
+        try {
+            OpenSSLECGroupContext group = OpenSSLECGroupContext
+                    .getInstance(ecPublicKey.getParams());
+            OpenSSLECPointContext pubKey = OpenSSLECPointContext.getInstance(group,
+                    ecPublicKey.getW());
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getNativeRef(),
+                    pubKey.getNativeRef(), null));
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return ALGORITHM;
+    }
+
+    @Override
+    public String getFormat() {
+        return "X.509";
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return NativeCrypto.EVP_marshal_public_key(key.getNativeRef());
+    }
+
+    @Override
+    public ECParameterSpec getParams() {
+        return group.getECParameterSpec();
+    }
+
+    private ECPoint getPublicKey() {
+        final OpenSSLECPointContext pubKey = new OpenSSLECPointContext(group,
+                new NativeRef.EC_POINT(NativeCrypto.EC_KEY_get_public_key(key.getNativeRef())));
+
+        return pubKey.getECPoint();
+    }
+
+    @Override
+    public ECPoint getW() {
+        return getPublicKey();
+    }
+
+    @Override
+    public OpenSSLKey getOpenSSLKey() {
+        return key;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (o instanceof OpenSSLECPublicKey) {
+            OpenSSLECPublicKey other = (OpenSSLECPublicKey) o;
+            return key.equals(other.key);
+        }
+
+        if (!(o instanceof ECPublicKey)) {
+            return false;
+        }
+
+        final ECPublicKey other = (ECPublicKey) o;
+        if (!getPublicKey().equals(other.getW())) {
+            return false;
+        }
+
+        final ECParameterSpec spec = getParams();
+        final ECParameterSpec otherSpec = other.getParams();
+
+        return spec.getCurve().equals(otherSpec.getCurve())
+                && spec.getGenerator().equals(otherSpec.getGenerator())
+                && spec.getOrder().equals(otherSpec.getOrder())
+                && spec.getCofactor() == otherSpec.getCofactor();
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(NativeCrypto.EVP_marshal_public_key(key.getNativeRef()));
+    }
+
+    @Override
+    public String toString() {
+        return NativeCrypto.EVP_PKEY_print_public(key.getNativeRef());
+    }
+
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+
+        byte[] encoded = (byte[]) stream.readObject();
+
+        try {
+            key = new OpenSSLKey(NativeCrypto.EVP_parse_public_key(encoded));
+        } catch (ParsingException e) {
+            throw new IOException(e);
+        }
+        group = new OpenSSLECGroupContext(new NativeRef.EC_GROUP(
+                NativeCrypto.EC_KEY_get1_group(key.getNativeRef())));
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+        stream.writeObject(getEncoded());
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipher.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipher.java
new file mode 100644
index 0000000..34bf157
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipher.java
@@ -0,0 +1,213 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import com.android.org.conscrypt.NativeRef.EVP_CIPHER_CTX;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLEvpCipher extends OpenSSLCipher {
+    /**
+     * Native pointer for the OpenSSL EVP_CIPHER context.
+     */
+    private final EVP_CIPHER_CTX cipherCtx = new EVP_CIPHER_CTX(
+            NativeCrypto.EVP_CIPHER_CTX_new());
+
+    /**
+     * Whether the cipher has processed any data yet. EVP_CIPHER doesn't
+     * like calling "doFinal()" in decryption mode without processing any
+     * updates.
+     */
+    private boolean calledUpdate;
+
+    /**
+     * The block size of the current mode.
+     */
+    private int modeBlockSize;
+
+    public OpenSSLEvpCipher(Mode mode, Padding padding) {
+        super(mode, padding);
+    }
+
+    @Override
+    void engineInitInternal(byte[] encodedKey, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException,
+        InvalidAlgorithmParameterException {
+        byte[] iv;
+        if (params instanceof IvParameterSpec) {
+            IvParameterSpec ivParams = (IvParameterSpec) params;
+            iv = ivParams.getIV();
+        } else {
+            iv = null;
+        }
+
+        final long cipherType = NativeCrypto.EVP_get_cipherbyname(getCipherName(
+                encodedKey.length, mode));
+        if (cipherType == 0) {
+            throw new InvalidAlgorithmParameterException("Cannot find name for key length = "
+                    + (encodedKey.length * 8) + " and mode = " + mode);
+        }
+
+        final boolean encrypting = isEncrypting();
+
+        final int expectedIvLength = NativeCrypto.EVP_CIPHER_iv_length(cipherType);
+        if (iv == null && expectedIvLength != 0) {
+            if (!encrypting) {
+                throw new InvalidAlgorithmParameterException("IV must be specified in " + mode
+                        + " mode");
+            }
+
+            iv = new byte[expectedIvLength];
+            if (random != null) {
+                random.nextBytes(iv);
+            } else {
+                NativeCrypto.RAND_bytes(iv);
+            }
+        } else if (expectedIvLength == 0 && iv != null) {
+            throw new InvalidAlgorithmParameterException("IV not used in " + mode + " mode");
+        } else if (iv != null && iv.length != expectedIvLength) {
+            throw new InvalidAlgorithmParameterException("expected IV length of "
+                    + expectedIvLength + " but was " + iv.length);
+        }
+
+        this.iv = iv;
+
+        if (supportsVariableSizeKey()) {
+            NativeCrypto.EVP_CipherInit_ex(cipherCtx, cipherType, null, null, encrypting);
+            NativeCrypto.EVP_CIPHER_CTX_set_key_length(cipherCtx, encodedKey.length);
+            NativeCrypto.EVP_CipherInit_ex(cipherCtx, 0, encodedKey, iv, isEncrypting());
+        } else {
+            NativeCrypto.EVP_CipherInit_ex(cipherCtx, cipherType, encodedKey, iv, encrypting);
+        }
+
+        // OpenSSL only supports PKCS5 Padding.
+        NativeCrypto
+                .EVP_CIPHER_CTX_set_padding(cipherCtx, getPadding() == Padding.PKCS5PADDING);
+        modeBlockSize = NativeCrypto.EVP_CIPHER_CTX_block_size(cipherCtx);
+        calledUpdate = false;
+    }
+
+    @Override
+    int updateInternal(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset, int maximumLen) throws ShortBufferException {
+        final int intialOutputOffset = outputOffset;
+
+        final int bytesLeft = output.length - outputOffset;
+        if (bytesLeft < maximumLen) {
+            throw new ShortBufferException("output buffer too small during update: "
+                    + bytesLeft + " < " + maximumLen);
+        }
+
+        outputOffset += NativeCrypto.EVP_CipherUpdate(cipherCtx, output, outputOffset, input,
+                inputOffset, inputLen);
+
+        calledUpdate = true;
+
+        return outputOffset - intialOutputOffset;
+    }
+
+    @Override
+    int doFinalInternal(byte[] output, int outputOffset, int maximumLen)
+            throws IllegalBlockSizeException, BadPaddingException, ShortBufferException {
+        /* Remember this so we can tell how many characters were written. */
+        final int initialOutputOffset = outputOffset;
+
+        /*
+         * If we're decrypting and haven't had any input, we should return
+         * null. Otherwise OpenSSL will complain if we call final.
+         */
+        if (!isEncrypting() && !calledUpdate) {
+            return 0;
+        }
+
+        /* Allow OpenSSL to pad if necessary and clean up state. */
+        final int bytesLeft = output.length - outputOffset;
+        final int writtenBytes;
+        if (bytesLeft >= maximumLen) {
+            writtenBytes = NativeCrypto.EVP_CipherFinal_ex(cipherCtx, output, outputOffset);
+        } else {
+            final byte[] lastBlock = new byte[maximumLen];
+            writtenBytes = NativeCrypto.EVP_CipherFinal_ex(cipherCtx, lastBlock, 0);
+            if (writtenBytes > bytesLeft) {
+                throw new ShortBufferException("buffer is too short: " + writtenBytes + " > "
+                        + bytesLeft);
+            } else if (writtenBytes > 0) {
+                System.arraycopy(lastBlock, 0, output, outputOffset, writtenBytes);
+            }
+        }
+        outputOffset += writtenBytes;
+
+        reset();
+
+        return outputOffset - initialOutputOffset;
+    }
+
+    @Override
+    int getOutputSizeForFinal(int inputLen) {
+        if (modeBlockSize == 1) {
+            return inputLen;
+        } else {
+            final int buffered = NativeCrypto.get_EVP_CIPHER_CTX_buf_len(cipherCtx);
+
+            if (getPadding() == Padding.NOPADDING) {
+                return buffered + inputLen;
+            } else {
+                final boolean finalUsed = NativeCrypto.get_EVP_CIPHER_CTX_final_used(cipherCtx);
+                // There is an additional buffer containing the possible final block.
+                int totalLen = inputLen + buffered + (finalUsed ? modeBlockSize : 0);
+                // Extra block for remainder bytes plus padding.
+                // In case it's encrypting and there are no remainder bytes, add an extra block
+                // consisting only of padding.
+                totalLen += ((totalLen % modeBlockSize != 0) || isEncrypting())
+                        ? modeBlockSize : 0;
+                // The minimum multiple of {@code modeBlockSize} that can hold all the bytes.
+                return totalLen - (totalLen % modeBlockSize);
+            }
+        }
+    }
+
+    @Override
+    int getOutputSizeForUpdate(int inputLen) {
+        return getOutputSizeForFinal(inputLen);
+    }
+
+    /**
+     * Returns the OpenSSL cipher name for the particular {@code keySize}
+     * and cipher {@code mode}.
+     */
+    abstract String getCipherName(int keySize, Mode mode);
+
+    /**
+     * Reset this Cipher instance state to process a new chunk of data.
+     */
+    private void reset() {
+        NativeCrypto.EVP_CipherInit_ex(cipherCtx, 0, encodedKey, iv, isEncrypting());
+        calledUpdate = false;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherAES.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherAES.java
new file mode 100644
index 0000000..3a7cf5e
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherAES.java
@@ -0,0 +1,353 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLEvpCipherAES extends OpenSSLEvpCipher {
+    private static final int AES_BLOCK_SIZE = 16;
+
+    OpenSSLEvpCipherAES(Mode mode, Padding padding) {
+        super(mode, padding);
+    }
+
+    @Override
+    void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+        switch (mode) {
+            case CBC:
+            case CTR:
+            case ECB:
+                return;
+            default:
+                throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
+        }
+    }
+
+    @Override
+    void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
+        switch (padding) {
+            case NOPADDING:
+            case PKCS5PADDING:
+                return;
+            default:
+                throw new NoSuchPaddingException(
+                        "Unsupported padding " + padding.toString());
+        }
+    }
+
+    @Override
+    String getBaseCipherName() {
+        return "AES";
+    }
+
+    @Override
+    String getCipherName(int keyLength, Mode mode) {
+        return "aes-" + (keyLength * 8) + "-" + mode.toString().toLowerCase(Locale.US);
+    }
+
+    @Override
+    int getCipherBlockSize() {
+        return AES_BLOCK_SIZE;
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class AES extends OpenSSLEvpCipherAES {
+        AES(Mode mode, Padding padding) {
+            super(mode, padding);
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class CBC extends AES {
+            CBC(Padding padding) {
+                super(Mode.CBC, padding);
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class NoPadding extends CBC {
+                @libcore.api.IntraCoreApi
+                public NoPadding() {
+                    super(Padding.NOPADDING);
+                }
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class PKCS5Padding extends CBC {
+                @libcore.api.IntraCoreApi
+                public PKCS5Padding() {
+                    super(Padding.PKCS5PADDING);
+                }
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class CTR extends AES {
+            @libcore.api.IntraCoreApi
+            public CTR() {
+                super(Mode.CTR, Padding.NOPADDING);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class ECB extends AES {
+            ECB(Padding padding) {
+                super(Mode.ECB, padding);
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class NoPadding extends ECB {
+                @libcore.api.IntraCoreApi
+                public NoPadding() {
+                    super(Padding.NOPADDING);
+                }
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class PKCS5Padding extends ECB {
+                @libcore.api.IntraCoreApi
+                public PKCS5Padding() {
+                    super(Padding.PKCS5PADDING);
+                }
+            }
+        }
+
+        @Override
+        void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+            switch (keyLength) {
+                case 16: // AES 128
+                case 24: // AES 192
+                case 32: // AES 256
+                    return;
+                default:
+                    throw new InvalidKeyException("Unsupported key size: " + keyLength
+                        + " bytes");
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class AES_128 extends OpenSSLEvpCipherAES {
+        AES_128(Mode mode, Padding padding) {
+            super(mode, padding);
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class CBC extends AES_128 {
+            CBC(Padding padding) {
+                super(Mode.CBC, padding);
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class NoPadding extends CBC {
+                @libcore.api.IntraCoreApi
+                public NoPadding() {
+                    super(Padding.NOPADDING);
+                }
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class PKCS5Padding extends CBC {
+                @libcore.api.IntraCoreApi
+                public PKCS5Padding() {
+                    super(Padding.PKCS5PADDING);
+                }
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        public static class CTR extends AES_128 {
+            public CTR() {
+                super(Mode.CTR, Padding.NOPADDING);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class ECB extends AES_128 {
+            ECB(Padding padding) {
+                super(Mode.ECB, padding);
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class NoPadding extends ECB {
+                @libcore.api.IntraCoreApi
+                public NoPadding() {
+                    super(Padding.NOPADDING);
+                }
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class PKCS5Padding extends ECB {
+                @libcore.api.IntraCoreApi
+                public PKCS5Padding() {
+                    super(Padding.PKCS5PADDING);
+                }
+            }
+        }
+
+        @Override
+        void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+            if (keyLength != 16) { // 128 bits
+                throw new InvalidKeyException("Unsupported key size: " + keyLength + " bytes");
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class AES_256 extends OpenSSLEvpCipherAES {
+        AES_256(Mode mode, Padding padding) {
+            super(mode, padding);
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class CBC extends AES_256 {
+            CBC(Padding padding) {
+                super(Mode.CBC, padding);
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class NoPadding extends CBC {
+                @libcore.api.IntraCoreApi
+                public NoPadding() {
+                    super(Padding.NOPADDING);
+                }
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class PKCS5Padding extends CBC {
+                @libcore.api.IntraCoreApi
+                public PKCS5Padding() {
+                    super(Padding.PKCS5PADDING);
+                }
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        public static class CTR extends AES_256 {
+            public CTR() {
+                super(Mode.CTR, Padding.NOPADDING);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class ECB extends AES_256 {
+            ECB(Padding padding) {
+                super(Mode.ECB, padding);
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class NoPadding extends ECB {
+                @libcore.api.IntraCoreApi
+                public NoPadding() {
+                    super(Padding.NOPADDING);
+                }
+            }
+
+            /**
+             * @hide This class is not part of the Android public SDK API
+             */
+            @libcore.api.IntraCoreApi
+            public static class PKCS5Padding extends ECB {
+                @libcore.api.IntraCoreApi
+                public PKCS5Padding() {
+                    super(Padding.PKCS5PADDING);
+                }
+            }
+        }
+
+        @Override
+        void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
+            if (keyLength != 32) { // 256 bits
+                throw new InvalidKeyException("Unsupported key size: " + keyLength + " bytes");
+            }
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherARC4.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherARC4.java
new file mode 100644
index 0000000..5e86792
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherARC4.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLEvpCipherARC4 extends OpenSSLEvpCipher {
+    @libcore.api.IntraCoreApi
+    public OpenSSLEvpCipherARC4() {
+        // Modes and padding don't make sense for ARC4.
+        super(Mode.ECB, Padding.NOPADDING);
+    }
+
+    @Override
+    String getBaseCipherName() {
+        return "ARCFOUR";
+    }
+
+    @Override
+    String getCipherName(int keySize, Mode mode) {
+        return "rc4";
+    }
+
+    @Override
+    void checkSupportedKeySize(int keySize) throws InvalidKeyException {
+    }
+
+    @Override
+    void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+        if (mode != Mode.NONE && mode != Mode.ECB) {
+            throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
+        }
+    }
+
+    @Override
+    void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
+        if (padding != Padding.NOPADDING) {
+            throw new NoSuchPaddingException("Unsupported padding " + padding.toString());
+        }
+    }
+
+    @Override
+    int getCipherBlockSize() {
+        return 0;
+    }
+
+    @Override
+    boolean supportsVariableSizeKey() {
+        return true;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherDESEDE.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherDESEDE.java
new file mode 100644
index 0000000..bd8f40a
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLEvpCipherDESEDE.java
@@ -0,0 +1,116 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLEvpCipherDESEDE extends OpenSSLEvpCipher {
+    private static final int DES_BLOCK_SIZE = 8;
+
+    OpenSSLEvpCipherDESEDE(Mode mode, Padding padding) {
+        super(mode, padding);
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static class CBC extends OpenSSLEvpCipherDESEDE {
+        CBC(Padding padding) {
+            super(Mode.CBC, padding);
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class NoPadding extends CBC {
+            @libcore.api.IntraCoreApi
+            public NoPadding() {
+                super(Padding.NOPADDING);
+            }
+        }
+
+        /**
+         * @hide This class is not part of the Android public SDK API
+         */
+        @libcore.api.IntraCoreApi
+        public static class PKCS5Padding extends CBC {
+            @libcore.api.IntraCoreApi
+            public PKCS5Padding() {
+                super(Padding.PKCS5PADDING);
+            }
+        }
+    }
+
+    @Override
+    String getBaseCipherName() {
+        return "DESede";
+    }
+
+    @Override
+    String getCipherName(int keySize, Mode mode) {
+        final String baseCipherName;
+        if (keySize == 16) {
+            baseCipherName = "des-ede";
+        } else {
+            baseCipherName = "des-ede3";
+        }
+
+        return baseCipherName + "-" + mode.toString().toLowerCase(Locale.US);
+    }
+
+    @Override
+    void checkSupportedKeySize(int keySize) throws InvalidKeyException {
+        if (keySize != 16 && keySize != 24) {
+            throw new InvalidKeyException("key size must be 128 or 192 bits");
+        }
+    }
+
+    @Override
+    void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
+        if (mode != Mode.CBC) {
+            throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
+        }
+    }
+
+    @Override
+    void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
+        switch (padding) {
+            case NOPADDING:
+            case PKCS5PADDING:
+                return;
+            default:
+                throw new NoSuchPaddingException("Unsupported padding "
+                        + padding.toString());
+        }
+    }
+
+    @Override
+    int getCipherBlockSize() {
+        return DES_BLOCK_SIZE;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
new file mode 100644
index 0000000..0307073
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
@@ -0,0 +1,355 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * Represents a BoringSSL {@code EVP_PKEY}.
+ */
+final class OpenSSLKey {
+    private final NativeRef.EVP_PKEY ctx;
+
+    private final boolean wrapped;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    OpenSSLKey(long ctx) {
+        this(ctx, false);
+    }
+
+    OpenSSLKey(long ctx, boolean wrapped) {
+        this.ctx = new NativeRef.EVP_PKEY(ctx);
+        this.wrapped = wrapped;
+    }
+
+    /**
+     * Returns the EVP_PKEY context for use in JNI calls.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    NativeRef.EVP_PKEY getNativeRef() {
+        return ctx;
+    }
+
+    boolean isWrapped() {
+        return wrapped;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static OpenSSLKey fromPrivateKey(PrivateKey key) throws InvalidKeyException {
+        if (key instanceof OpenSSLKeyHolder) {
+            return ((OpenSSLKeyHolder) key).getOpenSSLKey();
+        }
+
+        final String keyFormat = key.getFormat();
+        if (keyFormat == null) {
+            return wrapPrivateKey(key);
+        } else if (!"PKCS#8".equals(key.getFormat())) {
+            throw new InvalidKeyException("Unknown key format " + keyFormat);
+        }
+
+        final byte[] encoded = key.getEncoded();
+        if (encoded == null) {
+            throw new InvalidKeyException("Key encoding is null");
+        }
+
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_parse_private_key(key.getEncoded()));
+        } catch (ParsingException e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    /**
+     * Parse a private key in PEM encoding from the provided input stream.
+     *
+     * @throws InvalidKeyException if parsing fails
+     */
+    static OpenSSLKey fromPrivateKeyPemInputStream(InputStream is)
+            throws InvalidKeyException {
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+        try {
+            long keyCtx = NativeCrypto.PEM_read_bio_PrivateKey(bis.getBioContext());
+            if (keyCtx == 0L) {
+                return null;
+            }
+
+            return new OpenSSLKey(keyCtx);
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        } finally {
+            bis.release();
+        }
+    }
+
+    /**
+     * Gets an {@code OpenSSLKey} instance backed by the provided private key. The resulting key is
+     * usable only by this provider's TLS/SSL stack.
+     *
+     * @param privateKey private key.
+     * @param publicKey corresponding public key or {@code null} if not available. Some opaque
+     *        private keys cannot be used by the TLS/SSL stack without the public key.
+     */
+    static OpenSSLKey fromPrivateKeyForTLSStackOnly(
+            PrivateKey privateKey, PublicKey publicKey) throws InvalidKeyException {
+        OpenSSLKey result = getOpenSSLKey(privateKey);
+        if (result != null) {
+            return result;
+        }
+
+        result = fromKeyMaterial(privateKey);
+        if (result != null) {
+            return result;
+        }
+
+        return wrapJCAPrivateKeyForTLSStackOnly(privateKey, publicKey);
+    }
+
+    /**
+     * Gets an {@code OpenSSLKey} instance backed by the provided EC private key. The resulting key
+     * is usable only by this provider's TLS/SSL stack.
+     *
+     * @param key private key.
+     * @param ecParams EC parameters {@code null} if not available. Some opaque private keys cannot
+     *        be used by the TLS/SSL stack without the parameters because the private key itself
+     *        might not expose the parameters.
+     */
+    static OpenSSLKey fromECPrivateKeyForTLSStackOnly(
+            PrivateKey key, ECParameterSpec ecParams) throws InvalidKeyException {
+        OpenSSLKey result = getOpenSSLKey(key);
+        if (result != null) {
+            return result;
+        }
+
+        result = fromKeyMaterial(key);
+        if (result != null) {
+            return result;
+        }
+
+        return OpenSSLECPrivateKey.wrapJCAPrivateKeyForTLSStackOnly(key, ecParams);
+    }
+
+    /**
+     * Gets the {@code OpenSSLKey} instance of the provided key.
+     *
+     * @return instance or {@code null} if the {@code key} is not backed by OpenSSL's
+     *         {@code EVP_PKEY}.
+     */
+    private static OpenSSLKey getOpenSSLKey(PrivateKey key) {
+        if (key instanceof OpenSSLKeyHolder) {
+            return ((OpenSSLKeyHolder) key).getOpenSSLKey();
+        }
+
+        if ("RSA".equals(key.getAlgorithm())) {
+            return Platform.wrapRsaKey(key);
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets an {@code OpenSSLKey} instance initialized with the key material of the provided key.
+     *
+     * @return instance or {@code null} if the {@code key} does not export its key material in a
+     *         suitable format.
+     */
+    private static OpenSSLKey fromKeyMaterial(PrivateKey key) throws InvalidKeyException {
+        if (!"PKCS#8".equals(key.getFormat())) {
+            return null;
+        }
+        byte[] encoded = key.getEncoded();
+        if (encoded == null) {
+            return null;
+        }
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_parse_private_key(encoded));
+        } catch (ParsingException e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    /**
+     * Wraps the provided private key for use in the TLS/SSL stack only. Sign/decrypt operations
+     * using the key will be delegated to the {@code Signature}/{@code Cipher} implementation of the
+     * provider which accepts the key.
+     */
+    private static OpenSSLKey wrapJCAPrivateKeyForTLSStackOnly(PrivateKey privateKey,
+            PublicKey publicKey) throws InvalidKeyException {
+        String keyAlgorithm = privateKey.getAlgorithm();
+        if ("RSA".equals(keyAlgorithm)) {
+            return OpenSSLRSAPrivateKey.wrapJCAPrivateKeyForTLSStackOnly(privateKey, publicKey);
+        } else if ("EC".equals(keyAlgorithm)) {
+            return OpenSSLECPrivateKey.wrapJCAPrivateKeyForTLSStackOnly(privateKey, publicKey);
+        } else {
+            throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private static OpenSSLKey wrapPrivateKey(PrivateKey key) throws InvalidKeyException {
+        if (key instanceof RSAPrivateKey) {
+            return OpenSSLRSAPrivateKey.wrapPlatformKey((RSAPrivateKey) key);
+        } else if (key instanceof ECPrivateKey) {
+            return OpenSSLECPrivateKey.wrapPlatformKey((ECPrivateKey) key);
+        } else {
+            throw new InvalidKeyException("Unknown key type: " + key.toString());
+        }
+    }
+
+    static OpenSSLKey fromPublicKey(PublicKey key) throws InvalidKeyException {
+        if (key instanceof OpenSSLKeyHolder) {
+            return ((OpenSSLKeyHolder) key).getOpenSSLKey();
+        }
+
+        if (!"X.509".equals(key.getFormat())) {
+            throw new InvalidKeyException("Unknown key format " + key.getFormat());
+        }
+
+        final byte[] encoded = key.getEncoded();
+        if (encoded == null) {
+            throw new InvalidKeyException("Key encoding is null");
+        }
+
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_parse_public_key(key.getEncoded()));
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    /**
+     * Parse a public key in PEM encoding from the provided input stream.
+     *
+     * @throws InvalidKeyException if parsing fails
+     */
+    static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
+            throws InvalidKeyException {
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+        try {
+            long keyCtx = NativeCrypto.PEM_read_bio_PUBKEY(bis.getBioContext());
+            if (keyCtx == 0L) {
+                return null;
+            }
+
+            return new OpenSSLKey(keyCtx);
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        } finally {
+            bis.release();
+        }
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    PublicKey getPublicKey() throws NoSuchAlgorithmException {
+        switch (NativeCrypto.EVP_PKEY_type(ctx)) {
+            case NativeConstants.EVP_PKEY_RSA:
+                return new OpenSSLRSAPublicKey(this);
+            case NativeConstants.EVP_PKEY_EC:
+                return new OpenSSLECPublicKey(this);
+            default:
+                throw new NoSuchAlgorithmException("unknown PKEY type");
+        }
+    }
+
+    static PublicKey getPublicKey(X509EncodedKeySpec keySpec, int type)
+            throws InvalidKeySpecException {
+        X509EncodedKeySpec x509KeySpec = keySpec;
+
+        final OpenSSLKey key;
+        try {
+            key = new OpenSSLKey(NativeCrypto.EVP_parse_public_key(x509KeySpec.getEncoded()));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+
+        if (NativeCrypto.EVP_PKEY_type(key.getNativeRef()) != type) {
+            throw new InvalidKeySpecException("Unexpected key type");
+        }
+
+        try {
+            return key.getPublicKey();
+        } catch (NoSuchAlgorithmException e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
+        switch (NativeCrypto.EVP_PKEY_type(ctx)) {
+            case NativeConstants.EVP_PKEY_RSA:
+                return new OpenSSLRSAPrivateKey(this);
+            case NativeConstants.EVP_PKEY_EC:
+                return new OpenSSLECPrivateKey(this);
+            default:
+                throw new NoSuchAlgorithmException("unknown PKEY type");
+        }
+    }
+
+    static PrivateKey getPrivateKey(PKCS8EncodedKeySpec keySpec, int type)
+            throws InvalidKeySpecException {
+        PKCS8EncodedKeySpec pkcs8KeySpec = keySpec;
+
+        final OpenSSLKey key;
+        try {
+            key = new OpenSSLKey(NativeCrypto.EVP_parse_private_key(pkcs8KeySpec.getEncoded()));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+
+        if (NativeCrypto.EVP_PKEY_type(key.getNativeRef()) != type) {
+            throw new InvalidKeySpecException("Unexpected key type");
+        }
+
+        try {
+            return key.getPrivateKey();
+        } catch (NoSuchAlgorithmException e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof OpenSSLKey)) {
+            return false;
+        }
+
+        OpenSSLKey other = (OpenSSLKey) o;
+        if (ctx.equals(other.getNativeRef())) {
+            return true;
+        }
+
+        return NativeCrypto.EVP_PKEY_cmp(ctx, other.getNativeRef()) == 1;
+    }
+
+    @Override
+    public int hashCode() {
+        return ctx.hashCode();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKeyHolder.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKeyHolder.java
new file mode 100644
index 0000000..7921778
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKeyHolder.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt;
+
+/**
+ * Marker interface for classes that hold an {@link OpenSSLKey}.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public interface OpenSSLKeyHolder {
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    OpenSSLKey getOpenSSLKey();
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
new file mode 100644
index 0000000..538aed1
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
@@ -0,0 +1,226 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.MacSpi;
+import javax.crypto.SecretKey;
+
+/**
+ * An implementation of {@link javax.crypto.Mac} which uses BoringSSL to perform all the operations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public abstract class OpenSSLMac extends MacSpi {
+    private NativeRef.HMAC_CTX ctx;
+
+    /**
+     * Holds the EVP_MD for the hashing algorithm, e.g.
+     * EVP_get_digestbyname("sha1");
+     */
+    private final long evp_md;
+
+    /**
+     * The secret key used in this keyed MAC.
+     */
+    private byte[] keyBytes;
+
+    /**
+     * Holds the output size of the message digest.
+     */
+    private final int size;
+
+    /**
+     * Holds a dummy buffer for writing single bytes to the digest.
+     */
+    private final byte[] singleByte = new byte[1];
+
+    private OpenSSLMac(long evp_md, int size) {
+        this.evp_md = evp_md;
+        this.size = size;
+    }
+
+    @Override
+    protected int engineGetMacLength() {
+        return size;
+    }
+
+    @Override
+    protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
+            InvalidAlgorithmParameterException {
+        if (!(key instanceof SecretKey)) {
+            throw new InvalidKeyException("key must be a SecretKey");
+        }
+
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException("unknown parameter type");
+        }
+
+        keyBytes = key.getEncoded();
+        if (keyBytes == null) {
+            throw new InvalidKeyException("key cannot be encoded");
+        }
+
+        resetContext();
+    }
+
+    private final void resetContext() {
+        NativeRef.HMAC_CTX ctxLocal = new NativeRef.HMAC_CTX(NativeCrypto.HMAC_CTX_new());
+        if (keyBytes != null) {
+            NativeCrypto.HMAC_Init_ex(ctxLocal, keyBytes, evp_md);
+        }
+
+        this.ctx = ctxLocal;
+    }
+
+    @Override
+    protected void engineUpdate(byte input) {
+        singleByte[0] = input;
+        engineUpdate(singleByte, 0, 1);
+    }
+
+    @Override
+    protected void engineUpdate(byte[] input, int offset, int len) {
+        final NativeRef.HMAC_CTX ctxLocal = ctx;
+        NativeCrypto.HMAC_Update(ctxLocal, input, offset, len);
+    }
+
+    @Override
+    protected void engineUpdate(ByteBuffer input) {
+        // Optimization: Avoid copying/allocation for direct buffers because their contents are
+        // stored as a contiguous region in memory and thus can be efficiently accessed from native
+        // code.
+
+        if (!input.hasRemaining()) {
+            return;
+        }
+
+        if (!input.isDirect()) {
+            super.engineUpdate(input);
+            return;
+        }
+
+        long baseAddress = NativeCrypto.getDirectBufferAddress(input);
+        if (baseAddress == 0) {
+            // Direct buffer's contents can't be accessed from JNI  -- superclass's implementation
+            // is good enough to handle this.
+            super.engineUpdate(input);
+            return;
+        }
+
+        // MAC the contents between Buffer's position and limit (remaining() number of bytes)
+        int position = input.position();
+        if (position < 0) {
+            throw new RuntimeException("Negative position");
+        }
+        long ptr = baseAddress + position;
+        int len = input.remaining();
+        if (len < 0) {
+            throw new RuntimeException("Negative remaining amount");
+        }
+
+        final NativeRef.HMAC_CTX ctxLocal = ctx;
+        NativeCrypto.HMAC_UpdateDirect(ctxLocal, ptr, len);
+        input.position(position + len);
+    }
+
+    @Override
+    protected byte[] engineDoFinal() {
+        final NativeRef.HMAC_CTX ctxLocal = ctx;
+        final byte[] output = NativeCrypto.HMAC_Final(ctxLocal);
+        resetContext();
+        return output;
+    }
+
+    @Override
+    protected void engineReset() {
+        resetContext();
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacMD5 extends OpenSSLMac {
+        @libcore.api.IntraCoreApi
+        public HmacMD5() {
+            super(EvpMdRef.MD5.EVP_MD, EvpMdRef.MD5.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA1 extends OpenSSLMac {
+        @libcore.api.IntraCoreApi
+        public HmacSHA1() {
+            super(EvpMdRef.SHA1.EVP_MD, EvpMdRef.SHA1.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA224 extends OpenSSLMac {
+        @libcore.api.IntraCoreApi
+        public HmacSHA224() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA224.EVP_MD, EvpMdRef.SHA224.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA256 extends OpenSSLMac {
+        @libcore.api.IntraCoreApi
+        public HmacSHA256() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA256.EVP_MD, EvpMdRef.SHA256.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA384 extends OpenSSLMac {
+        @libcore.api.IntraCoreApi
+        public HmacSHA384() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA384.EVP_MD, EvpMdRef.SHA384.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class HmacSHA512 extends OpenSSLMac {
+        @libcore.api.IntraCoreApi
+        public HmacSHA512() {
+            super(EvpMdRef.SHA512.EVP_MD, EvpMdRef.SHA512.SIZE_BYTES);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMessageDigestJDK.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMessageDigestJDK.java
new file mode 100644
index 0000000..2e756b5
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMessageDigestJDK.java
@@ -0,0 +1,237 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2008 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import java.security.MessageDigestSpi;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Implements the JDK MessageDigest interface using OpenSSL's EVP API.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLMessageDigestJDK extends MessageDigestSpi implements Cloneable {
+    private final NativeRef.EVP_MD_CTX ctx;
+
+    /**
+     * Holds the EVP_MD for the hashing algorithm, e.g. EVP_get_digestbyname("sha1");
+     */
+    private final long evp_md;
+
+    /**
+     * Holds the output size of the message digest.
+     */
+    private final int size;
+
+    /**
+     * Holds a dummy buffer for writing single bytes to the digest.
+     */
+    private final byte[] singleByte = new byte[1];
+
+    /**
+     * Whether the digest struct has been initialized inside EVP_MD_CTX.
+     */
+    private boolean digestInitializedInContext;
+
+    /**
+     * Creates a new OpenSSLMessageDigest instance for the given algorithm name.
+     */
+    private OpenSSLMessageDigestJDK(long evp_md, int size) throws NoSuchAlgorithmException {
+        this.evp_md = evp_md;
+        this.size = size;
+        NativeRef.EVP_MD_CTX ctxLocal = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create());
+        this.ctx = ctxLocal;
+    }
+
+    private OpenSSLMessageDigestJDK(long evp_md, int size, NativeRef.EVP_MD_CTX ctx,
+            boolean digestInitializedInContext) {
+        this.evp_md = evp_md;
+        this.size = size;
+        this.ctx = ctx;
+        this.digestInitializedInContext = digestInitializedInContext;
+    }
+
+    private synchronized void ensureDigestInitializedInContext() {
+        if (!digestInitializedInContext) {
+            final NativeRef.EVP_MD_CTX ctxLocal = ctx;
+            NativeCrypto.EVP_DigestInit_ex(ctxLocal, evp_md);
+            digestInitializedInContext = true;
+        }
+    }
+
+    @Override
+    protected synchronized void engineReset() {
+        // Reset to the same state as at the end of the <init>(long evp_md, int size). We can avoid
+        // allocating a new EVP_MD_CTX by invoking EVP_MD_CTX_cleanup on the existing one.
+        // EVP_MD_CTX_cleanup cleans up and reinitializes the EVP_MD_CTX.
+        final NativeRef.EVP_MD_CTX ctxLocal = ctx;
+        NativeCrypto.EVP_MD_CTX_cleanup(ctxLocal);
+        digestInitializedInContext = false;
+    }
+
+    @Override
+    protected int engineGetDigestLength() {
+        return size;
+    }
+
+    @Override
+    protected synchronized void engineUpdate(byte input) {
+        singleByte[0] = input;
+        engineUpdate(singleByte, 0, 1);
+    }
+
+    @Override
+    protected synchronized void engineUpdate(byte[] input, int offset, int len) {
+        ensureDigestInitializedInContext();
+        NativeCrypto.EVP_DigestUpdate(ctx, input, offset, len);
+    }
+
+    @Override
+    protected synchronized void engineUpdate(ByteBuffer input) {
+        // Optimization: Avoid copying/allocation for direct buffers because their contents are
+        // stored as a contiguous region in memory and thus can be efficiently accessed from native
+        // code.
+
+        if (!input.hasRemaining()) {
+            return;
+        }
+
+        if (!input.isDirect()) {
+            super.engineUpdate(input);
+            return;
+        }
+
+        long baseAddress = NativeCrypto.getDirectBufferAddress(input);
+        if (baseAddress == 0) {
+            // Direct buffer's contents can't be accessed from JNI  -- superclass's implementation
+            // is good enough to handle this.
+            super.engineUpdate(input);
+            return;
+        }
+
+        // Digest the contents between Buffer's position and limit (remaining() number of bytes)
+        int position = input.position();
+        if (position < 0) {
+            throw new RuntimeException("Negative position");
+        }
+        long ptr = baseAddress + position;
+        int len = input.remaining();
+        if (len < 0) {
+            throw new RuntimeException("Negative remaining amount");
+        }
+
+        ensureDigestInitializedInContext();
+        NativeCrypto.EVP_DigestUpdateDirect(ctx, ptr, len);
+        input.position(position + len);
+    }
+
+    @Override
+    protected synchronized byte[] engineDigest() {
+        ensureDigestInitializedInContext();
+        final byte[] result = new byte[size];
+        NativeCrypto.EVP_DigestFinal_ex(ctx, result, 0);
+
+        // Optimized reset path:
+        // 1. No need to wipe EVP_MD_CTX because EVP_DigestFinal_ex has already cleansed any
+        //    sensitive state from it.
+        // 2. Require EVP_DigestInit_ex to be invoked before this MessageDigestSpi starts computing
+        //    a new digest.
+        digestInitializedInContext = false;
+
+        return result;
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class MD5 extends OpenSSLMessageDigestJDK {
+        @libcore.api.IntraCoreApi
+        public MD5() throws NoSuchAlgorithmException {
+            super(EvpMdRef.MD5.EVP_MD, EvpMdRef.MD5.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA1 extends OpenSSLMessageDigestJDK {
+        @libcore.api.IntraCoreApi
+        public SHA1() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA1.EVP_MD, EvpMdRef.SHA1.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA224 extends OpenSSLMessageDigestJDK {
+        @libcore.api.IntraCoreApi
+        public SHA224() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA224.EVP_MD, EvpMdRef.SHA224.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA256 extends OpenSSLMessageDigestJDK {
+        @libcore.api.IntraCoreApi
+        public SHA256() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA256.EVP_MD, EvpMdRef.SHA256.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA384 extends OpenSSLMessageDigestJDK {
+        @libcore.api.IntraCoreApi
+        public SHA384() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA384.EVP_MD, EvpMdRef.SHA384.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA512 extends OpenSSLMessageDigestJDK {
+        @libcore.api.IntraCoreApi
+        public SHA512() throws NoSuchAlgorithmException {
+            super(EvpMdRef.SHA512.EVP_MD, EvpMdRef.SHA512.SIZE_BYTES);
+        }
+    }
+
+    @Override
+    public Object clone() {
+        NativeRef.EVP_MD_CTX ctxCopy = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create());
+        // EVP_MD_CTX_copy_ex requires that the digest struct of source EVP_MD_CTX is initialized.
+        // There's no need to invoke EVP_MD_CTX_copy_ex when the digest struct isn't initialized.
+        if (digestInitializedInContext) {
+            NativeCrypto.EVP_MD_CTX_copy_ex(ctxCopy, ctx);
+        }
+        return new OpenSSLMessageDigestJDK(evp_md, size, ctxCopy, digestInitializedInContext);
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
new file mode 100644
index 0000000..63c53a8
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
@@ -0,0 +1,593 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt;
+
+import java.security.Provider;
+
+/**
+ * Provider that uses BoringSSL to perform the actual cryptographic operations.
+ * <p>
+ * Every algorithm should have its IANA assigned OID as an alias. See the following URLs for each
+ * type: <ul> <li><a
+ * href="http://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml">Hash
+ * functions</a></li> <li><a href="http://www.iana.org/assignments/dssc/dssc.xml">Signature
+ * algorithms</a></li> <li><a
+ * href="http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html">NIST cryptographic
+ * algorithms</a></li>
+ * </ul>
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public final class OpenSSLProvider extends Provider {
+    private static final long serialVersionUID = 2996752495318905136L;
+
+    private static final String PREFIX = OpenSSLProvider.class.getPackage().getName() + ".";
+
+    private static final String STANDARD_EC_PRIVATE_KEY_INTERFACE_CLASS_NAME =
+            "java.security.interfaces.ECPrivateKey";
+    private static final String STANDARD_RSA_PRIVATE_KEY_INTERFACE_CLASS_NAME =
+            "java.security.interfaces.RSAPrivateKey";
+    private static final String STANDARD_RSA_PUBLIC_KEY_INTERFACE_CLASS_NAME =
+            "java.security.interfaces.RSAPublicKey";
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public OpenSSLProvider() {
+        this(Platform.getDefaultProviderName());
+    }
+
+    public OpenSSLProvider(String providerName) {
+        this(providerName, Platform.provideTrustManagerByDefault());
+    }
+
+    OpenSSLProvider(String providerName, boolean includeTrustManager) {
+        super(providerName, 1.0, "Android's OpenSSL-backed security provider");
+
+        // Ensure that the native library has been loaded.
+        NativeCrypto.checkAvailability();
+
+        // Make sure the platform is initialized.
+        Platform.setup();
+
+        /* === SSL Contexts === */
+        final String classOpenSSLContextImpl = PREFIX + "OpenSSLContextImpl";
+        final String tls13SSLContext = classOpenSSLContextImpl + "$TLSv13";
+        // Keep SSL as an alias to TLS
+        put("SSLContext.SSL", tls13SSLContext);
+        put("SSLContext.TLS", tls13SSLContext);
+        put("SSLContext.TLSv1", classOpenSSLContextImpl + "$TLSv1");
+        put("SSLContext.TLSv1.1", classOpenSSLContextImpl + "$TLSv11");
+        put("SSLContext.TLSv1.2", classOpenSSLContextImpl + "$TLSv12");
+        put("SSLContext.TLSv1.3", tls13SSLContext);
+        put("SSLContext.Default", PREFIX + "DefaultSSLContextImpl");
+
+        if (includeTrustManager) {
+            put("TrustManagerFactory.PKIX", TrustManagerFactoryImpl.class.getName());
+            put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
+        }
+
+        /* === AlgorithmParameters === */
+        put("AlgorithmParameters.AES", PREFIX + "IvParameters$AES");
+        put("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.1.2", "AES");
+        put("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.1.22", "AES");
+        put("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.1.42", "AES");
+
+        put("AlgorithmParameters.ChaCha20", PREFIX + "IvParameters$ChaCha20");
+
+        put("AlgorithmParameters.DESEDE", PREFIX + "IvParameters$DESEDE");
+        put("Alg.Alias.AlgorithmParameters.TDEA", "DESEDE");
+        put("Alg.Alias.AlgorithmParameters.1.2.840.113549.3.7", "DESEDE");
+
+        put("AlgorithmParameters.GCM", PREFIX + "GCMParameters");
+        put("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.1.6", "GCM");
+        put("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.1.26", "GCM");
+        put("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.1.46", "GCM");
+        put("AlgorithmParameters.OAEP", PREFIX + "OAEPParameters");
+        put("AlgorithmParameters.PSS", PREFIX + "PSSParameters");
+        put("AlgorithmParameters.EC", PREFIX + "ECParameters");
+
+        /* === Message Digests === */
+        put("MessageDigest.SHA-1", PREFIX + "OpenSSLMessageDigestJDK$SHA1");
+        put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
+        put("Alg.Alias.MessageDigest.SHA", "SHA-1");
+        put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA-1");
+
+        put("MessageDigest.SHA-224", PREFIX + "OpenSSLMessageDigestJDK$SHA224");
+        put("Alg.Alias.MessageDigest.SHA224", "SHA-224");
+        put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
+
+        put("MessageDigest.SHA-256", PREFIX + "OpenSSLMessageDigestJDK$SHA256");
+        put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
+        put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
+
+        put("MessageDigest.SHA-384", PREFIX + "OpenSSLMessageDigestJDK$SHA384");
+        put("Alg.Alias.MessageDigest.SHA384", "SHA-384");
+        put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
+
+        put("MessageDigest.SHA-512", PREFIX + "OpenSSLMessageDigestJDK$SHA512");
+        put("Alg.Alias.MessageDigest.SHA512", "SHA-512");
+        put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
+
+        // iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) md5(5)
+        put("MessageDigest.MD5", PREFIX + "OpenSSLMessageDigestJDK$MD5");
+        put("Alg.Alias.MessageDigest.1.2.840.113549.2.5", "MD5");
+
+        /* == KeyGenerators == */
+        put("KeyGenerator.ARC4", PREFIX + "KeyGeneratorImpl$ARC4");
+        put("Alg.Alias.KeyGenerator.RC4", "ARC4");
+        put("Alg.Alias.KeyGenerator.1.2.840.113549.3.4", "ARC4");
+
+        put("KeyGenerator.AES", PREFIX + "KeyGeneratorImpl$AES");
+
+        put("KeyGenerator.ChaCha20", PREFIX + "KeyGeneratorImpl$ChaCha20");
+
+        put("KeyGenerator.DESEDE", PREFIX + "KeyGeneratorImpl$DESEDE");
+        put("Alg.Alias.KeyGenerator.TDEA", "DESEDE");
+
+        put("KeyGenerator.HmacMD5", PREFIX + "KeyGeneratorImpl$HmacMD5");
+        put("Alg.Alias.KeyGenerator.1.3.6.1.5.5.8.1.1", "HmacMD5");
+        put("Alg.Alias.KeyGenerator.HMAC-MD5", "HmacMD5");
+        put("Alg.Alias.KeyGenerator.HMAC/MD5", "HmacMD5");
+
+        put("KeyGenerator.HmacSHA1", PREFIX + "KeyGeneratorImpl$HmacSHA1");
+        put("Alg.Alias.KeyGenerator.1.2.840.113549.2.7", "HmacSHA1");
+        put("Alg.Alias.KeyGenerator.1.3.6.1.5.5.8.1.2", "HmacSHA1");
+        put("Alg.Alias.KeyGenerator.HMAC-SHA1", "HmacSHA1");
+        put("Alg.Alias.KeyGenerator.HMAC/SHA1", "HmacSHA1");
+
+        put("KeyGenerator.HmacSHA224", PREFIX + "KeyGeneratorImpl$HmacSHA224");
+        put("Alg.Alias.KeyGenerator.1.2.840.113549.2.8", "HmacSHA224");
+        put("Alg.Alias.KeyGenerator.HMAC-SHA224", "HmacSHA224");
+        put("Alg.Alias.KeyGenerator.HMAC/SHA224", "HmacSHA224");
+
+        put("KeyGenerator.HmacSHA256", PREFIX + "KeyGeneratorImpl$HmacSHA256");
+        put("Alg.Alias.KeyGenerator.1.2.840.113549.2.9", "HmacSHA256");
+        put("Alg.Alias.KeyGenerator.2.16.840.1.101.3.4.2.1", "HmacSHA256");
+        put("Alg.Alias.KeyGenerator.HMAC-SHA256", "HmacSHA256");
+        put("Alg.Alias.KeyGenerator.HMAC/SHA256", "HmacSHA256");
+
+        put("KeyGenerator.HmacSHA384", PREFIX + "KeyGeneratorImpl$HmacSHA384");
+        put("Alg.Alias.KeyGenerator.1.2.840.113549.2.10", "HmacSHA384");
+        put("Alg.Alias.KeyGenerator.HMAC-SHA384", "HmacSHA384");
+        put("Alg.Alias.KeyGenerator.HMAC/SHA384", "HmacSHA384");
+
+        put("KeyGenerator.HmacSHA512", PREFIX + "KeyGeneratorImpl$HmacSHA512");
+        put("Alg.Alias.KeyGenerator.1.2.840.113549.2.11", "HmacSHA512");
+        put("Alg.Alias.KeyGenerator.HMAC-SHA512", "HmacSHA512");
+        put("Alg.Alias.KeyGenerator.HMAC/SHA512", "HmacSHA512");
+
+        /* == KeyPairGenerators == */
+        put("KeyPairGenerator.RSA", PREFIX + "OpenSSLRSAKeyPairGenerator");
+        put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.1", "RSA");
+        put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.7", "RSA");
+        put("Alg.Alias.KeyPairGenerator.2.5.8.1.1", "RSA");
+
+        put("KeyPairGenerator.EC", PREFIX + "OpenSSLECKeyPairGenerator");
+        put("Alg.Alias.KeyPairGenerator.1.2.840.10045.2.1", "EC");
+        put("Alg.Alias.KeyPairGenerator.1.3.133.16.840.63.0.2", "EC");
+
+        /* == KeyFactory == */
+        put("KeyFactory.RSA", PREFIX + "OpenSSLRSAKeyFactory");
+        put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.1", "RSA");
+        put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.7", "RSA");
+        put("Alg.Alias.KeyFactory.2.5.8.1.1", "RSA");
+
+        put("KeyFactory.EC", PREFIX + "OpenSSLECKeyFactory");
+        put("Alg.Alias.KeyFactory.1.2.840.10045.2.1", "EC");
+        put("Alg.Alias.KeyFactory.1.3.133.16.840.63.0.2", "EC");
+
+        /* == SecretKeyFactory == */
+        put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
+        put("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
+
+        /* == KeyAgreement == */
+        putECDHKeyAgreementImplClass("OpenSSLECDHKeyAgreement");
+
+        /* == Signatures == */
+        putSignatureImplClass("MD5withRSA", "OpenSSLSignature$MD5RSA");
+        put("Alg.Alias.Signature.MD5withRSAEncryption", "MD5withRSA");
+        put("Alg.Alias.Signature.MD5/RSA", "MD5withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
+        put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1", "MD5withRSA");
+
+        putSignatureImplClass("SHA1withRSA", "OpenSSLSignature$SHA1RSA");
+        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.OID.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("Alg.Alias.Signature.OID.1.3.14.3.2.29", "SHA1withRSA");
+
+        putSignatureImplClass("SHA224withRSA", "OpenSSLSignature$SHA224RSA");
+        put("Alg.Alias.Signature.SHA224withRSAEncryption", "SHA224withRSA");
+        put("Alg.Alias.Signature.SHA224/RSA", "SHA224withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.14", "SHA224withRSA");
+        put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.1",
+                "SHA224withRSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.14",
+                "SHA224withRSA");
+
+        putSignatureImplClass("SHA256withRSA", "OpenSSLSignature$SHA256RSA");
+        put("Alg.Alias.Signature.SHA256withRSAEncryption", "SHA256withRSA");
+        put("Alg.Alias.Signature.SHA256/RSA", "SHA256withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
+        put("Alg.Alias.Signature.OID.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",
+                "SHA256withRSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11",
+                "SHA256withRSA");
+
+        putSignatureImplClass("SHA384withRSA", "OpenSSLSignature$SHA384RSA");
+        put("Alg.Alias.Signature.SHA384withRSAEncryption", "SHA384withRSA");
+        put("Alg.Alias.Signature.SHA384/RSA", "SHA384withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
+        put("Alg.Alias.Signature.OID.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",
+                "SHA384withRSA");
+
+        putSignatureImplClass("SHA512withRSA", "OpenSSLSignature$SHA512RSA");
+        put("Alg.Alias.Signature.SHA512withRSAEncryption", "SHA512withRSA");
+        put("Alg.Alias.Signature.SHA512/RSA", "SHA512withRSA");
+        put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
+        put("Alg.Alias.Signature.OID.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",
+                "SHA512withRSA");
+
+        putRAWRSASignatureImplClass("OpenSSLSignatureRawRSA");
+
+        putSignatureImplClass("NONEwithECDSA", "OpenSSLSignatureRawECDSA");
+
+        putSignatureImplClass("SHA1withECDSA", "OpenSSLSignature$SHA1ECDSA");
+        put("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
+        put("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
+        // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA1(1)
+        put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
+        put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10045.2.1", "SHA1withECDSA");
+
+        // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
+        putSignatureImplClass("SHA224withECDSA", "OpenSSLSignature$SHA224ECDSA");
+        put("Alg.Alias.Signature.SHA224/ECDSA", "SHA224withECDSA");
+        // ecdsa-with-SHA224(1)
+        put("Alg.Alias.Signature.1.2.840.10045.4.3.1", "SHA224withECDSA");
+        put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.10045.2.1", "SHA224withECDSA");
+
+        // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
+        putSignatureImplClass("SHA256withECDSA", "OpenSSLSignature$SHA256ECDSA");
+        put("Alg.Alias.Signature.SHA256/ECDSA", "SHA256withECDSA");
+        // ecdsa-with-SHA256(2)
+        put("Alg.Alias.Signature.1.2.840.10045.4.3.2", "SHA256withECDSA");
+        put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.2", "SHA256withECDSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.10045.2.1", "SHA256withECDSA");
+
+        putSignatureImplClass("SHA384withECDSA", "OpenSSLSignature$SHA384ECDSA");
+        put("Alg.Alias.Signature.SHA384/ECDSA", "SHA384withECDSA");
+        // ecdsa-with-SHA384(3)
+        put("Alg.Alias.Signature.1.2.840.10045.4.3.3", "SHA384withECDSA");
+        put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.3", "SHA384withECDSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.10045.2.1", "SHA384withECDSA");
+
+        putSignatureImplClass("SHA512withECDSA", "OpenSSLSignature$SHA512ECDSA");
+        put("Alg.Alias.Signature.SHA512/ECDSA", "SHA512withECDSA");
+        // ecdsa-with-SHA512(4)
+        put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
+        put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.4", "SHA512withECDSA");
+        put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.10045.2.1", "SHA512withECDSA");
+
+        putSignatureImplClass("SHA1withRSA/PSS", "OpenSSLSignature$SHA1RSAPSS");
+        put("Alg.Alias.Signature.SHA1withRSAandMGF1", "SHA1withRSA/PSS");
+
+        putSignatureImplClass("SHA224withRSA/PSS", "OpenSSLSignature$SHA224RSAPSS");
+        put("Alg.Alias.Signature.SHA224withRSAandMGF1", "SHA224withRSA/PSS");
+
+        putSignatureImplClass("SHA256withRSA/PSS", "OpenSSLSignature$SHA256RSAPSS");
+        put("Alg.Alias.Signature.SHA256withRSAandMGF1", "SHA256withRSA/PSS");
+
+        putSignatureImplClass("SHA384withRSA/PSS", "OpenSSLSignature$SHA384RSAPSS");
+        put("Alg.Alias.Signature.SHA384withRSAandMGF1", "SHA384withRSA/PSS");
+
+        putSignatureImplClass("SHA512withRSA/PSS", "OpenSSLSignature$SHA512RSAPSS");
+        put("Alg.Alias.Signature.SHA512withRSAandMGF1", "SHA512withRSA/PSS");
+
+        /* === SecureRandom === */
+        /*
+         * We have to specify SHA1PRNG because various documentation mentions
+         * that algorithm by name instead of just recommending calling
+         * "new SecureRandom()"
+         */
+        put("SecureRandom.SHA1PRNG", PREFIX + "OpenSSLRandom");
+        put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
+
+        /* === Cipher === */
+        putRSACipherImplClass("RSA/ECB/NoPadding", "OpenSSLCipherRSA$Raw");
+        put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding");
+        putRSACipherImplClass("RSA/ECB/PKCS1Padding", "OpenSSLCipherRSA$PKCS1");
+        put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding");
+
+        putRSACipherImplClass("RSA/ECB/OAEPPadding", "OpenSSLCipherRSA$OAEP$SHA1");
+        put("Alg.Alias.Cipher.RSA/None/OAEPPadding", "RSA/ECB/OAEPPadding");
+        putRSACipherImplClass("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "OpenSSLCipherRSA$OAEP$SHA1");
+        put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-1AndMGF1Padding",
+                "RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
+        putRSACipherImplClass(
+                "RSA/ECB/OAEPWithSHA-224AndMGF1Padding", "OpenSSLCipherRSA$OAEP$SHA224");
+        put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-224AndMGF1Padding",
+                "RSA/ECB/OAEPWithSHA-224AndMGF1Padding");
+        putRSACipherImplClass(
+                "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", "OpenSSLCipherRSA$OAEP$SHA256");
+        put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-256AndMGF1Padding",
+                "RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
+        putRSACipherImplClass(
+                "RSA/ECB/OAEPWithSHA-384AndMGF1Padding", "OpenSSLCipherRSA$OAEP$SHA384");
+        put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-384AndMGF1Padding",
+                "RSA/ECB/OAEPWithSHA-384AndMGF1Padding");
+        putRSACipherImplClass(
+                "RSA/ECB/OAEPWithSHA-512AndMGF1Padding", "OpenSSLCipherRSA$OAEP$SHA512");
+        put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-512AndMGF1Padding",
+                "RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
+
+        /*
+         * OpenSSL only supports a subset of modes, so we'll name them
+         * explicitly here.
+         *
+         * Moreover, OpenSSL only supports PKCS#7 padding. PKCS#5 padding
+         * is also supported because it's a special case of PKCS#7 for 64-bit
+         * blocks. PKCS#5 technically supports only 64-bit blocks and won't
+         * produce the same result as PKCS#7 for blocks that are not 64 bits
+         * long. However, everybody assumes PKCS#7 when they say PKCS#5. For
+         * example, lots of code uses PKCS#5 with AES whose blocks are longer
+         * than 64 bits. We solve this confusion by making PKCS7Padding an
+         * alias for PKCS5Padding.
+         */
+        putSymmetricCipherImplClass("AES/ECB/NoPadding", "OpenSSLEvpCipherAES$AES$ECB$NoPadding");
+        putSymmetricCipherImplClass(
+                "AES/ECB/PKCS5Padding", "OpenSSLEvpCipherAES$AES$ECB$PKCS5Padding");
+        put("Alg.Alias.Cipher.AES/ECB/PKCS7Padding", "AES/ECB/PKCS5Padding");
+        putSymmetricCipherImplClass("AES/CBC/NoPadding", "OpenSSLEvpCipherAES$AES$CBC$NoPadding");
+        putSymmetricCipherImplClass(
+                "AES/CBC/PKCS5Padding", "OpenSSLEvpCipherAES$AES$CBC$PKCS5Padding");
+        put("Alg.Alias.Cipher.AES/CBC/PKCS7Padding", "AES/CBC/PKCS5Padding");
+        putSymmetricCipherImplClass("AES/CTR/NoPadding", "OpenSSLEvpCipherAES$AES$CTR");
+
+        putSymmetricCipherImplClass(
+                "AES_128/ECB/NoPadding", "OpenSSLEvpCipherAES$AES_128$ECB$NoPadding");
+        putSymmetricCipherImplClass(
+                "AES_128/ECB/PKCS5Padding", "OpenSSLEvpCipherAES$AES_128$ECB$PKCS5Padding");
+        put("Alg.Alias.Cipher.AES_128/ECB/PKCS7Padding", "AES_128/ECB/PKCS5Padding");
+        putSymmetricCipherImplClass(
+                "AES_128/CBC/NoPadding", "OpenSSLEvpCipherAES$AES_128$CBC$NoPadding");
+        putSymmetricCipherImplClass(
+                "AES_128/CBC/PKCS5Padding", "OpenSSLEvpCipherAES$AES_128$CBC$PKCS5Padding");
+        put("Alg.Alias.Cipher.AES_128/CBC/PKCS7Padding", "AES_128/CBC/PKCS5Padding");
+
+        put("Alg.Alias.Cipher.PBEWithHmacSHA1AndAES_128", "AES_128/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA224AndAES_128", "AES_128/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA256AndAES_128", "AES_128/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA384AndAES_128", "AES_128/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA512AndAES_128", "AES_128/CBC/PKCS5PADDING");
+
+        putSymmetricCipherImplClass(
+                "AES_256/ECB/NoPadding", "OpenSSLEvpCipherAES$AES_256$ECB$NoPadding");
+        putSymmetricCipherImplClass(
+                "AES_256/ECB/PKCS5Padding", "OpenSSLEvpCipherAES$AES_256$ECB$PKCS5Padding");
+        put("Alg.Alias.Cipher.AES_256/ECB/PKCS7Padding", "AES_256/ECB/PKCS5Padding");
+        putSymmetricCipherImplClass(
+                "AES_256/CBC/NoPadding", "OpenSSLEvpCipherAES$AES_256$CBC$NoPadding");
+        putSymmetricCipherImplClass(
+                "AES_256/CBC/PKCS5Padding", "OpenSSLEvpCipherAES$AES_256$CBC$PKCS5Padding");
+        put("Alg.Alias.Cipher.AES_256/CBC/PKCS7Padding", "AES_256/CBC/PKCS5Padding");
+
+        put("Alg.Alias.Cipher.PBEWithHmacSHA1AndAES_256", "AES_256/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA224AndAES_256", "AES_256/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA256AndAES_256", "AES_256/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA384AndAES_256", "AES_256/CBC/PKCS5PADDING");
+        put("Alg.Alias.Cipher.PBEWithHmacSHA512AndAES_256", "AES_256/CBC/PKCS5PADDING");
+
+        putSymmetricCipherImplClass("DESEDE/CBC/NoPadding", "OpenSSLEvpCipherDESEDE$CBC$NoPadding");
+        putSymmetricCipherImplClass(
+                "DESEDE/CBC/PKCS5Padding", "OpenSSLEvpCipherDESEDE$CBC$PKCS5Padding");
+        put("Alg.Alias.Cipher.DESEDE/CBC/PKCS7Padding", "DESEDE/CBC/PKCS5Padding");
+
+        putSymmetricCipherImplClass("ARC4", "OpenSSLEvpCipherARC4");
+        put("Alg.Alias.Cipher.ARCFOUR", "ARC4");
+        put("Alg.Alias.Cipher.RC4", "ARC4");
+        put("Alg.Alias.Cipher.1.2.840.113549.3.4", "ARC4");
+        put("Alg.Alias.Cipher.OID.1.2.840.113549.3.4", "ARC4");
+
+        putSymmetricCipherImplClass("AES/GCM/NoPadding", "OpenSSLAeadCipherAES$GCM");
+        put("Alg.Alias.Cipher.GCM", "AES/GCM/NoPadding");
+        put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.6", "AES/GCM/NoPadding");
+        put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.26", "AES/GCM/NoPadding");
+        put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.46", "AES/GCM/NoPadding");
+        putSymmetricCipherImplClass("AES_128/GCM/NoPadding", "OpenSSLAeadCipherAES$GCM$AES_128");
+        putSymmetricCipherImplClass("AES_256/GCM/NoPadding", "OpenSSLAeadCipherAES$GCM$AES_256");
+
+        putSymmetricCipherImplClass("AES/GCM-SIV/NoPadding", "OpenSSLAeadCipherAES$GCM_SIV");
+        putSymmetricCipherImplClass(
+                "AES_128/GCM-SIV/NoPadding", "OpenSSLAeadCipherAES$GCM_SIV$AES_128");
+        putSymmetricCipherImplClass(
+                "AES_256/GCM-SIV/NoPadding", "OpenSSLAeadCipherAES$GCM_SIV$AES_256");
+
+        putSymmetricCipherImplClass("ChaCha20",
+                "OpenSSLCipherChaCha20");
+        putSymmetricCipherImplClass("ChaCha20/Poly1305/NoPadding", "OpenSSLAeadCipherChaCha20");
+        put("Alg.Alias.Cipher.ChaCha20-Poly1305", "ChaCha20/Poly1305/NoPadding");
+
+        /* === Mac === */
+
+        putMacImplClass("HmacMD5", "OpenSSLMac$HmacMD5");
+        put("Alg.Alias.Mac.1.3.6.1.5.5.8.1.1", "HmacMD5");
+        put("Alg.Alias.Mac.HMAC-MD5", "HmacMD5");
+        put("Alg.Alias.Mac.HMAC/MD5", "HmacMD5");
+
+        // PKCS#2 - iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2)
+        // http://www.oid-info.com/get/1.2.840.113549.2
+
+        // HMAC-SHA-1 PRF (7)
+        putMacImplClass("HmacSHA1", "OpenSSLMac$HmacSHA1");
+        put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
+        put("Alg.Alias.Mac.1.3.6.1.5.5.8.1.2", "HmacSHA1");
+        put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1");
+        put("Alg.Alias.Mac.HMAC/SHA1", "HmacSHA1");
+
+        // id-hmacWithSHA224 (8)
+        putMacImplClass("HmacSHA224", "OpenSSLMac$HmacSHA224");
+        put("Alg.Alias.Mac.1.2.840.113549.2.8", "HmacSHA224");
+        put("Alg.Alias.Mac.HMAC-SHA224", "HmacSHA224");
+        put("Alg.Alias.Mac.HMAC/SHA224", "HmacSHA224");
+        put("Alg.Alias.Mac.PBEWITHHMACSHA224", "HmacSHA224");
+
+        // id-hmacWithSHA256 (9)
+        putMacImplClass("HmacSHA256", "OpenSSLMac$HmacSHA256");
+        put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA256");
+        put("Alg.Alias.Mac.2.16.840.1.101.3.4.2.1", "HmacSHA256");
+        put("Alg.Alias.Mac.HMAC-SHA256", "HmacSHA256");
+        put("Alg.Alias.Mac.HMAC/SHA256", "HmacSHA256");
+        put("Alg.Alias.Mac.PBEWITHHMACSHA256", "HmacSHA256");
+
+        // id-hmacWithSHA384 (10)
+        putMacImplClass("HmacSHA384", "OpenSSLMac$HmacSHA384");
+        put("Alg.Alias.Mac.1.2.840.113549.2.10", "HmacSHA384");
+        put("Alg.Alias.Mac.HMAC-SHA384", "HmacSHA384");
+        put("Alg.Alias.Mac.HMAC/SHA384", "HmacSHA384");
+        put("Alg.Alias.Mac.PBEWITHHMACSHA384", "HmacSHA384");
+
+        // id-hmacWithSHA384 (11)
+        putMacImplClass("HmacSHA512", "OpenSSLMac$HmacSHA512");
+        put("Alg.Alias.Mac.1.2.840.113549.2.11", "HmacSHA512");
+        put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512");
+        put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512");
+        put("Alg.Alias.Mac.PBEWITHHMACSHA512", "HmacSHA512");
+
+        /* === Certificate === */
+
+        put("CertificateFactory.X509", PREFIX + "OpenSSLX509CertificateFactory");
+        put("Alg.Alias.CertificateFactory.X.509", "X509");
+    }
+
+    private void putMacImplClass(String algorithm, String className) {
+        // Accept only keys for which any of the following is true:
+        // * the key is from this provider (subclass of OpenSSLKeyHolder),
+        // * the key provides its key material in "RAW" encoding via Key.getEncoded.
+        String supportedKeyClasses = PREFIX + "OpenSSLKeyHolder";
+        String supportedKeyFormats = "RAW";
+        putImplClassWithKeyConstraints(
+                "Mac." + algorithm,
+                PREFIX + className,
+                supportedKeyClasses,
+                supportedKeyFormats);
+    }
+
+    private void putSymmetricCipherImplClass(String transformation, String className) {
+        // Accept only keys for which any of the following is true:
+        // * the key provides its key material in "RAW" encoding via Key.getEncoded.
+        String supportedKeyClasses = null; // ignored -- filtered based on encoding format only
+        String supportedKeyFormats = "RAW";
+        putImplClassWithKeyConstraints(
+                "Cipher." + transformation,
+                PREFIX + className,
+                supportedKeyClasses,
+                supportedKeyFormats);
+    }
+
+    private void putRSACipherImplClass(String transformation, String className) {
+        // Accept only keys for which any of the following is true:
+        // * the key is instance of OpenSSLRSAPrivateKey, RSAPrivateKey, OpenSSLRSAPublicKey, or
+        //   RSAPublicKey.
+        String supportedKeyClasses = PREFIX + "OpenSSLRSAPrivateKey"
+                + "|" + STANDARD_RSA_PRIVATE_KEY_INTERFACE_CLASS_NAME
+                + "|" + PREFIX + "OpenSSLRSAPublicKey"
+                + "|" + STANDARD_RSA_PUBLIC_KEY_INTERFACE_CLASS_NAME;
+        String supportedKeyFormats = null; // ignored -- filtered based on class only
+        putImplClassWithKeyConstraints(
+                "Cipher." + transformation,
+                PREFIX + className,
+                supportedKeyClasses,
+                supportedKeyFormats);
+    }
+
+    private void putSignatureImplClass(String algorithm, String className) {
+        // Accept only keys for which any of the following is true:
+        // * the key is from this provider (subclass of OpenSSLKeyHolder),
+        // * the key provides its key material in "PKCS#8" or "X.509" encodings via Key.getEncoded.
+        // * the key is a transparent private key (subclass of RSAPrivateKey or ECPrivateKey). For
+        //   some reason this provider's Signature implementation does not unconditionally accept
+        //   transparent public keys -- it only accepts them if they provide their key material in
+        //   encoded form (see above).
+        String supportedKeyClasses = PREFIX + "OpenSSLKeyHolder"
+                + "|" + STANDARD_RSA_PRIVATE_KEY_INTERFACE_CLASS_NAME
+                + "|" + STANDARD_EC_PRIVATE_KEY_INTERFACE_CLASS_NAME
+                + "|" + STANDARD_RSA_PUBLIC_KEY_INTERFACE_CLASS_NAME;
+        String supportedKeyFormats = "PKCS#8|X.509";
+        putImplClassWithKeyConstraints(
+                "Signature." + algorithm,
+                PREFIX + className,
+                supportedKeyClasses,
+                supportedKeyFormats);
+    }
+
+    private void putRAWRSASignatureImplClass(String className) {
+        // Accept only keys for which any of the following is true:
+        // * the key is instance of OpenSSLRSAPrivateKey, RSAPrivateKey, OpenSSLRSAPublicKey, or
+        //   RSAPublicKey.
+        String supportedKeyClasses = PREFIX + "OpenSSLRSAPrivateKey"
+                + "|" + STANDARD_RSA_PRIVATE_KEY_INTERFACE_CLASS_NAME
+                + "|" + PREFIX + "OpenSSLRSAPublicKey"
+                + "|" + STANDARD_RSA_PUBLIC_KEY_INTERFACE_CLASS_NAME;
+        String supportedKeyFormats = null; // ignored -- filtered based on class only
+        putImplClassWithKeyConstraints(
+                "Signature.NONEwithRSA",
+                PREFIX + className,
+                supportedKeyClasses,
+                supportedKeyFormats);
+    }
+
+    private void putECDHKeyAgreementImplClass(String className) {
+        // Accept only keys for which any of the following is true:
+        // * the key is from this provider (subclass of OpenSSLKeyHolder),
+        // * the key provides its key material in "PKCS#8" encoding via Key.getEncoded.
+        // * the key is a transparent EC private key (subclass of ECPrivateKey).
+        String supportedKeyClasses = PREFIX + "OpenSSLKeyHolder"
+                + "|" + STANDARD_EC_PRIVATE_KEY_INTERFACE_CLASS_NAME;
+        String supportedKeyFormats = "PKCS#8";
+        putImplClassWithKeyConstraints(
+                "KeyAgreement.ECDH",
+                PREFIX + className,
+                supportedKeyClasses,
+                supportedKeyFormats);
+    }
+
+    private void putImplClassWithKeyConstraints(String typeAndAlgName,
+            String fullyQualifiedClassName,
+            String supportedKeyClasses,
+            String supportedKeyFormats) {
+        put(typeAndAlgName, fullyQualifiedClassName);
+        if (supportedKeyClasses != null) {
+            put(typeAndAlgName + " SupportedKeyClasses", supportedKeyClasses);
+        }
+        if (supportedKeyFormats != null) {
+            put(typeAndAlgName + " SupportedKeyFormats", supportedKeyFormats);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAKeyFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAKeyFactory.java
new file mode 100644
index 0000000..4565328
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAKeyFactory.java
@@ -0,0 +1,258 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactorySpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * An implementation of {@link java.security.KeyFactory} which uses BoringSSL to perform all the
+ * operations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLRSAKeyFactory extends KeyFactorySpi {
+    @libcore.api.IntraCoreApi
+    public OpenSSLRSAKeyFactory() {}
+
+    @Override
+    protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("keySpec == null");
+        }
+
+        if (keySpec instanceof RSAPublicKeySpec) {
+            return new OpenSSLRSAPublicKey((RSAPublicKeySpec) keySpec);
+        } else if (keySpec instanceof X509EncodedKeySpec) {
+            return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeConstants.EVP_PKEY_RSA);
+        }
+        throw new InvalidKeySpecException("Must use RSAPublicKeySpec or X509EncodedKeySpec; was "
+                + keySpec.getClass().getName());
+    }
+
+    @Override
+    protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("keySpec == null");
+        }
+
+        if (keySpec instanceof RSAPrivateCrtKeySpec) {
+            return new OpenSSLRSAPrivateCrtKey((RSAPrivateCrtKeySpec) keySpec);
+        } else if (keySpec instanceof RSAPrivateKeySpec) {
+            return new OpenSSLRSAPrivateKey((RSAPrivateKeySpec) keySpec);
+        } else if (keySpec instanceof PKCS8EncodedKeySpec) {
+            return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
+                    NativeConstants.EVP_PKEY_RSA);
+        }
+        throw new InvalidKeySpecException("Must use RSAPublicKeySpec or PKCS8EncodedKeySpec; was "
+                + keySpec.getClass().getName());
+    }
+
+    @Override
+    protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
+            throws InvalidKeySpecException {
+        if (key == null) {
+            throw new InvalidKeySpecException("key == null");
+        }
+
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("keySpec == null");
+        }
+
+        if (!"RSA".equals(key.getAlgorithm())) {
+            throw new InvalidKeySpecException("Key must be a RSA key");
+        }
+
+        if (key instanceof RSAPublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            RSAPublicKey rsaKey = (RSAPublicKey) key;
+            @SuppressWarnings("unchecked")
+            T result = (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
+            return result;
+        } else if (key instanceof PublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"X.509".equals(key.getFormat()) || encoded == null) {
+                throw new InvalidKeySpecException("Not a valid X.509 encoding");
+            }
+            RSAPublicKey rsaKey =
+                    (RSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
+            @SuppressWarnings("unchecked")
+            T result = (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
+            return result;
+        } else if (key instanceof RSAPrivateCrtKey
+                && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
+            RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
+            @SuppressWarnings("unchecked")
+            T result = (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent(),
+                    rsaKey.getPrivateExponent(), rsaKey.getPrimeP(), rsaKey.getPrimeQ(),
+                    rsaKey.getPrimeExponentP(), rsaKey.getPrimeExponentQ(),
+                    rsaKey.getCrtCoefficient());
+            return result;
+        } else if (key instanceof RSAPrivateCrtKey
+                && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
+            @SuppressWarnings("unchecked")
+            T result = (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
+            return result;
+        } else if (key instanceof RSAPrivateKey
+                && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            RSAPrivateKey rsaKey = (RSAPrivateKey) key;
+            @SuppressWarnings("unchecked")
+            T result = (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
+            return result;
+        } else if (key instanceof PrivateKey
+                && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
+                throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
+            }
+            RSAPrivateKey privKey =
+                    (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
+            if (privKey instanceof RSAPrivateCrtKey) {
+                RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) privKey;
+                @SuppressWarnings("unchecked")
+                T result = (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(),
+                        rsaKey.getPublicExponent(), rsaKey.getPrivateExponent(), rsaKey.getPrimeP(),
+                        rsaKey.getPrimeQ(), rsaKey.getPrimeExponentP(), rsaKey.getPrimeExponentQ(),
+                        rsaKey.getCrtCoefficient());
+                return result;
+            } else {
+                throw new InvalidKeySpecException("Encoded key is not an RSAPrivateCrtKey");
+            }
+        } else if (key instanceof PrivateKey && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
+                throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
+            }
+            RSAPrivateKey rsaKey =
+                    (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
+            @SuppressWarnings("unchecked")
+            T result = (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
+            return result;
+        } else if (key instanceof PrivateKey
+                && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"PKCS#8".equals(key.getFormat())) {
+                throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
+                        + key.getFormat());
+            } else if (encoded == null) {
+                throw new InvalidKeySpecException("Key is not encodable");
+            }
+            @SuppressWarnings("unchecked") T result = (T) new PKCS8EncodedKeySpec(encoded);
+            return result;
+        } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
+            final byte[] encoded = key.getEncoded();
+            if (!"X.509".equals(key.getFormat())) {
+                throw new InvalidKeySpecException("Encoding type must be X.509; was "
+                        + key.getFormat());
+            } else if (encoded == null) {
+                throw new InvalidKeySpecException("Key is not encodable");
+            }
+            @SuppressWarnings("unchecked") T result = (T) new X509EncodedKeySpec(encoded);
+            return result;
+        } else {
+            throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
+                    + key.getClass().getName() + ", keySpec=" + keySpec.getName());
+        }
+    }
+
+    @Override
+    protected Key engineTranslateKey(Key key) throws InvalidKeyException {
+        if (key == null) {
+            throw new InvalidKeyException("key == null");
+        }
+
+        if ((key instanceof OpenSSLRSAPublicKey) || (key instanceof OpenSSLRSAPrivateKey)) {
+            return key;
+        } else if (key instanceof RSAPublicKey) {
+            RSAPublicKey rsaKey = (RSAPublicKey) key;
+
+            try {
+                return engineGeneratePublic(new RSAPublicKeySpec(rsaKey.getModulus(),
+                        rsaKey.getPublicExponent()));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if (key instanceof RSAPrivateCrtKey) {
+            RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
+            BigInteger modulus = rsaKey.getModulus();
+            BigInteger publicExponent = rsaKey.getPublicExponent();
+            BigInteger privateExponent = rsaKey.getPrivateExponent();
+            BigInteger primeP = rsaKey.getPrimeP();
+            BigInteger primeQ = rsaKey.getPrimeQ();
+            BigInteger primeExponentP = rsaKey.getPrimeExponentP();
+            BigInteger primeExponentQ = rsaKey.getPrimeExponentQ();
+            BigInteger crtCoefficient = rsaKey.getCrtCoefficient();
+
+            try {
+                return engineGeneratePrivate(new RSAPrivateCrtKeySpec(modulus, publicExponent,
+                        privateExponent, primeP, primeQ, primeExponentP, primeExponentQ,
+                        crtCoefficient));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if (key instanceof RSAPrivateKey) {
+            RSAPrivateKey rsaKey = (RSAPrivateKey) key;
+            BigInteger modulus = rsaKey.getModulus();
+            BigInteger privateExponent = rsaKey.getPrivateExponent();
+
+            try {
+                return engineGeneratePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
+            byte[] encoded = key.getEncoded();
+            if (encoded == null) {
+                throw new InvalidKeyException("Key does not support encoding");
+            }
+            try {
+                return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else if ((key instanceof PublicKey) && "X.509".equals(key.getFormat())) {
+            byte[] encoded = key.getEncoded();
+            if (encoded == null) {
+                throw new InvalidKeyException("Key does not support encoding");
+            }
+            try {
+                return engineGeneratePublic(new X509EncodedKeySpec(encoded));
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException(e);
+            }
+        } else {
+            throw new InvalidKeyException("Key must be an RSA public or private key; was "
+                    + key.getClass().getName());
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAKeyPairGenerator.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAKeyPairGenerator.java
new file mode 100644
index 0000000..4501a49
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAKeyPairGenerator.java
@@ -0,0 +1,85 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGeneratorSpi;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+/**
+ * An implementation of {@link java.security.KeyPairGenerator} which uses BoringSSL to perform all
+ * the operations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLRSAKeyPairGenerator extends KeyPairGeneratorSpi {
+    /**
+     * Default modulus size is 0x10001 (65537)
+     */
+    private byte[] publicExponent = new byte[] {
+            0x01, 0x00, 0x01
+    };
+
+    /**
+     * Default RSA key size 2048 bits.
+     */
+    private int modulusBits = 2048;
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLRSAKeyPairGenerator() {}
+
+    @Override
+    public KeyPair generateKeyPair() {
+        final OpenSSLKey key = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(modulusBits,
+                publicExponent));
+
+        PrivateKey privKey = OpenSSLRSAPrivateKey.getInstance(key);
+        PublicKey pubKey = new OpenSSLRSAPublicKey(key);
+
+        return new KeyPair(pubKey, privKey);
+    }
+
+    @Override
+    public void initialize(int keysize, SecureRandom random) {
+        this.modulusBits = keysize;
+    }
+
+    @Override
+    public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidAlgorithmParameterException {
+        if (!(params instanceof RSAKeyGenParameterSpec)) {
+            throw new InvalidAlgorithmParameterException("Only RSAKeyGenParameterSpec supported");
+        }
+
+        RSAKeyGenParameterSpec spec = (RSAKeyGenParameterSpec) params;
+
+        final BigInteger publicExponent = spec.getPublicExponent();
+        if (publicExponent != null) {
+            this.publicExponent = publicExponent.toByteArray();
+        }
+
+        this.modulusBits = spec.getKeysize();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateCrtKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
new file mode 100644
index 0000000..22188bc
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
@@ -0,0 +1,285 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateCrtKeySpec;
+
+/**
+ * An implementation of {@link java.security.PrivateKey} for RSA keys which uses BoringSSL to
+ * perform all the operations.
+ */
+final class OpenSSLRSAPrivateCrtKey extends OpenSSLRSAPrivateKey implements RSAPrivateCrtKey {
+    private static final long serialVersionUID = 3785291944868707197L;
+
+    private BigInteger publicExponent;
+
+    private BigInteger primeP;
+
+    private BigInteger primeQ;
+
+    private BigInteger primeExponentP;
+
+    private BigInteger primeExponentQ;
+
+    private BigInteger crtCoefficient;
+
+    OpenSSLRSAPrivateCrtKey(OpenSSLKey key) {
+        super(key);
+    }
+
+    OpenSSLRSAPrivateCrtKey(OpenSSLKey key, byte[][] params) {
+        super(key, params);
+    }
+
+    OpenSSLRSAPrivateCrtKey(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
+        super(init(rsaKeySpec));
+    }
+
+    private static OpenSSLKey init(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
+        BigInteger modulus = rsaKeySpec.getModulus();
+        BigInteger privateExponent = rsaKeySpec.getPrivateExponent();
+
+        if (modulus == null) {
+            throw new InvalidKeySpecException("modulus == null");
+        } else if (privateExponent == null) {
+            throw new InvalidKeySpecException("privateExponent == null");
+        }
+
+        try {
+            /*
+             * OpenSSL uses the public modulus to do RSA blinding. If
+             * the public modulus is not available, the call to
+             * EVP_PKEY_new_RSA will turn off blinding for this key
+             * instance.
+             */
+            final BigInteger publicExponent = rsaKeySpec.getPublicExponent();
+            final BigInteger primeP = rsaKeySpec.getPrimeP();
+            final BigInteger primeQ = rsaKeySpec.getPrimeQ();
+            final BigInteger primeExponentP = rsaKeySpec.getPrimeExponentP();
+            final BigInteger primeExponentQ = rsaKeySpec.getPrimeExponentQ();
+            final BigInteger crtCoefficient = rsaKeySpec.getCrtCoefficient();
+
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                    modulus.toByteArray(),
+                    publicExponent == null ? null : publicExponent.toByteArray(),
+                    privateExponent.toByteArray(),
+                    primeP == null ? null : primeP.toByteArray(),
+                    primeQ == null ? null : primeQ.toByteArray(),
+                    primeExponentP == null ? null : primeExponentP.toByteArray(),
+                    primeExponentQ == null ? null : primeExponentQ.toByteArray(),
+                    crtCoefficient == null ? null : crtCoefficient.toByteArray()));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    static OpenSSLKey getInstance(RSAPrivateCrtKey rsaPrivateKey) throws InvalidKeyException {
+        /**
+         * If the key is not encodable (PKCS11-like key), then wrap it and use
+         * JNI upcalls to satisfy requests.
+         */
+        if (rsaPrivateKey.getFormat() == null) {
+            return wrapPlatformKey(rsaPrivateKey);
+        }
+
+        BigInteger modulus = rsaPrivateKey.getModulus();
+        BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
+
+        if (modulus == null) {
+            throw new InvalidKeyException("modulus == null");
+        } else if (privateExponent == null) {
+            throw new InvalidKeyException("privateExponent == null");
+        }
+
+        try {
+            /*
+             * OpenSSL uses the public modulus to do RSA blinding. If
+             * the public modulus is not available, the call to
+             * EVP_PKEY_new_RSA will turn off blinding for this key
+             * instance.
+             */
+            final BigInteger publicExponent = rsaPrivateKey.getPublicExponent();
+            final BigInteger primeP = rsaPrivateKey.getPrimeP();
+            final BigInteger primeQ = rsaPrivateKey.getPrimeQ();
+            final BigInteger primeExponentP = rsaPrivateKey.getPrimeExponentP();
+            final BigInteger primeExponentQ = rsaPrivateKey.getPrimeExponentQ();
+            final BigInteger crtCoefficient = rsaPrivateKey.getCrtCoefficient();
+
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                    modulus.toByteArray(),
+                    publicExponent == null ? null : publicExponent.toByteArray(),
+                    privateExponent.toByteArray(),
+                    primeP == null ? null : primeP.toByteArray(),
+                    primeQ == null ? null : primeQ.toByteArray(),
+                    primeExponentP == null ? null : primeExponentP.toByteArray(),
+                    primeExponentQ == null ? null : primeExponentQ.toByteArray(),
+                    crtCoefficient == null ? null : crtCoefficient.toByteArray()));
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    @Override
+    synchronized void readParams(byte[][] params) {
+        super.readParams(params);
+        // params[0] read in super.readParams
+        if (params[1] != null) {
+            publicExponent = new BigInteger(params[1]);
+        }
+        // params[2] read in super.readParams
+        if (params[3] != null) {
+            primeP = new BigInteger(params[3]);
+        }
+        if (params[4] != null) {
+            primeQ = new BigInteger(params[4]);
+        }
+        if (params[5] != null) {
+            primeExponentP = new BigInteger(params[5]);
+        }
+        if (params[6] != null) {
+            primeExponentQ = new BigInteger(params[6]);
+        }
+        if (params[7] != null) {
+            crtCoefficient = new BigInteger(params[7]);
+        }
+    }
+
+    @Override
+    public BigInteger getPublicExponent() {
+        ensureReadParams();
+        return publicExponent;
+    }
+
+    @Override
+    public BigInteger getPrimeP() {
+        ensureReadParams();
+        return primeP;
+    }
+
+    @Override
+    public BigInteger getPrimeQ() {
+        ensureReadParams();
+        return primeQ;
+    }
+
+    @Override
+    public BigInteger getPrimeExponentP() {
+        ensureReadParams();
+        return primeExponentP;
+    }
+
+    @Override
+    public BigInteger getPrimeExponentQ() {
+        ensureReadParams();
+        return primeExponentQ;
+    }
+
+    @Override
+    public BigInteger getCrtCoefficient() {
+        ensureReadParams();
+        return crtCoefficient;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (o instanceof OpenSSLRSAPrivateKey) {
+            OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
+            return getOpenSSLKey().equals(other.getOpenSSLKey());
+        }
+
+        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());
+        } else if (o instanceof RSAPrivateKey) {
+            ensureReadParams();
+            RSAPrivateKey other = (RSAPrivateKey) o;
+
+            return getModulus().equals(other.getModulus())
+                    && getPrivateExponent().equals(other.getPrivateExponent());
+        }
+
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        int hashCode = super.hashCode();
+        if (publicExponent != null) {
+            hashCode ^= publicExponent.hashCode();
+        }
+        return hashCode;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateCrtKey{");
+
+        ensureReadParams();
+        sb.append("modulus=");
+        sb.append(getModulus().toString(16));
+
+        if (publicExponent != null) {
+            sb.append(',');
+            sb.append("publicExponent=");
+            sb.append(publicExponent.toString(16));
+        }
+
+        sb.append('}');
+        return sb.toString();
+    }
+
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+
+        key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                modulus.toByteArray(),
+                publicExponent == null ? null : publicExponent.toByteArray(),
+                privateExponent.toByteArray(),
+                primeP == null ? null : primeP.toByteArray(),
+                primeQ == null ? null : primeQ.toByteArray(),
+                primeExponentP == null ? null : primeExponentP.toByteArray(),
+                primeExponentQ == null ? null : primeExponentQ.toByteArray(),
+                crtCoefficient == null ? null : crtCoefficient.toByteArray()));
+        fetchedParams = true;
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        ensureReadParams();
+        stream.defaultWriteObject();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java
new file mode 100644
index 0000000..bb34171
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPrivateKey.java
@@ -0,0 +1,278 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateKeySpec;
+
+/**
+ * An implementation of {@link java.security.PrivateKey} for RSA keys which uses BoringSSL to
+ * perform all the operations.
+ */
+class OpenSSLRSAPrivateKey implements RSAPrivateKey, OpenSSLKeyHolder {
+    private static final long serialVersionUID = 4872170254439578735L;
+
+    transient OpenSSLKey key;
+
+    transient boolean fetchedParams;
+
+    BigInteger modulus;
+
+    BigInteger privateExponent;
+
+    OpenSSLRSAPrivateKey(OpenSSLKey key) {
+        this.key = key;
+    }
+
+    OpenSSLRSAPrivateKey(OpenSSLKey key, byte[][] params) {
+        this(key);
+        readParams(params);
+        fetchedParams = true;
+    }
+
+    @Override
+    public OpenSSLKey getOpenSSLKey() {
+        return key;
+    }
+
+    public OpenSSLRSAPrivateKey(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
+        this(init(rsaKeySpec));
+    }
+
+    private static OpenSSLKey init(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
+        final BigInteger modulus = rsaKeySpec.getModulus();
+        final BigInteger privateExponent = rsaKeySpec.getPrivateExponent();
+
+        if (modulus == null) {
+            throw new InvalidKeySpecException("modulus == null");
+        } else if (privateExponent == null) {
+            throw new InvalidKeySpecException("privateExponent == null");
+        }
+
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                    modulus.toByteArray(),
+                    null,
+                    privateExponent.toByteArray(),
+                    null,
+                    null,
+                    null,
+                    null,
+                    null));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
+        byte[][] params = NativeCrypto.get_RSA_private_params(key.getNativeRef());
+        if (params[1] != null) {
+            return new OpenSSLRSAPrivateCrtKey(key, params);
+        }
+        return new OpenSSLRSAPrivateKey(key, params);
+    }
+
+    static OpenSSLKey wrapPlatformKey(RSAPrivateKey rsaPrivateKey)
+            throws InvalidKeyException {
+        OpenSSLKey wrapper = Platform.wrapRsaKey(rsaPrivateKey);
+        if (wrapper != null) {
+            return wrapper;
+        }
+        return new OpenSSLKey(NativeCrypto.getRSAPrivateKeyWrapper(rsaPrivateKey, rsaPrivateKey
+                .getModulus().toByteArray()), true);
+    }
+
+    /**
+     * Wraps the provided private key for use in the TLS/SSL stack only. Sign/decrypt operations
+     * using the key will be delegated to the {@code Signature}/{@code Cipher} implementation of the
+     * provider which accepts the key.
+     */
+    static OpenSSLKey wrapJCAPrivateKeyForTLSStackOnly(PrivateKey privateKey,
+            PublicKey publicKey) throws InvalidKeyException {
+        BigInteger modulus = null;
+        if (privateKey instanceof RSAKey) {
+            modulus = ((RSAKey) privateKey).getModulus();
+        } else if (publicKey instanceof RSAKey) {
+            modulus = ((RSAKey) publicKey).getModulus();
+        }
+        if (modulus == null) {
+            throw new InvalidKeyException("RSA modulus not available. Private: " + privateKey
+                    + ", public: " + publicKey);
+        }
+        return new OpenSSLKey(
+                NativeCrypto.getRSAPrivateKeyWrapper(privateKey, modulus.toByteArray()), true);
+    }
+
+    static OpenSSLKey getInstance(RSAPrivateKey rsaPrivateKey) throws InvalidKeyException {
+        /**
+         * If the key is not encodable (PKCS11-like key), then wrap it and use
+         * JNI upcalls to satisfy requests.
+         */
+        if (rsaPrivateKey.getFormat() == null) {
+            return wrapPlatformKey(rsaPrivateKey);
+        }
+
+        final BigInteger modulus = rsaPrivateKey.getModulus();
+        final BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
+
+        if (modulus == null) {
+            throw new InvalidKeyException("modulus == null");
+        } else if (privateExponent == null) {
+            throw new InvalidKeyException("privateExponent == null");
+        }
+
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                    modulus.toByteArray(),
+                    null,
+                    privateExponent.toByteArray(),
+                    null,
+                    null,
+                    null,
+                    null,
+                    null));
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    synchronized final void ensureReadParams() {
+        if (fetchedParams) {
+            return;
+        }
+        readParams(NativeCrypto.get_RSA_private_params(key.getNativeRef()));
+        fetchedParams = true;
+    }
+
+    void readParams(byte[][] params) {
+        if (params[0] == null) {
+            throw new NullPointerException("modulus == null");
+        } else if (params[2] == null) {
+            throw new NullPointerException("privateExponent == null");
+        }
+
+        modulus = new BigInteger(params[0]);
+
+        // ENGINE-based keys are not guaranteed to have a private exponent.
+        if (params[2] != null) {
+            privateExponent = new BigInteger(params[2]);
+        }
+    }
+
+    @Override
+    public final BigInteger getPrivateExponent() {
+        ensureReadParams();
+        return privateExponent;
+    }
+
+    @Override
+    public final BigInteger getModulus() {
+        ensureReadParams();
+        return modulus;
+    }
+
+    @Override
+    public final byte[] getEncoded() {
+        return NativeCrypto.EVP_marshal_private_key(key.getNativeRef());
+    }
+
+    @Override
+    public final String getFormat() {
+        return "PKCS#8";
+    }
+
+    @Override
+    public final String getAlgorithm() {
+        return "RSA";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (o instanceof OpenSSLRSAPrivateKey) {
+            OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
+            return key.equals(other.getOpenSSLKey());
+        }
+
+        if (o instanceof RSAPrivateKey) {
+            ensureReadParams();
+            RSAPrivateKey other = (RSAPrivateKey) o;
+
+            return modulus.equals(other.getModulus())
+                    && privateExponent.equals(other.getPrivateExponent());
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        ensureReadParams();
+        int hash = 1;
+
+        hash = hash * 3 + modulus.hashCode();
+        if (privateExponent != null) {
+            hash = hash * 7 + privateExponent.hashCode();
+        }
+
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");
+
+        ensureReadParams();
+        sb.append("modulus=");
+        sb.append(modulus.toString(16));
+
+        return sb.toString();
+    }
+
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+
+        key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                modulus.toByteArray(),
+                null,
+                privateExponent.toByteArray(),
+                null,
+                null,
+                null,
+                null,
+                null));
+        fetchedParams = true;
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        ensureReadParams();
+        stream.defaultWriteObject();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPublicKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPublicKey.java
new file mode 100644
index 0000000..8821fd0
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRSAPublicKey.java
@@ -0,0 +1,196 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPublicKeySpec;
+
+/**
+ * An implementation of {@link java.security.PublicKey} for RSA keys which uses BoringSSL to
+ * perform all the operations.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class OpenSSLRSAPublicKey implements RSAPublicKey, OpenSSLKeyHolder {
+    private static final long serialVersionUID = 123125005824688292L;
+
+    private transient OpenSSLKey key;
+
+    private BigInteger publicExponent;
+
+    private BigInteger modulus;
+
+    private transient boolean fetchedParams;
+
+    OpenSSLRSAPublicKey(OpenSSLKey key) {
+        this.key = key;
+    }
+
+    @Override
+    public OpenSSLKey getOpenSSLKey() {
+        return key;
+    }
+
+    OpenSSLRSAPublicKey(RSAPublicKeySpec spec) throws InvalidKeySpecException {
+        try {
+            key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                    spec.getModulus().toByteArray(),
+                    spec.getPublicExponent().toByteArray(),
+                    null,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null));
+        } catch (Exception e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    static OpenSSLKey getInstance(RSAPublicKey rsaPublicKey) throws InvalidKeyException {
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                    rsaPublicKey.getModulus().toByteArray(),
+                    rsaPublicKey.getPublicExponent().toByteArray(),
+                    null,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null));
+        } catch (Exception e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return "RSA";
+    }
+
+    @Override
+    public String getFormat() {
+        return "X.509";
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return NativeCrypto.EVP_marshal_public_key(key.getNativeRef());
+    }
+
+    private synchronized void ensureReadParams() {
+        if (fetchedParams) {
+            return;
+        }
+
+        byte[][] params = NativeCrypto.get_RSA_public_params(key.getNativeRef());
+        modulus = new BigInteger(params[0]);
+        publicExponent = new BigInteger(params[1]);
+
+        fetchedParams = true;
+    }
+
+    @Override
+    public BigInteger getModulus() {
+        ensureReadParams();
+        return modulus;
+    }
+
+    @Override
+    public BigInteger getPublicExponent() {
+        ensureReadParams();
+        return publicExponent;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (o instanceof OpenSSLRSAPublicKey) {
+            OpenSSLRSAPublicKey other = (OpenSSLRSAPublicKey) o;
+
+            /*
+             * We can shortcut the true case, but it still may be equivalent but
+             * different copies.
+             */
+            if (key.equals(other.getOpenSSLKey())) {
+                return true;
+            }
+        }
+
+        if (!(o instanceof RSAPublicKey)) {
+            return false;
+        }
+
+        ensureReadParams();
+
+        RSAPublicKey other = (RSAPublicKey) o;
+        return modulus.equals(other.getModulus())
+                && publicExponent.equals(other.getPublicExponent());
+    }
+
+    @Override
+    public int hashCode() {
+        ensureReadParams();
+
+        return modulus.hashCode() ^ publicExponent.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        ensureReadParams();
+
+        final StringBuilder sb = new StringBuilder("OpenSSLRSAPublicKey{");
+        sb.append("modulus=");
+        sb.append(modulus.toString(16));
+        sb.append(',');
+        sb.append("publicExponent=");
+        sb.append(publicExponent.toString(16));
+        sb.append('}');
+
+        return sb.toString();
+    }
+
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+
+        key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
+                modulus.toByteArray(),
+                publicExponent.toByteArray(),
+                null,
+                null,
+                null,
+                null,
+                null,
+                null));
+        fetchedParams = true;
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        ensureReadParams();
+        stream.defaultWriteObject();
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRandom.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRandom.java
new file mode 100644
index 0000000..69d7309
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLRandom.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.Serializable;
+import java.security.SecureRandomSpi;
+
+/**
+ * Implements {@link java.security.SecureRandom} using BoringSSL's RAND interface.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLRandom extends SecureRandomSpi implements Serializable {
+    private static final long serialVersionUID = 8506210602917522861L;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.IntraCoreApi
+    public OpenSSLRandom() {}
+
+    @Override
+    protected void engineSetSeed(byte[] seed) {
+        if (seed == null) {
+            throw new NullPointerException("seed == null");
+        }
+    }
+
+    @Override
+    protected void engineNextBytes(byte[] bytes) {
+        NativeCrypto.RAND_bytes(bytes);
+    }
+
+    @Override
+    protected byte[] engineGenerateSeed(int numBytes) {
+        byte[] output = new byte[numBytes];
+        NativeCrypto.RAND_bytes(output);
+        return output;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLServerSocketFactoryImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
new file mode 100644
index 0000000..540d7e4
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
@@ -0,0 +1,104 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2007 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.security.KeyManagementException;
+import javax.net.ssl.SSLServerSocketFactory;
+
+/**
+ * An implementation of {@link SSLServerSocketFactory} using BoringSSL.
+ *
+ * <p/>This name of this class cannot change in order to maintain backward-compatibility with GMS
+ * core {@code ProviderInstallerImpl}
+ */
+final class OpenSSLServerSocketFactoryImpl extends SSLServerSocketFactory {
+    private static boolean useEngineSocketByDefault = SSLUtils.USE_ENGINE_SOCKET_BY_DEFAULT;
+
+    private SSLParametersImpl sslParameters;
+    private IOException instantiationException;
+    private boolean useEngineSocket = useEngineSocketByDefault;
+
+    OpenSSLServerSocketFactoryImpl() {
+        try {
+            this.sslParameters = SSLParametersImpl.getDefault();
+            this.sslParameters.setUseClientMode(false);
+        } catch (KeyManagementException e) {
+            instantiationException = new IOException("Delayed instantiation exception:");
+            instantiationException.initCause(e);
+        }
+    }
+
+    OpenSSLServerSocketFactoryImpl(SSLParametersImpl sslParameters) {
+        this.sslParameters = (SSLParametersImpl) sslParameters.clone();
+        this.sslParameters.setUseClientMode(false);
+    }
+
+    /**
+     * Configures the default socket to be created for all instances.
+     */
+    static void setUseEngineSocketByDefault(boolean useEngineSocket) {
+        useEngineSocketByDefault = useEngineSocket;
+    }
+
+    /**
+     * Configures the socket to be created for this instance. If not called,
+     * {@link #useEngineSocketByDefault} will be used.
+     */
+    void setUseEngineSocket(boolean useEngineSocket) {
+        this.useEngineSocket = useEngineSocket;
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+        return sslParameters.getEnabledCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return NativeCrypto.getSupportedCipherSuites();
+    }
+
+    @Override
+    public ServerSocket createServerSocket() throws IOException {
+        return new ConscryptServerSocket((SSLParametersImpl) sslParameters.clone())
+                .setUseEngineSocket(useEngineSocket);
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port) throws IOException {
+        return new ConscryptServerSocket(port, (SSLParametersImpl) sslParameters.clone())
+                .setUseEngineSocket(useEngineSocket);
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port, int backlog) throws IOException {
+        return new ConscryptServerSocket(port, backlog, (SSLParametersImpl) sslParameters.clone())
+                .setUseEngineSocket(useEngineSocket);
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port, int backlog, InetAddress iAddress)
+            throws IOException {
+        return new ConscryptServerSocket(
+                port, backlog, iAddress, (SSLParametersImpl) sslParameters.clone())
+                .setUseEngineSocket(useEngineSocket);
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignature.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignature.java
new file mode 100644
index 0000000..f62600d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignature.java
@@ -0,0 +1,576 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2008 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 com.android.org.conscrypt;
+
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.ProviderException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+
+/**
+ * Implements the subset of the JDK Signature interface needed for
+ * signature verification using OpenSSL.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLSignature extends SignatureSpi {
+    private enum EngineType {
+        RSA, EC,
+    }
+
+    private NativeRef.EVP_MD_CTX ctx;
+
+    /**
+     * The current OpenSSL key we're operating on.
+     */
+    private OpenSSLKey key;
+
+    /**
+     * Holds the type of the Java algorithm.
+     */
+    private final EngineType engineType;
+
+    /**
+     * Digest algorithm (reference to {@code EVP_MD}).
+     */
+    private final long evpMdRef;
+
+    /**
+     * Holds a dummy buffer for writing single bytes to the digest.
+     */
+    private final byte[] singleByte = new byte[1];
+
+    /**
+     * True when engine is initialized to signing.
+     */
+    private boolean signing;
+
+    /**
+     * Public key algorithm context (reference to {@code EVP_PKEY_CTX}).
+     */
+    private long evpPkeyCtx;
+
+    /**
+     * Creates a new OpenSSLSignature instance for the given algorithm name.
+     *
+     * @param evpMdRef digest algorithm ({@code EVP_MD} reference).
+     */
+    private OpenSSLSignature(long evpMdRef, EngineType engineType) {
+        this.engineType = engineType;
+        this.evpMdRef = evpMdRef;
+    }
+
+    private void resetContext() throws InvalidAlgorithmParameterException {
+        NativeRef.EVP_MD_CTX ctxLocal = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create());
+        if (signing) {
+            evpPkeyCtx = NativeCrypto.EVP_DigestSignInit(ctxLocal, evpMdRef, key.getNativeRef());
+        } else {
+            evpPkeyCtx = NativeCrypto.EVP_DigestVerifyInit(ctxLocal, evpMdRef, key.getNativeRef());
+        }
+        configureEVP_PKEY_CTX(evpPkeyCtx);
+        this.ctx = ctxLocal;
+    }
+
+    /**
+     * Configures the public key algorithm context ({@code EVP_PKEY_CTX}) associated with this
+     * operation.
+     *
+     * <p>The default implementation does nothing.
+     *
+     * @param ctx reference to the context ({@code EVP_PKEY_CTX}).
+     */
+    protected void configureEVP_PKEY_CTX(long ctx) throws InvalidAlgorithmParameterException {}
+
+    @Override
+    protected void engineUpdate(byte input) {
+        singleByte[0] = input;
+        engineUpdate(singleByte, 0, 1);
+    }
+
+    @Override
+    protected void engineUpdate(byte[] input, int offset, int len) {
+        final NativeRef.EVP_MD_CTX ctxLocal = ctx;
+        if (signing) {
+            NativeCrypto.EVP_DigestSignUpdate(ctxLocal, input, offset, len);
+        } else {
+            NativeCrypto.EVP_DigestVerifyUpdate(ctxLocal, input, offset, len);
+        }
+    }
+
+    @Override
+    protected void engineUpdate(ByteBuffer input) {
+        // Optimization: Avoid copying/allocation for direct buffers because their contents are
+        // stored as a contiguous region in memory and thus can be efficiently accessed from native
+        // code.
+
+        if (!input.hasRemaining()) {
+            return;
+        }
+
+        if (!input.isDirect()) {
+            super.engineUpdate(input);
+            return;
+        }
+
+        long baseAddress = NativeCrypto.getDirectBufferAddress(input);
+        if (baseAddress == 0) {
+            // Direct buffer's contents can't be accessed from JNI  -- superclass's implementation
+            // is good enough to handle this.
+            super.engineUpdate(input);
+            return;
+        }
+
+        // Process the contents between Buffer's position and limit (remaining() number of bytes)
+        int position = input.position();
+        if (position < 0) {
+            throw new RuntimeException("Negative position");
+        }
+        long ptr = baseAddress + position;
+        int len = input.remaining();
+        if (len < 0) {
+            throw new RuntimeException("Negative remaining amount");
+        }
+
+        final NativeRef.EVP_MD_CTX ctxLocal = ctx;
+        if (signing) {
+            NativeCrypto.EVP_DigestSignUpdateDirect(ctxLocal, ptr, len);
+        } else {
+            NativeCrypto.EVP_DigestVerifyUpdateDirect(ctxLocal, ptr, len);
+        }
+        input.position(position + len);
+    }
+
+    @Deprecated
+    @Override
+    protected Object engineGetParameter(String param) throws InvalidParameterException {
+        return null;
+    }
+
+    private void checkEngineType(OpenSSLKey pkey) throws InvalidKeyException {
+        final int pkeyType = NativeCrypto.EVP_PKEY_type(pkey.getNativeRef());
+
+        switch (engineType) {
+            case RSA:
+                if (pkeyType != NativeConstants.EVP_PKEY_RSA) {
+                    throw new InvalidKeyException("Signature initialized as " + engineType
+                            + " (not RSA)");
+                }
+                break;
+            case EC:
+                if (pkeyType != NativeConstants.EVP_PKEY_EC) {
+                    throw new InvalidKeyException("Signature initialized as " + engineType
+                            + " (not EC)");
+                }
+                break;
+            default:
+                throw new InvalidKeyException("Key must be of type " + engineType);
+        }
+    }
+
+    private void initInternal(OpenSSLKey newKey, boolean signing) throws InvalidKeyException {
+        checkEngineType(newKey);
+        key = newKey;
+
+        this.signing = signing;
+        try {
+            resetContext();
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new InvalidKeyException(e);
+        }
+    }
+
+    @Override
+    protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+        initInternal(OpenSSLKey.fromPrivateKey(privateKey), true);
+    }
+
+    @Override
+    protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+        initInternal(OpenSSLKey.fromPublicKey(publicKey), false);
+    }
+
+    @Deprecated
+    @Override
+    protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
+    }
+
+    @Override
+    @SuppressWarnings("Finally")
+    protected byte[] engineSign() throws SignatureException {
+        final NativeRef.EVP_MD_CTX ctxLocal = ctx;
+        try {
+            return NativeCrypto.EVP_DigestSignFinal(ctxLocal);
+        } catch (Exception ex) {
+            throw new SignatureException(ex);
+        } finally {
+            /*
+             * Java expects the digest context to be reset completely after sign
+             * calls.
+             */
+            try {
+                resetContext();
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new AssertionError("Reset of context failed after it was successful once");
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings("Finally")
+    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+        final NativeRef.EVP_MD_CTX ctxLocal = ctx;
+        try {
+            return NativeCrypto.EVP_DigestVerifyFinal(ctxLocal, sigBytes, 0, sigBytes.length);
+        } catch (Exception ex) {
+            throw new SignatureException(ex);
+        } finally {
+            /*
+             * Java expects the digest context to be reset completely after
+             * verify calls.
+             */
+            try {
+                resetContext();
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new AssertionError("Reset of context failed after it was successful once");
+            }
+        }
+    }
+
+    /**
+     * Returns the public key algorithm context ({@code EVP_PKEY_CTX} reference) associated with
+     * this operation or {@code 0} if operation hasn't been initialized.
+     */
+    protected final long getEVP_PKEY_CTX() {
+        return evpPkeyCtx;
+    }
+
+    /**
+     * Base class for {@code RSASSA-PKCS1-v1_5} signatures.
+     */
+    abstract static class RSAPKCS1Padding extends OpenSSLSignature {
+        RSAPKCS1Padding(long evpMdRef) {
+            super(evpMdRef, EngineType.RSA);
+        }
+
+        @Override
+        protected final void configureEVP_PKEY_CTX(long ctx)
+                throws InvalidAlgorithmParameterException {
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_padding(ctx, NativeConstants.RSA_PKCS1_PADDING);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class MD5RSA extends RSAPKCS1Padding {
+        @libcore.api.IntraCoreApi
+        public MD5RSA() {
+            super(EvpMdRef.MD5.EVP_MD);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA1RSA extends RSAPKCS1Padding {
+        @libcore.api.IntraCoreApi
+        public SHA1RSA() {
+            super(EvpMdRef.SHA1.EVP_MD);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA224RSA extends RSAPKCS1Padding {
+        @libcore.api.IntraCoreApi
+        public SHA224RSA() {
+            super(EvpMdRef.SHA224.EVP_MD);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA256RSA extends RSAPKCS1Padding {
+        @libcore.api.IntraCoreApi
+        public SHA256RSA() {
+            super(EvpMdRef.SHA256.EVP_MD);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA384RSA extends RSAPKCS1Padding {
+        @libcore.api.IntraCoreApi
+        public SHA384RSA() {
+            super(EvpMdRef.SHA384.EVP_MD);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA512RSA extends RSAPKCS1Padding {
+        @libcore.api.IntraCoreApi
+        public SHA512RSA() {
+            super(EvpMdRef.SHA512.EVP_MD);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA1ECDSA extends OpenSSLSignature {
+        @libcore.api.IntraCoreApi
+        public SHA1ECDSA() {
+            super(EvpMdRef.SHA1.EVP_MD, EngineType.EC);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA224ECDSA extends OpenSSLSignature {
+        @libcore.api.IntraCoreApi
+        public SHA224ECDSA() {
+            super(EvpMdRef.SHA224.EVP_MD, EngineType.EC);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA256ECDSA extends OpenSSLSignature {
+        @libcore.api.IntraCoreApi
+        public SHA256ECDSA() {
+            super(EvpMdRef.SHA256.EVP_MD, EngineType.EC);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA384ECDSA extends OpenSSLSignature {
+        @libcore.api.IntraCoreApi
+        public SHA384ECDSA() {
+            super(EvpMdRef.SHA384.EVP_MD, EngineType.EC);
+        }
+    }
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA512ECDSA extends OpenSSLSignature {
+        @libcore.api.IntraCoreApi
+        public SHA512ECDSA() {
+            super(EvpMdRef.SHA512.EVP_MD, EngineType.EC);
+        }
+    }
+
+    /**
+     * Base class for {@code RSASSA-PSS} signatures.
+     */
+    abstract static class RSAPSSPadding extends OpenSSLSignature {
+        private static final int TRAILER_FIELD_BC_ID = 1;
+
+        private final String contentDigestAlgorithm;
+
+        private String mgf1DigestAlgorithm;
+        private long mgf1EvpMdRef;
+        private int saltSizeBytes;
+
+        RSAPSSPadding(
+                long contentDigestEvpMdRef, String contentDigestAlgorithm, int saltSizeBytes) {
+            super(contentDigestEvpMdRef, EngineType.RSA);
+            this.contentDigestAlgorithm = contentDigestAlgorithm;
+            this.mgf1DigestAlgorithm = contentDigestAlgorithm;
+            this.mgf1EvpMdRef = contentDigestEvpMdRef;
+            this.saltSizeBytes = saltSizeBytes;
+        }
+
+        @Override
+        protected final void configureEVP_PKEY_CTX(long ctx)
+                throws InvalidAlgorithmParameterException {
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_padding(ctx, NativeConstants.RSA_PKCS1_PSS_PADDING);
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1EvpMdRef);
+            NativeCrypto.EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltSizeBytes);
+        }
+
+        @Override
+        protected final void engineSetParameter(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            if (!(params instanceof PSSParameterSpec)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Unsupported parameter: " + params + ". Only "
+                                + PSSParameterSpec.class.getName() + " supported");
+            }
+            PSSParameterSpec spec = (PSSParameterSpec) params;
+            String specContentDigest = EvpMdRef
+                    .getJcaDigestAlgorithmStandardName(spec.getDigestAlgorithm());
+            if (specContentDigest == null) {
+                throw new InvalidAlgorithmParameterException(
+                        "Unsupported content digest algorithm: " + spec.getDigestAlgorithm());
+            } else if (!contentDigestAlgorithm.equalsIgnoreCase(specContentDigest)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Changing content digest algorithm not supported");
+            }
+
+            String specMgfAlgorithm = spec.getMGFAlgorithm();
+            if (!EvpMdRef.MGF1_ALGORITHM_NAME.equalsIgnoreCase(specMgfAlgorithm)
+                    && !EvpMdRef.MGF1_OID.equals(specMgfAlgorithm)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Unsupported MGF algorithm: " + specMgfAlgorithm + ". Only "
+                                + EvpMdRef.MGF1_ALGORITHM_NAME + " supported");
+            }
+
+            AlgorithmParameterSpec mgfSpec = spec.getMGFParameters();
+            if (!(mgfSpec instanceof MGF1ParameterSpec)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Unsupported MGF parameters: " + mgfSpec + ". Only "
+                                + MGF1ParameterSpec.class.getName() + " supported");
+            }
+            MGF1ParameterSpec specMgf1Spec = (MGF1ParameterSpec) spec.getMGFParameters();
+
+            String specMgf1Digest = EvpMdRef
+                    .getJcaDigestAlgorithmStandardName(specMgf1Spec.getDigestAlgorithm());
+            if (specMgf1Digest == null) {
+                throw new InvalidAlgorithmParameterException(
+                        "Unsupported MGF1 digest algorithm: " + specMgf1Spec.getDigestAlgorithm());
+            }
+            long specMgf1EvpMdRef;
+            try {
+                specMgf1EvpMdRef = EvpMdRef
+                        .getEVP_MDByJcaDigestAlgorithmStandardName(specMgf1Digest);
+            } catch (NoSuchAlgorithmException e) {
+                throw new ProviderException("Failed to obtain EVP_MD for " + specMgf1Digest, e);
+            }
+
+            int specSaltSizeBytes = spec.getSaltLength();
+            if (specSaltSizeBytes < 0) {
+                throw new InvalidAlgorithmParameterException(
+                        "Salt length must be non-negative: " + specSaltSizeBytes);
+            }
+
+            int specTrailer = spec.getTrailerField();
+            if (specTrailer != TRAILER_FIELD_BC_ID) {
+                throw new InvalidAlgorithmParameterException(
+                        "Unsupported trailer field: " + specTrailer + ". Only "
+                                + TRAILER_FIELD_BC_ID + " supported");
+            }
+
+            this.mgf1DigestAlgorithm = specMgf1Digest;
+            this.mgf1EvpMdRef = specMgf1EvpMdRef;
+            this.saltSizeBytes = specSaltSizeBytes;
+
+            long ctx = getEVP_PKEY_CTX();
+            if (ctx != 0) {
+                configureEVP_PKEY_CTX(ctx);
+            }
+        }
+
+        @Override
+        protected final AlgorithmParameters engineGetParameters() {
+            try {
+                AlgorithmParameters result = AlgorithmParameters.getInstance("PSS");
+                result.init(
+                        new PSSParameterSpec(
+                                contentDigestAlgorithm,
+                                EvpMdRef.MGF1_ALGORITHM_NAME,
+                                new MGF1ParameterSpec(mgf1DigestAlgorithm),
+                                saltSizeBytes,
+                                TRAILER_FIELD_BC_ID));
+                return result;
+            } catch (NoSuchAlgorithmException e) {
+                throw new ProviderException("Failed to create PSS AlgorithmParameters", e);
+            } catch (InvalidParameterSpecException e) {
+                throw new ProviderException("Failed to create PSS AlgorithmParameters", e);
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA1RSAPSS extends RSAPSSPadding {
+        @libcore.api.IntraCoreApi
+        public SHA1RSAPSS() {
+            super(EvpMdRef.SHA1.EVP_MD, EvpMdRef.SHA1.JCA_NAME, EvpMdRef.SHA1.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA224RSAPSS extends RSAPSSPadding {
+        @libcore.api.IntraCoreApi
+        public SHA224RSAPSS() {
+            super(EvpMdRef.SHA224.EVP_MD, EvpMdRef.SHA224.JCA_NAME, EvpMdRef.SHA224.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA256RSAPSS extends RSAPSSPadding {
+        @libcore.api.IntraCoreApi
+        public SHA256RSAPSS() {
+            super(EvpMdRef.SHA256.EVP_MD, EvpMdRef.SHA256.JCA_NAME, EvpMdRef.SHA256.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA384RSAPSS extends RSAPSSPadding {
+        @libcore.api.IntraCoreApi
+        public SHA384RSAPSS() {
+            super(EvpMdRef.SHA384.EVP_MD, EvpMdRef.SHA384.JCA_NAME, EvpMdRef.SHA384.SIZE_BYTES);
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @libcore.api.IntraCoreApi
+    public static final class SHA512RSAPSS extends RSAPSSPadding {
+        @libcore.api.IntraCoreApi
+        public SHA512RSAPSS() {
+            super(EvpMdRef.SHA512.EVP_MD, EvpMdRef.SHA512.JCA_NAME, EvpMdRef.SHA512.SIZE_BYTES);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignatureRawECDSA.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignatureRawECDSA.java
new file mode 100644
index 0000000..9710801
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignatureRawECDSA.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayOutputStream;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+
+/**
+ * Implements the JDK Signature interface needed for RAW ECDSA signature
+ * generation and verification using BoringSSL.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLSignatureRawECDSA extends SignatureSpi {
+    /**
+     * The current OpenSSL key we're operating on.
+     */
+    private OpenSSLKey key;
+
+    /**
+     * Buffer to hold value to be signed or verified.
+     */
+    private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLSignatureRawECDSA() {}
+
+    @Override
+    protected void engineUpdate(byte input) {
+        buffer.write(input);
+    }
+
+    @Override
+    protected void engineUpdate(byte[] input, int offset, int len) {
+        buffer.write(input, offset, len);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    protected Object engineGetParameter(String param) throws InvalidParameterException {
+        return null;
+    }
+
+    private static OpenSSLKey verifyKey(OpenSSLKey key) throws InvalidKeyException {
+        int pkeyType = NativeCrypto.EVP_PKEY_type(key.getNativeRef());
+        if (pkeyType != NativeConstants.EVP_PKEY_EC) {
+            throw new InvalidKeyException("Non-EC key used to initialize EC signature.");
+        }
+        return key;
+    }
+
+    @Override
+    protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+        key = verifyKey(OpenSSLKey.fromPrivateKey(privateKey));
+    }
+
+    @Override
+    protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+        key = verifyKey(OpenSSLKey.fromPublicKey(publicKey));
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
+    }
+
+    @Override
+    protected byte[] engineSign() throws SignatureException {
+        if (key == null) {
+            // This can't actually happen, but you never know...
+            throw new SignatureException("No key provided");
+        }
+
+        int output_size = NativeCrypto.ECDSA_size(key.getNativeRef());
+        byte[] outputBuffer = new byte[output_size];
+        try {
+            int bytes_written =
+                    NativeCrypto.ECDSA_sign(buffer.toByteArray(), outputBuffer, key.getNativeRef());
+            if (bytes_written < 0) {
+                throw new SignatureException("Could not compute signature.");
+            }
+            // There's no guarantee that the signature will be ECDSA_size bytes long,
+            // that's just the maximum possible length of a signature.  Only return the bytes
+            // that were actually produced.
+            if (bytes_written != output_size) {
+                byte[] newBuffer = new byte[bytes_written];
+                System.arraycopy(outputBuffer, 0, newBuffer, 0, bytes_written);
+                outputBuffer = newBuffer;
+            }
+            return outputBuffer;
+        } catch (Exception ex) {
+            throw new SignatureException(ex);
+        } finally {
+            buffer.reset();
+        }
+    }
+
+    @Override
+    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+        if (key == null) {
+            // This can't actually happen, but you never know...
+            throw new SignatureException("No key provided");
+        }
+
+        try {
+            int result =
+                    NativeCrypto.ECDSA_verify(buffer.toByteArray(), sigBytes, key.getNativeRef());
+            if (result == -1) {
+                throw new SignatureException("Could not verify signature.");
+            }
+            return result == 1;
+        } catch (Exception ex) {
+            throw new SignatureException(ex);
+        } finally {
+            buffer.reset();
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignatureRawRSA.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignatureRawRSA.java
new file mode 100644
index 0000000..5b7d2b8
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSignatureRawRSA.java
@@ -0,0 +1,203 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * Implements the JDK Signature interface needed for RAW RSA signature
+ * generation and verification using BoringSSL.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public final class OpenSSLSignatureRawRSA extends SignatureSpi {
+    /**
+     * The current OpenSSL key we're operating on.
+     */
+    private OpenSSLKey key;
+
+    /**
+     * Buffer to hold value to be signed or verified.
+     */
+    private byte[] inputBuffer;
+
+    /**
+     * Current offset in input buffer.
+     */
+    private int inputOffset;
+
+    /**
+     * Provides a flag to specify when the input is too long.
+     */
+    private boolean inputIsTooLong;
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLSignatureRawRSA() {}
+
+    @Override
+    protected void engineUpdate(byte input) {
+        final int oldOffset = inputOffset++;
+
+        if (inputOffset > inputBuffer.length) {
+            inputIsTooLong = true;
+            return;
+        }
+
+        inputBuffer[oldOffset] = input;
+    }
+
+    @Override
+    protected void engineUpdate(byte[] input, int offset, int len) {
+        final int oldOffset = inputOffset;
+        inputOffset += len;
+
+        if (inputOffset > inputBuffer.length) {
+            inputIsTooLong = true;
+            return;
+        }
+
+        System.arraycopy(input, offset, inputBuffer, oldOffset, len);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    protected Object engineGetParameter(String param) throws InvalidParameterException {
+        return null;
+    }
+
+    @Override
+    protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+        if (privateKey instanceof OpenSSLRSAPrivateKey) {
+            OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) privateKey;
+            key = rsaPrivateKey.getOpenSSLKey();
+        } else if (privateKey instanceof RSAPrivateCrtKey) {
+            RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
+            key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
+        } else if (privateKey instanceof RSAPrivateKey) {
+            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
+            key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
+        } else {
+            throw new InvalidKeyException("Need RSA private key");
+        }
+
+        // Allocate buffer according to RSA modulus size.
+        int maxSize = NativeCrypto.RSA_size(key.getNativeRef());
+        inputBuffer = new byte[maxSize];
+        inputOffset = 0;
+    }
+
+    @Override
+    protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+        if (publicKey instanceof OpenSSLRSAPublicKey) {
+            OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) publicKey;
+            key = rsaPublicKey.getOpenSSLKey();
+        } else if (publicKey instanceof RSAPublicKey) {
+            RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
+            key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
+        } else {
+            throw new InvalidKeyException("Need RSA public key");
+        }
+
+        // Allocate buffer according to RSA modulus size.
+        int maxSize = NativeCrypto.RSA_size(key.getNativeRef());
+        inputBuffer = new byte[maxSize];
+        inputOffset = 0;
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
+    }
+
+    @Override
+    protected byte[] engineSign() throws SignatureException {
+        if (key == null) {
+            // This can't actually happen, but you never know...
+            throw new SignatureException("Need RSA private key");
+        }
+
+        if (inputIsTooLong) {
+            throw new SignatureException("input length " + inputOffset + " != "
+                    + inputBuffer.length + " (modulus size)");
+        }
+
+        byte[] outputBuffer = new byte[inputBuffer.length];
+        try {
+            NativeCrypto.RSA_private_encrypt(inputOffset, inputBuffer, outputBuffer,
+                    key.getNativeRef(), NativeConstants.RSA_PKCS1_PADDING);
+            return outputBuffer;
+        } catch (Exception ex) {
+            throw new SignatureException(ex);
+        } finally {
+            inputOffset = 0;
+        }
+    }
+
+    @Override
+    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+        if (key == null) {
+            // This can't actually happen, but you never know...
+            throw new SignatureException("Need RSA public key");
+        }
+
+        if (inputIsTooLong) {
+            return false;
+        }
+
+        // We catch this case here instead of BoringSSL so we can throw an
+        // exception that matches other implementations.
+        if (sigBytes.length > inputBuffer.length) {
+            throw new SignatureException("Input signature length is too large: " + sigBytes.length
+                    + " > " + inputBuffer.length);
+        }
+
+        byte[] outputBuffer = new byte[inputBuffer.length];
+        try {
+            final int resultSize;
+            try {
+                resultSize = NativeCrypto.RSA_public_decrypt(sigBytes.length, sigBytes,
+                        outputBuffer, key.getNativeRef(), NativeConstants.RSA_PKCS1_PADDING);
+            } catch (SignatureException e) {
+                throw e;
+            } catch (Exception e) {
+                return false;
+            }
+            /* Make this constant time by comparing every byte. */
+            boolean matches = (resultSize == inputOffset);
+            for (int i = 0; i < resultSize; i++) {
+                if (inputBuffer[i] != outputBuffer[i]) {
+                    matches = false;
+                }
+            }
+            return matches;
+        } catch (Exception ex) {
+            throw new SignatureException(ex);
+        } finally {
+            inputOffset = 0;
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketFactoryImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketFactoryImpl.java
new file mode 100644
index 0000000..748c529
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketFactoryImpl.java
@@ -0,0 +1,173 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2007 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.Platform.createEngineSocket;
+import static com.android.org.conscrypt.Platform.createFileDescriptorSocket;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * An implementation of {@link SSLSocketFactory} based on BoringSSL.
+ *
+ * <p/>This name of this class cannot change in order to maintain backward-compatibility with GMS
+ * core {@code ProviderInstallerImpl}
+ */
+final class OpenSSLSocketFactoryImpl extends SSLSocketFactory {
+    private static boolean useEngineSocketByDefault = SSLUtils.USE_ENGINE_SOCKET_BY_DEFAULT;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private final SSLParametersImpl sslParameters;
+    private final IOException instantiationException;
+    private boolean useEngineSocket = useEngineSocketByDefault;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    OpenSSLSocketFactoryImpl() {
+        SSLParametersImpl sslParametersLocal = null;
+        IOException instantiationExceptionLocal = null;
+        try {
+            sslParametersLocal = SSLParametersImpl.getDefault();
+        } catch (KeyManagementException e) {
+            instantiationExceptionLocal = new IOException("Delayed instantiation exception:", e);
+        }
+        this.sslParameters = sslParametersLocal;
+        this.instantiationException = instantiationExceptionLocal;
+    }
+
+    OpenSSLSocketFactoryImpl(SSLParametersImpl sslParameters) {
+        this.sslParameters = sslParameters;
+        this.instantiationException = null;
+    }
+
+    /**
+     * Configures the default socket to be created for all instances.
+     */
+    static void setUseEngineSocketByDefault(boolean useEngineSocket) {
+        useEngineSocketByDefault = useEngineSocket;
+    }
+
+    /**
+     * Configures the socket to be created for this instance. If not called,
+     * {@link #useEngineSocketByDefault} will be used.
+     */
+    void setUseEngineSocket(boolean useEngineSocket) {
+        this.useEngineSocket = useEngineSocket;
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+        return sslParameters.getEnabledCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return NativeCrypto.getSupportedCipherSuites();
+    }
+
+    @Override
+    public Socket createSocket() throws IOException {
+        if (instantiationException != null) {
+            throw instantiationException;
+        }
+        if (useEngineSocket) {
+            return createEngineSocket((SSLParametersImpl) sslParameters.clone());
+        } else {
+            return createFileDescriptorSocket((SSLParametersImpl) sslParameters.clone());
+        }
+    }
+
+    @Override
+    public Socket createSocket(String hostname, int port) throws IOException, UnknownHostException {
+        if (useEngineSocket) {
+            return createEngineSocket(
+                    hostname, port, (SSLParametersImpl) sslParameters.clone());
+        } else {
+            return createFileDescriptorSocket(
+                    hostname, port, (SSLParametersImpl) sslParameters.clone());
+        }
+    }
+
+    @Override
+    public Socket createSocket(String hostname, int port, InetAddress localHost, int localPort)
+            throws IOException, UnknownHostException {
+        if (useEngineSocket) {
+            return createEngineSocket(hostname, port, localHost,
+                    localPort, (SSLParametersImpl) sslParameters.clone());
+        } else {
+            return createFileDescriptorSocket(hostname, port, localHost,
+                    localPort, (SSLParametersImpl) sslParameters.clone());
+        }
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port) throws IOException {
+        if (useEngineSocket) {
+            return createEngineSocket(
+                    address, port, (SSLParametersImpl) sslParameters.clone());
+        } else {
+            return createFileDescriptorSocket(
+                    address, port, (SSLParametersImpl) sslParameters.clone());
+        }
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+            int localPort) throws IOException {
+        if (useEngineSocket) {
+            return createEngineSocket(address, port, localAddress,
+                    localPort, (SSLParametersImpl) sslParameters.clone());
+        } else {
+            return createFileDescriptorSocket(address, port, localAddress,
+                    localPort, (SSLParametersImpl) sslParameters.clone());
+        }
+    }
+
+    @Override
+    public Socket createSocket(Socket socket, String hostname, int port, boolean autoClose)
+            throws IOException {
+        Preconditions.checkNotNull(socket, "socket");
+        if (!socket.isConnected()) {
+            throw new SocketException("Socket is not connected.");
+        }
+
+        if (!useEngineSocket && hasFileDescriptor(socket)) {
+            return createFileDescriptorSocket(
+                    socket, hostname, port, autoClose, (SSLParametersImpl) sslParameters.clone());
+        } else {
+            return createEngineSocket(
+                    socket, hostname, port, autoClose, (SSLParametersImpl) sslParameters.clone());
+        }
+    }
+
+    private boolean hasFileDescriptor(Socket s) {
+        try {
+            // If socket has a file descriptor we can use it directly
+            // otherwise we need to use the engine.
+            Platform.getFileDescriptor(s);
+            return true;
+        } catch (RuntimeException re) {
+            return false;
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java
new file mode 100644
index 0000000..42d0261
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLSocketImpl.java
@@ -0,0 +1,183 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2007 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 com.android.org.conscrypt;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.security.PrivateKey;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * Public shim allowing us to stay backward-compatible with legacy applications which were using
+ * Conscrypt's extended socket API before the introduction of the {@link Conscrypt} class.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public abstract class OpenSSLSocketImpl extends AbstractConscryptSocket {
+    OpenSSLSocketImpl() throws IOException {
+    }
+
+    OpenSSLSocketImpl(String hostname, int port) throws IOException {
+        super(hostname, port);
+    }
+
+    OpenSSLSocketImpl(InetAddress address, int port) throws IOException {
+        super(address, port);
+    }
+
+    OpenSSLSocketImpl(String hostname, int port, InetAddress clientAddress, int clientPort)
+        throws IOException {
+        super(hostname, port, clientAddress, clientPort);
+    }
+
+    OpenSSLSocketImpl(InetAddress address, int port, InetAddress clientAddress,
+        int clientPort)
+        throws IOException {
+        super(address, port, clientAddress, clientPort);
+    }
+
+    OpenSSLSocketImpl(Socket socket, String hostname, int port, boolean autoClose)
+        throws IOException {
+        super(socket, hostname, port, autoClose);
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public String getHostname() {
+        return super.getHostname();
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    public void setHostname(String hostname) {
+        super.setHostname(hostname);
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public String getHostnameOrIP() {
+        return super.getHostnameOrIP();
+    }
+
+    @Override
+    public FileDescriptor getFileDescriptor$() {
+        return super.getFileDescriptor$();
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
+        super.setSoWriteTimeout(writeTimeoutMilliseconds);
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public int getSoWriteTimeout() throws SocketException {
+        return super.getSoWriteTimeout();
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
+        super.setHandshakeTimeout(handshakeTimeoutMilliseconds);
+    }
+
+    @Override
+    public abstract SSLSession getHandshakeSession();
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    public abstract void setUseSessionTickets(boolean useSessionTickets);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public abstract void setChannelIdEnabled(boolean enabled);
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    public abstract byte[] getChannelId() throws SSLException;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    public abstract void setChannelIdPrivateKey(PrivateKey privateKey);
+
+    /**
+     * @deprecated NPN is not supported
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    @Deprecated
+    public final byte[] getNpnSelectedProtocol() {
+        return super.getNpnSelectedProtocol();
+    }
+
+    /**
+     * @deprecated NPN is not supported
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    @Deprecated
+    public final void setNpnProtocols(byte[] npnProtocols) {
+        super.setNpnProtocols(npnProtocols);
+    }
+
+    /**
+     * @deprecated use {@link #setApplicationProtocols(String[])} instead.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @Override
+    @Deprecated
+    public final void setAlpnProtocols(String[] alpnProtocols) {
+        setApplicationProtocols(alpnProtocols == null ? EmptyArray.STRING : alpnProtocols);
+    }
+
+    /**
+     * @deprecated use {@link #getApplicationProtocol()} instead.
+     */
+    @dalvik.annotation.
+    compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    @Deprecated
+    public final byte[] getAlpnSelectedProtocol() {
+        return SSLUtils.toProtocolBytes(getApplicationProtocol());
+    }
+
+    /**
+     * @deprecated Use {@link #setAlpnProtocols(String[])} instead.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    @Override
+    @Deprecated
+    public final void setAlpnProtocols(byte[] protocols) {
+        setApplicationProtocols(SSLUtils.decodeProtocols(protocols == null ? EmptyArray.BYTE : protocols));
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CRL.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CRL.java
new file mode 100644
index 0000000..58f831d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CRL.java
@@ -0,0 +1,420 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.Certificate;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TimeZone;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * An implementation of {@link X509CRL} based on BoringSSL.
+ */
+final class OpenSSLX509CRL extends X509CRL {
+    private final long mContext;
+    private final Date thisUpdate;
+    private final Date nextUpdate;
+
+    private OpenSSLX509CRL(long ctx) throws ParsingException {
+        mContext = ctx;
+        // The legacy X509 OpenSSL APIs don't validate ASN1_TIME structures until access, so
+        // parse them here because this is the only time we're allowed to throw ParsingException
+        thisUpdate = toDate(NativeCrypto.X509_CRL_get_lastUpdate(mContext, this));
+        nextUpdate = toDate(NativeCrypto.X509_CRL_get_nextUpdate(mContext, this));
+    }
+
+    // Package-visible because it's also used by OpenSSLX509CRLEntry
+    static Date toDate(long asn1time) throws ParsingException {
+        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+        calendar.set(Calendar.MILLISECOND, 0);
+        NativeCrypto.ASN1_TIME_to_Calendar(asn1time, calendar);
+        return calendar.getTime();
+    }
+
+    static OpenSSLX509CRL fromX509DerInputStream(InputStream is) throws ParsingException {
+        final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        try {
+            final long crlCtx = NativeCrypto.d2i_X509_CRL_bio(bis.getBioContext());
+            if (crlCtx == 0) {
+                return null;
+            }
+            return new OpenSSLX509CRL(crlCtx);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+    }
+
+    static List<OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
+            throws ParsingException {
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        final long[] certRefs;
+        try {
+            certRefs = NativeCrypto.d2i_PKCS7_bio(bis.getBioContext(), NativeCrypto.PKCS7_CRLS);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+
+        final List<OpenSSLX509CRL> certs = new ArrayList<OpenSSLX509CRL>(certRefs.length);
+        for (int i = 0; i < certRefs.length; i++) {
+            if (certRefs[i] == 0) {
+                continue;
+            }
+            certs.add(new OpenSSLX509CRL(certRefs[i]));
+        }
+        return certs;
+    }
+
+    static OpenSSLX509CRL fromX509PemInputStream(InputStream is) throws ParsingException {
+        final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        try {
+            final long crlCtx = NativeCrypto.PEM_read_bio_X509_CRL(bis.getBioContext());
+            if (crlCtx == 0) {
+                return null;
+            }
+            return new OpenSSLX509CRL(crlCtx);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+    }
+
+    static List<OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
+            throws ParsingException {
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        final long[] certRefs;
+        try {
+            certRefs = NativeCrypto.PEM_read_bio_PKCS7(bis.getBioContext(),
+                    NativeCrypto.PKCS7_CRLS);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+
+        final List<OpenSSLX509CRL> certs = new ArrayList<OpenSSLX509CRL>(certRefs.length);
+        for (int i = 0; i < certRefs.length; i++) {
+            if (certRefs[i] == 0) {
+                continue;
+            }
+            certs.add(new OpenSSLX509CRL(certRefs[i]));
+        }
+        return certs;
+    }
+
+    @Override
+    public Set<String> getCriticalExtensionOIDs() {
+        String[] critOids =
+                NativeCrypto.get_X509_CRL_ext_oids(mContext, this, NativeCrypto.EXTENSION_TYPE_CRITICAL);
+
+        /*
+         * This API has a special case that if there are no extensions, we
+         * should return null. So if we have no critical extensions, we'll check
+         * non-critical extensions.
+         */
+        if ((critOids.length == 0)
+                && (NativeCrypto.get_X509_CRL_ext_oids(mContext, this,
+                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
+            return null;
+        }
+
+        return new HashSet<String>(Arrays.asList(critOids));
+    }
+
+    @Override
+    public byte[] getExtensionValue(String oid) {
+        return NativeCrypto.X509_CRL_get_ext_oid(mContext, this, oid);
+    }
+
+    @Override
+    public Set<String> getNonCriticalExtensionOIDs() {
+        String[] nonCritOids =
+                NativeCrypto.get_X509_CRL_ext_oids(mContext, this,
+                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
+
+        /*
+         * This API has a special case that if there are no extensions, we
+         * should return null. So if we have no non-critical extensions, we'll
+         * check critical extensions.
+         */
+        if ((nonCritOids.length == 0)
+                && (NativeCrypto.get_X509_CRL_ext_oids(mContext, this,
+                        NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
+            return null;
+        }
+
+        return new HashSet<String>(Arrays.asList(nonCritOids));
+    }
+
+    @Override
+    public boolean hasUnsupportedCriticalExtension() {
+        final String[] criticalOids =
+                NativeCrypto.get_X509_CRL_ext_oids(mContext, this, NativeCrypto.EXTENSION_TYPE_CRITICAL);
+        for (String oid : criticalOids) {
+            final long extensionRef = NativeCrypto.X509_CRL_get_ext(mContext, this, oid);
+            if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public byte[] getEncoded() throws CRLException {
+        return NativeCrypto.i2d_X509_CRL(mContext, this);
+    }
+
+    private void verifyOpenSSL(OpenSSLKey pkey) throws CRLException, NoSuchAlgorithmException,
+            InvalidKeyException, NoSuchProviderException, SignatureException {
+        NativeCrypto.X509_CRL_verify(mContext, this, pkey.getNativeRef());
+    }
+
+    private void verifyInternal(PublicKey key, String sigProvider) throws CRLException,
+            NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
+            SignatureException {
+        String sigAlg = getSigAlgName();
+        if (sigAlg == null) {
+            sigAlg = getSigAlgOID();
+        }
+
+        final Signature sig;
+        if (sigProvider == null) {
+            sig = Signature.getInstance(sigAlg);
+        } else {
+            sig = Signature.getInstance(sigAlg, sigProvider);
+        }
+
+        sig.initVerify(key);
+        sig.update(getTBSCertList());
+        if (!sig.verify(getSignature())) {
+            throw new SignatureException("signature did not verify");
+        }
+    }
+
+    @Override
+    public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException,
+            InvalidKeyException, NoSuchProviderException, SignatureException {
+        if (key instanceof OpenSSLKeyHolder) {
+            OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
+            verifyOpenSSL(pkey);
+            return;
+        }
+
+        verifyInternal(key, null);
+    }
+
+    @Override
+    public void verify(PublicKey key, String sigProvider) throws CRLException,
+            NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
+            SignatureException {
+        verifyInternal(key, sigProvider);
+    }
+
+    @Override
+    public int getVersion() {
+        return (int) NativeCrypto.X509_CRL_get_version(mContext, this) + 1;
+    }
+
+    @Override
+    public Principal getIssuerDN() {
+        return getIssuerX500Principal();
+    }
+
+    @Override
+    public X500Principal getIssuerX500Principal() {
+        final byte[] issuer = NativeCrypto.X509_CRL_get_issuer_name(mContext, this);
+        return new X500Principal(issuer);
+    }
+
+    @Override
+    public Date getThisUpdate() {
+        return (Date) thisUpdate.clone();
+    }
+
+    @Override
+    public Date getNextUpdate() {
+        return (Date) nextUpdate.clone();
+    }
+
+    @Override
+    public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
+        final long revokedRef = NativeCrypto.X509_CRL_get0_by_serial(mContext, this,
+                serialNumber.toByteArray());
+        if (revokedRef == 0) {
+            return null;
+        }
+        try {
+            return new OpenSSLX509CRLEntry(NativeCrypto.X509_REVOKED_dup(revokedRef));
+        } catch (ParsingException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
+        if (certificate instanceof OpenSSLX509Certificate) {
+            OpenSSLX509Certificate osslCert = (OpenSSLX509Certificate) certificate;
+            final long x509RevokedRef = NativeCrypto.X509_CRL_get0_by_cert(mContext, this,
+                    osslCert.getContext(), osslCert);
+
+            if (x509RevokedRef == 0) {
+                return null;
+            }
+
+            try {
+                return new OpenSSLX509CRLEntry(NativeCrypto.X509_REVOKED_dup(x509RevokedRef));
+            } catch (ParsingException e) {
+                return null;
+            }
+        }
+
+        return getRevokedCertificate(certificate.getSerialNumber());
+    }
+
+    @Override
+    public Set<? extends X509CRLEntry> getRevokedCertificates() {
+        final long[] entryRefs = NativeCrypto.X509_CRL_get_REVOKED(mContext, this);
+        if (entryRefs == null || entryRefs.length == 0) {
+            return null;
+        }
+
+        final Set<OpenSSLX509CRLEntry> crlSet = new HashSet<OpenSSLX509CRLEntry>();
+        for (long entryRef : entryRefs) {
+            try {
+                crlSet.add(new OpenSSLX509CRLEntry(entryRef));
+            } catch (ParsingException e) {
+                // Skip this entry
+            }
+        }
+
+        return crlSet;
+    }
+
+    @Override
+    public byte[] getTBSCertList() throws CRLException {
+        return NativeCrypto.get_X509_CRL_crl_enc(mContext, this);
+    }
+
+    @Override
+    public byte[] getSignature() {
+        return NativeCrypto.get_X509_CRL_signature(mContext, this);
+    }
+
+    @Override
+    public String getSigAlgName() {
+        String oid = getSigAlgOID();
+        String algName = OidData.oidToAlgorithmName(oid);
+        if (algName != null) {
+            return algName;
+        }
+        algName = Platform.oidToAlgorithmName(oid);
+        if (algName != null) {
+            return algName;
+        }
+        return oid;
+    }
+
+    @Override
+    public String getSigAlgOID() {
+        return NativeCrypto.get_X509_CRL_sig_alg_oid(mContext, this);
+    }
+
+    @Override
+    public byte[] getSigAlgParams() {
+        return NativeCrypto.get_X509_CRL_sig_alg_parameter(mContext, this);
+    }
+
+    @Override
+    public boolean isRevoked(Certificate cert) {
+        if (!(cert instanceof X509Certificate)) {
+            return false;
+        }
+
+        final OpenSSLX509Certificate osslCert;
+        if (cert instanceof OpenSSLX509Certificate) {
+            osslCert = (OpenSSLX509Certificate) cert;
+        } else {
+            try {
+                osslCert = OpenSSLX509Certificate.fromX509DerInputStream(new ByteArrayInputStream(
+                        cert.getEncoded()));
+            } catch (Exception e) {
+                throw new RuntimeException("cannot convert certificate", e);
+            }
+        }
+
+        final long x509RevokedRef = NativeCrypto.X509_CRL_get0_by_cert(mContext, this,
+                osslCert.getContext(), osslCert);
+
+        return x509RevokedRef != 0;
+    }
+
+    @Override
+    public String toString() {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        final long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
+        try {
+            NativeCrypto.X509_CRL_print(bioCtx, mContext, this);
+            return os.toString();
+        } finally {
+            NativeCrypto.BIO_free_all(bioCtx);
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mContext != 0) {
+                NativeCrypto.X509_CRL_free(mContext, this);
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CRLEntry.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CRLEntry.java
new file mode 100644
index 0000000..d8c5d9e
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CRLEntry.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayOutputStream;
+import java.math.BigInteger;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRLEntry;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * An implementation of {@link X509CRLEntry} based on BoringSSL.
+ */
+final class OpenSSLX509CRLEntry extends X509CRLEntry {
+    private final long mContext;
+    private final Date revocationDate;
+
+    OpenSSLX509CRLEntry(long ctx) throws ParsingException {
+        mContext = ctx;
+        // The legacy X509 OpenSSL APIs don't validate ASN1_TIME structures until access, so
+        // parse them here because this is the only time we're allowed to throw ParsingException
+        revocationDate = OpenSSLX509CRL.toDate(NativeCrypto.get_X509_REVOKED_revocationDate(mContext));
+    }
+
+    @Override
+    public Set<String> getCriticalExtensionOIDs() {
+        String[] critOids =
+                NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                        NativeCrypto.EXTENSION_TYPE_CRITICAL);
+
+        /*
+         * This API has a special case that if there are no extensions, we
+         * should return null. So if we have no critical extensions, we'll check
+         * non-critical extensions.
+         */
+        if ((critOids.length == 0)
+                && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
+            return null;
+        }
+
+        return new HashSet<String>(Arrays.asList(critOids));
+    }
+
+    @Override
+    public byte[] getExtensionValue(String oid) {
+        return NativeCrypto.X509_REVOKED_get_ext_oid(mContext, oid);
+    }
+
+    @Override
+    public Set<String> getNonCriticalExtensionOIDs() {
+        String[] critOids =
+                NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
+
+        /*
+         * This API has a special case that if there are no extensions, we
+         * should return null. So if we have no non-critical extensions, we'll
+         * check critical extensions.
+         */
+        if ((critOids.length == 0)
+                && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                        NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
+            return null;
+        }
+
+        return new HashSet<String>(Arrays.asList(critOids));
+    }
+
+    @Override
+    public boolean hasUnsupportedCriticalExtension() {
+        final String[] criticalOids =
+                NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                        NativeCrypto.EXTENSION_TYPE_CRITICAL);
+        for (String oid : criticalOids) {
+            final long extensionRef = NativeCrypto.X509_REVOKED_get_ext(mContext, oid);
+            if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public byte[] getEncoded() throws CRLException {
+        return NativeCrypto.i2d_X509_REVOKED(mContext);
+    }
+
+    @Override
+    public BigInteger getSerialNumber() {
+        return new BigInteger(NativeCrypto.X509_REVOKED_get_serialNumber(mContext));
+    }
+
+    @Override
+    public Date getRevocationDate() {
+        return (Date) revocationDate.clone();
+    }
+
+    @Override
+    public boolean hasExtensions() {
+        return (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length != 0)
+                || (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
+                        NativeCrypto.EXTENSION_TYPE_CRITICAL).length != 0);
+    }
+
+    @Override
+    public String toString() {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
+        try {
+            NativeCrypto.X509_REVOKED_print(bioCtx, mContext);
+            return os.toString();
+        } finally {
+            NativeCrypto.BIO_free_all(bioCtx);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CertPath.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CertPath.java
new file mode 100644
index 0000000..a76c1fc
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CertPath.java
@@ -0,0 +1,263 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * An implementation of {@link CertPath} based on BoringSSL.
+ */
+final class OpenSSLX509CertPath extends CertPath {
+    private static final long serialVersionUID = -3249106005255170761L;
+
+    private static final byte[] PKCS7_MARKER = new byte[] {
+            '-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7'
+    };
+
+    private static final int PUSHBACK_SIZE = 64;
+
+    /**
+     * Supported encoding types for CerthPath. Used by the various APIs that
+     * encode this into bytes such as {@link #getEncoded()}.
+     */
+    private enum Encoding {
+        PKI_PATH("PkiPath"),
+        PKCS7("PKCS7");
+
+        private final String apiName;
+
+        Encoding(String apiName) {
+            this.apiName = apiName;
+        }
+
+        static Encoding findByApiName(String apiName) throws CertificateEncodingException {
+            for (Encoding element : values()) {
+                if (element.apiName.equals(apiName)) {
+                    return element;
+                }
+            }
+
+            return null;
+        }
+    }
+
+    /** Unmodifiable list of encodings for the API. */
+    private static final List<String> ALL_ENCODINGS = Collections.unmodifiableList(Arrays
+            .asList(new String[] {
+                    Encoding.PKI_PATH.apiName,
+                    Encoding.PKCS7.apiName,
+            }));
+
+    private static final Encoding DEFAULT_ENCODING = Encoding.PKI_PATH;
+
+    private final List<? extends X509Certificate> mCertificates;
+
+    static Iterator<String> getEncodingsIterator() {
+        return ALL_ENCODINGS.iterator();
+    }
+
+    OpenSSLX509CertPath(List<? extends X509Certificate> certificates) {
+        super("X.509");
+
+        mCertificates = certificates;
+    }
+
+    @Override
+    public List<? extends Certificate> getCertificates() {
+        return Collections.unmodifiableList(mCertificates);
+    }
+
+    private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException {
+        final OpenSSLX509Certificate[] certs = new OpenSSLX509Certificate[mCertificates.size()];
+        final long[] certRefs = new long[certs.length];
+
+        for (int i = 0, j = certs.length - 1; j >= 0; i++, j--) {
+            final X509Certificate cert = mCertificates.get(i);
+
+            if (cert instanceof OpenSSLX509Certificate) {
+                certs[j] = (OpenSSLX509Certificate) cert;
+            } else {
+                certs[j] = OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
+            }
+
+            certRefs[j] = certs[j].getContext();
+        }
+
+        switch (encoding) {
+            case PKI_PATH:
+                return NativeCrypto.ASN1_seq_pack_X509(certRefs);
+            case PKCS7:
+                return NativeCrypto.i2d_PKCS7(certRefs);
+            default:
+                throw new CertificateEncodingException("Unknown encoding");
+        }
+    }
+
+    @Override
+    public byte[] getEncoded() throws CertificateEncodingException {
+        return getEncoded(DEFAULT_ENCODING);
+    }
+
+    @Override
+    public byte[] getEncoded(String encoding) throws CertificateEncodingException {
+        Encoding enc = Encoding.findByApiName(encoding);
+        if (enc == null) {
+            throw new CertificateEncodingException("Invalid encoding: " + encoding);
+        }
+
+        return getEncoded(enc);
+    }
+
+    @Override
+    public Iterator<String> getEncodings() {
+        return getEncodingsIterator();
+    }
+
+    private static CertPath fromPkiPathEncoding(InputStream inStream) throws CertificateException {
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(inStream, true);
+
+        final boolean markable = inStream.markSupported();
+        if (markable) {
+            inStream.mark(PUSHBACK_SIZE);
+        }
+
+        final long[] certRefs;
+        try {
+            certRefs = NativeCrypto.ASN1_seq_unpack_X509_bio(bis.getBioContext());
+        } catch (Exception e) {
+            if (markable) {
+                try {
+                    inStream.reset();
+                } catch (IOException ignored) {
+                }
+            }
+            throw new CertificateException(e);
+        } finally {
+            bis.release();
+        }
+
+        if (certRefs == null) {
+            return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList());
+        }
+
+        final List<OpenSSLX509Certificate> certs =
+                new ArrayList<OpenSSLX509Certificate>(certRefs.length);
+        for (int i = certRefs.length - 1; i >= 0; i--) {
+            if (certRefs[i] == 0) {
+                continue;
+            }
+            try {
+                certs.add(new OpenSSLX509Certificate(certRefs[i]));
+            } catch (ParsingException e) {
+                throw new CertificateParsingException(e);
+            }
+        }
+
+        return new OpenSSLX509CertPath(certs);
+    }
+
+    private static CertPath fromPkcs7Encoding(InputStream inStream) throws CertificateException {
+        try {
+            if (inStream == null || inStream.available() == 0) {
+                return new OpenSSLX509CertPath(Collections.<X509Certificate> emptyList());
+            }
+        } catch (IOException e) {
+            throw new CertificateException("Problem reading input stream", e);
+        }
+
+        final boolean markable = inStream.markSupported();
+        if (markable) {
+            inStream.mark(PUSHBACK_SIZE);
+        }
+
+        /* Attempt to see if this is a PKCS#7 bag. */
+        final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
+        try {
+            final byte[] buffer = new byte[PKCS7_MARKER.length];
+
+            final int len = pbis.read(buffer);
+            if (len < 0) {
+                /* No need to reset here. The stream was empty or EOF. */
+                throw new ParsingException("inStream is empty");
+            }
+            pbis.unread(buffer, 0, len);
+
+            if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
+                return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7PemInputStream(pbis));
+            }
+
+            return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7DerInputStream(pbis));
+        } catch (Exception e) {
+            if (markable) {
+                try {
+                    inStream.reset();
+                } catch (IOException ignored) {
+                }
+            }
+            throw new CertificateException(e);
+        }
+    }
+
+    private static CertPath fromEncoding(InputStream inStream, Encoding encoding)
+            throws CertificateException {
+        switch (encoding) {
+            case PKI_PATH:
+                return fromPkiPathEncoding(inStream);
+            case PKCS7:
+                return fromPkcs7Encoding(inStream);
+            default:
+                throw new CertificateEncodingException("Unknown encoding");
+        }
+    }
+
+    static CertPath fromEncoding(InputStream inStream, String encoding)
+            throws CertificateException {
+        if (inStream == null) {
+            throw new CertificateException("inStream == null");
+        }
+
+        Encoding enc = Encoding.findByApiName(encoding);
+        if (enc == null) {
+            throw new CertificateException("Invalid encoding: " + encoding);
+        }
+
+        return fromEncoding(inStream, enc);
+    }
+
+    static CertPath fromEncoding(InputStream inStream) throws CertificateException {
+        if (inStream == null) {
+            throw new CertificateException("inStream == null");
+        }
+
+        return fromEncoding(inStream, DEFAULT_ENCODING);
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java
new file mode 100644
index 0000000..e8e7d50
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509Certificate.java
@@ -0,0 +1,594 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TimeZone;
+import javax.crypto.BadPaddingException;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * An implementation of {@link X509Certificate} based on BoringSSL.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class OpenSSLX509Certificate extends X509Certificate {
+    private static final long serialVersionUID = 1992239142393372128L;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private transient final long mContext;
+    private transient Integer mHashCode;
+
+    private final Date notBefore;
+    private final Date notAfter;
+
+    OpenSSLX509Certificate(long ctx) throws ParsingException {
+        mContext = ctx;
+        // The legacy X509 OpenSSL APIs don't validate ASN1_TIME structures until access, so
+        // parse them here because this is the only time we're allowed to throw ParsingException
+        notBefore = toDate(NativeCrypto.X509_get_notBefore(mContext, this));
+        notAfter = toDate(NativeCrypto.X509_get_notAfter(mContext, this));
+    }
+
+    // A non-throwing constructor used when we have already parsed the dates
+    private OpenSSLX509Certificate(long ctx, Date notBefore, Date notAfter) {
+        mContext = ctx;
+        this.notBefore = notBefore;
+        this.notAfter = notAfter;
+    }
+
+    private static Date toDate(long asn1time) throws ParsingException {
+        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+        calendar.set(Calendar.MILLISECOND, 0);
+        NativeCrypto.ASN1_TIME_to_Calendar(asn1time, calendar);
+        return calendar.getTime();
+    }
+
+    public static OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
+            throws ParsingException {
+        @SuppressWarnings("resource")
+        final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        try {
+            final long certCtx = NativeCrypto.d2i_X509_bio(bis.getBioContext());
+            if (certCtx == 0) {
+                return null;
+            }
+            return new OpenSSLX509Certificate(certCtx);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+    }
+
+    public static OpenSSLX509Certificate fromX509Der(byte[] encoded)
+            throws CertificateEncodingException {
+        try {
+            return new OpenSSLX509Certificate(NativeCrypto.d2i_X509(encoded));
+        } catch (ParsingException e) {
+            throw new CertificateEncodingException(e);
+        }
+    }
+
+    public static List<OpenSSLX509Certificate> fromPkcs7DerInputStream(InputStream is)
+            throws ParsingException {
+        @SuppressWarnings("resource")
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        final long[] certRefs;
+        try {
+            certRefs = NativeCrypto.d2i_PKCS7_bio(bis.getBioContext(), NativeCrypto.PKCS7_CERTS);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+
+        if (certRefs == null) {
+            return Collections.emptyList();
+        }
+
+        final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(
+                certRefs.length);
+        for (int i = 0; i < certRefs.length; i++) {
+            if (certRefs[i] == 0) {
+                continue;
+            }
+            certs.add(new OpenSSLX509Certificate(certRefs[i]));
+        }
+        return certs;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    public static OpenSSLX509Certificate fromX509PemInputStream(InputStream is)
+            throws ParsingException {
+        @SuppressWarnings("resource")
+        final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        try {
+            final long certCtx = NativeCrypto.PEM_read_bio_X509(bis.getBioContext());
+            if (certCtx == 0L) {
+                return null;
+            }
+            return new OpenSSLX509Certificate(certCtx);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+    }
+
+    public static List<OpenSSLX509Certificate> fromPkcs7PemInputStream(InputStream is)
+            throws ParsingException {
+        @SuppressWarnings("resource")
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+
+        final long[] certRefs;
+        try {
+            certRefs = NativeCrypto.PEM_read_bio_PKCS7(bis.getBioContext(),
+                    NativeCrypto.PKCS7_CERTS);
+        } catch (Exception e) {
+            throw new ParsingException(e);
+        } finally {
+            bis.release();
+        }
+
+        final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(
+                certRefs.length);
+        for (int i = 0; i < certRefs.length; i++) {
+            if (certRefs[i] == 0) {
+                continue;
+            }
+            certs.add(new OpenSSLX509Certificate(certRefs[i]));
+        }
+        return certs;
+    }
+
+    public static OpenSSLX509Certificate fromCertificate(Certificate cert)
+            throws CertificateEncodingException {
+        if (cert instanceof OpenSSLX509Certificate) {
+            return (OpenSSLX509Certificate) cert;
+        } else if (cert instanceof X509Certificate) {
+            return fromX509Der(cert.getEncoded());
+        } else {
+            throw new CertificateEncodingException("Only X.509 certificates are supported");
+        }
+    }
+
+    @Override
+    public Set<String> getCriticalExtensionOIDs() {
+        String[] critOids =
+                NativeCrypto.get_X509_ext_oids(mContext, this, NativeCrypto.EXTENSION_TYPE_CRITICAL);
+
+        /*
+         * This API has a special case that if there are no extensions, we
+         * should return null. So if we have no critical extensions, we'll check
+         * non-critical extensions.
+         */
+        if ((critOids.length == 0)
+                && (NativeCrypto.get_X509_ext_oids(mContext, this,
+                        NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
+            return null;
+        }
+
+        return new HashSet<String>(Arrays.asList(critOids));
+    }
+
+    @Override
+    public byte[] getExtensionValue(String oid) {
+        return NativeCrypto.X509_get_ext_oid(mContext, this, oid);
+    }
+
+    @Override
+    public Set<String> getNonCriticalExtensionOIDs() {
+        String[] nonCritOids =
+                NativeCrypto.get_X509_ext_oids(mContext, this, NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
+
+        /*
+         * This API has a special case that if there are no extensions, we
+         * should return null. So if we have no non-critical extensions, we'll
+         * check critical extensions.
+         */
+        if ((nonCritOids.length == 0)
+                && (NativeCrypto.get_X509_ext_oids(mContext, this,
+                        NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
+            return null;
+        }
+
+        return new HashSet<String>(Arrays.asList(nonCritOids));
+    }
+
+    @Override
+    public boolean hasUnsupportedCriticalExtension() {
+        return (NativeCrypto.get_X509_ex_flags(mContext, this) & NativeConstants.EXFLAG_CRITICAL) != 0;
+    }
+
+    @Override
+    public void checkValidity() throws CertificateExpiredException,
+            CertificateNotYetValidException {
+        checkValidity(new Date());
+    }
+
+    @Override
+    public void checkValidity(Date date) throws CertificateExpiredException,
+            CertificateNotYetValidException {
+        if (getNotBefore().compareTo(date) > 0) {
+            throw new CertificateNotYetValidException("Certificate not valid until "
+                    + getNotBefore().toString() + " (compared to " + date.toString() + ")");
+        }
+
+        if (getNotAfter().compareTo(date) < 0) {
+            throw new CertificateExpiredException("Certificate expired at "
+                    + getNotAfter().toString() + " (compared to " + date.toString() + ")");
+        }
+    }
+
+    @Override
+    public int getVersion() {
+        return (int) NativeCrypto.X509_get_version(mContext, this) + 1;
+    }
+
+    @Override
+    public BigInteger getSerialNumber() {
+        return new BigInteger(NativeCrypto.X509_get_serialNumber(mContext, this));
+    }
+
+    @Override
+    public Principal getIssuerDN() {
+        return getIssuerX500Principal();
+    }
+
+    @Override
+    public Principal getSubjectDN() {
+        return getSubjectX500Principal();
+    }
+
+    @Override
+    public Date getNotBefore() {
+        return (Date) notBefore.clone();
+    }
+
+    @Override
+    public Date getNotAfter() {
+        return (Date) notAfter.clone();
+    }
+
+    @Override
+    public byte[] getTBSCertificate() throws CertificateEncodingException {
+        return NativeCrypto.get_X509_cert_info_enc(mContext, this);
+    }
+
+    @Override
+    public byte[] getSignature() {
+        return NativeCrypto.get_X509_signature(mContext, this);
+    }
+
+    @Override
+    public String getSigAlgName() {
+        String oid = getSigAlgOID();
+        String algName = OidData.oidToAlgorithmName(oid);
+        if (algName != null) {
+            return algName;
+        }
+        algName = Platform.oidToAlgorithmName(oid);
+        if (algName != null) {
+            return algName;
+        }
+        return oid;
+    }
+
+    @Override
+    public String getSigAlgOID() {
+        return NativeCrypto.get_X509_sig_alg_oid(mContext, this);
+    }
+
+    @Override
+    public byte[] getSigAlgParams() {
+        return NativeCrypto.get_X509_sig_alg_parameter(mContext, this);
+    }
+
+    @Override
+    public boolean[] getIssuerUniqueID() {
+        return NativeCrypto.get_X509_issuerUID(mContext, this);
+    }
+
+    @Override
+    public boolean[] getSubjectUniqueID() {
+        return NativeCrypto.get_X509_subjectUID(mContext, this);
+    }
+
+    @Override
+    public boolean[] getKeyUsage() {
+        final boolean[] kusage = NativeCrypto.get_X509_ex_kusage(mContext, this);
+        if (kusage == null) {
+            return null;
+        }
+
+        if (kusage.length >= 9) {
+            return kusage;
+        }
+
+        final boolean[] resized = new boolean[9];
+        System.arraycopy(kusage, 0, resized, 0, kusage.length);
+        return resized;
+    }
+
+    @Override
+    public int getBasicConstraints() {
+        if ((NativeCrypto.get_X509_ex_flags(mContext, this) & NativeConstants.EXFLAG_CA) == 0) {
+            return -1;
+        }
+
+        final int pathLen = NativeCrypto.get_X509_ex_pathlen(mContext, this);
+        if (pathLen == -1) {
+            return Integer.MAX_VALUE;
+        }
+
+        return pathLen;
+    }
+
+    @Override
+    public byte[] getEncoded() throws CertificateEncodingException {
+        return NativeCrypto.i2d_X509(mContext, this);
+    }
+
+    private void verifyOpenSSL(OpenSSLKey pkey) throws CertificateException,
+                                                       NoSuchAlgorithmException,
+                                                       InvalidKeyException, SignatureException {
+        try {
+            NativeCrypto.X509_verify(mContext, this, pkey.getNativeRef());
+        } catch (RuntimeException e) {
+            throw new CertificateException(e);
+        } catch (BadPaddingException e) {
+            throw new SignatureException();
+        }
+    }
+
+    private void verifyInternal(PublicKey key, String sigProvider) throws CertificateException,
+            NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
+            SignatureException {
+        final Signature sig;
+        if (sigProvider == null) {
+            sig = Signature.getInstance(getSigAlgName());
+        } else {
+            sig = Signature.getInstance(getSigAlgName(), sigProvider);
+        }
+
+        sig.initVerify(key);
+        sig.update(getTBSCertificate());
+        if (!sig.verify(getSignature())) {
+            throw new SignatureException("signature did not verify");
+        }
+    }
+
+    @Override
+    public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
+            InvalidKeyException, NoSuchProviderException, SignatureException {
+        if (key instanceof OpenSSLKeyHolder) {
+            OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
+            verifyOpenSSL(pkey);
+            return;
+        }
+
+        verifyInternal(key, (String) null);
+    }
+
+    @Override
+    public void verify(PublicKey key, String sigProvider) throws CertificateException,
+            NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
+            SignatureException {
+        verifyInternal(key, sigProvider);
+    }
+
+    /* @Override */
+    @SuppressWarnings("MissingOverride")  // For compilation with Java 7.
+    // noinspection Override
+    public void verify(PublicKey key, Provider sigProvider)
+            throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+                   SignatureException {
+        if (key instanceof OpenSSLKeyHolder && sigProvider instanceof OpenSSLProvider) {
+            OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
+            verifyOpenSSL(pkey);
+            return;
+        }
+
+        final Signature sig;
+        if (sigProvider == null) {
+            sig = Signature.getInstance(getSigAlgName());
+        } else {
+            sig = Signature.getInstance(getSigAlgName(), sigProvider);
+        }
+
+        sig.initVerify(key);
+        sig.update(getTBSCertificate());
+        if (!sig.verify(getSignature())) {
+            throw new SignatureException("signature did not verify");
+        }
+    }
+
+    @Override
+    public String toString() {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
+        try {
+            NativeCrypto.X509_print_ex(bioCtx, mContext, this, 0, 0);
+            return os.toString();
+        } finally {
+            NativeCrypto.BIO_free_all(bioCtx);
+        }
+    }
+
+    @Override
+    public PublicKey getPublicKey() {
+        /* First try to generate the key from supported OpenSSL key types. */
+        try {
+            OpenSSLKey pkey = new OpenSSLKey(NativeCrypto.X509_get_pubkey(mContext, this));
+            return pkey.getPublicKey();
+        } catch (NoSuchAlgorithmException ignored) {
+        } catch (InvalidKeyException ignored) {
+        }
+
+        /* Try generating the key using other Java providers. */
+        String oid = NativeCrypto.get_X509_pubkey_oid(mContext, this);
+        byte[] encoded = NativeCrypto.i2d_X509_PUBKEY(mContext, this);
+        try {
+            KeyFactory kf = KeyFactory.getInstance(oid);
+            return kf.generatePublic(new X509EncodedKeySpec(encoded));
+        } catch (NoSuchAlgorithmException ignored) {
+        } catch (InvalidKeySpecException ignored) {
+        }
+
+        /*
+         * We couldn't find anything else, so just return a nearly-unusable
+         * X.509-encoded key.
+         */
+        return new X509PublicKey(oid, encoded);
+    }
+
+    @Override
+    public X500Principal getIssuerX500Principal() {
+        final byte[] issuer = NativeCrypto.X509_get_issuer_name(mContext, this);
+        return new X500Principal(issuer);
+    }
+
+    @Override
+    public X500Principal getSubjectX500Principal() {
+        final byte[] subject = NativeCrypto.X509_get_subject_name(mContext, this);
+        return new X500Principal(subject);
+    }
+
+    @Override
+    public List<String> getExtendedKeyUsage() throws CertificateParsingException {
+        String[] extUsage = NativeCrypto.get_X509_ex_xkusage(mContext, this);
+        if (extUsage == null) {
+            return null;
+        }
+
+        return Arrays.asList(extUsage);
+    }
+
+    private static Collection<List<?>> alternativeNameArrayToList(Object[][] altNameArray) {
+        if (altNameArray == null) {
+            return null;
+        }
+
+        Collection<List<?>> coll = new ArrayList<List<?>>(altNameArray.length);
+        for (int i = 0; i < altNameArray.length; i++) {
+            coll.add(Collections.unmodifiableList(Arrays.asList(altNameArray[i])));
+        }
+
+        return Collections.unmodifiableCollection(coll);
+    }
+
+    @Override
+    public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
+        return alternativeNameArrayToList(NativeCrypto.get_X509_GENERAL_NAME_stack(mContext, this,
+                NativeCrypto.GN_STACK_SUBJECT_ALT_NAME));
+    }
+
+    @Override
+    public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
+        return alternativeNameArrayToList(NativeCrypto.get_X509_GENERAL_NAME_stack(mContext, this,
+                NativeCrypto.GN_STACK_ISSUER_ALT_NAME));
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof OpenSSLX509Certificate) {
+            OpenSSLX509Certificate o = (OpenSSLX509Certificate) other;
+
+            return NativeCrypto.X509_cmp(mContext, this, o.mContext, o) == 0;
+        }
+
+        return super.equals(other);
+    }
+
+    @Override
+    public int hashCode() {
+        if (mHashCode != null) {
+            return mHashCode;
+        }
+        mHashCode = super.hashCode();
+        return mHashCode;
+    }
+
+    /**
+     * Returns the raw pointer to the X509 context for use in JNI calls. The
+     * life cycle of this native pointer is managed by the
+     * {@code OpenSSLX509Certificate} instance and must not be destroyed or
+     * freed by users of this API.
+     */
+    public long getContext() {
+        return mContext;
+    }
+
+    /**
+     * Delete an extension.
+     *
+     * A modified copy of the certificate is returned. The original object
+     * is unchanged.
+     * If the extension is not present, an unmodified copy is returned.
+     */
+    public OpenSSLX509Certificate withDeletedExtension(String oid) {
+        OpenSSLX509Certificate copy = new OpenSSLX509Certificate(NativeCrypto.X509_dup(mContext, this), notBefore, notAfter);
+        NativeCrypto.X509_delete_ext(copy.getContext(), copy, oid);
+        return copy;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mContext != 0) {
+                NativeCrypto.X509_free(mContext, this);
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CertificateFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CertificateFactory.java
new file mode 100644
index 0000000..6097a71
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLX509CertificateFactory.java
@@ -0,0 +1,352 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.security.cert.CRL;
+import java.security.cert.CRLException;
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactorySpi;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An implementation of {@link java.security.cert.CertificateFactory} based on BoringSSL.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class OpenSSLX509CertificateFactory extends CertificateFactorySpi {
+    private static final byte[] PKCS7_MARKER = new byte[] {
+            '-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7'
+    };
+
+    private static final int PUSHBACK_SIZE = 64;
+
+    static class ParsingException extends Exception {
+        private static final long serialVersionUID = 8390802697728301325L;
+
+        ParsingException(String message) {
+            super(message);
+        }
+
+        ParsingException(Exception cause) {
+            super(cause);
+        }
+
+        ParsingException(String message, Exception cause) {
+            super(message, cause);
+        }
+    }
+
+    /**
+     * The code for X509 Certificates and CRL is pretty much the same. We use
+     * this abstract class to share the code between them. This makes it ugly,
+     * but it's already written in this language anyway.
+     */
+    private static abstract class Parser<T> {
+        T generateItem(InputStream inStream) throws ParsingException {
+            if (inStream == null) {
+                throw new ParsingException("inStream == null");
+            }
+
+            final boolean markable = inStream.markSupported();
+            if (markable) {
+                inStream.mark(PKCS7_MARKER.length);
+            }
+
+            final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
+            try {
+                final byte[] buffer = new byte[PKCS7_MARKER.length];
+
+                final int len = pbis.read(buffer);
+                if (len < 0) {
+                    /* No need to reset here. The stream was empty or EOF. */
+                    throw new ParsingException("inStream is empty");
+                }
+                pbis.unread(buffer, 0, len);
+
+                if (buffer[0] == '-') {
+                    if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
+                        List<? extends T> items = fromPkcs7PemInputStream(pbis);
+                        if (items.size() == 0) {
+                            return null;
+                        }
+                        items.get(0);
+                    } else {
+                        return fromX509PemInputStream(pbis);
+                    }
+                }
+
+                /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */
+                if (buffer[4] == 0x06) {
+                    List<? extends T> certs = fromPkcs7DerInputStream(pbis);
+                    if (certs.size() == 0) {
+                        return null;
+                    }
+                    return certs.get(0);
+                } else {
+                    return fromX509DerInputStream(pbis);
+                }
+            } catch (Exception e) {
+                if (markable) {
+                    try {
+                        inStream.reset();
+                    } catch (IOException ignored) {
+                    }
+                }
+                throw new ParsingException(e);
+            }
+        }
+
+        Collection<? extends T> generateItems(InputStream inStream)
+                throws ParsingException {
+            if (inStream == null) {
+                throw new ParsingException("inStream == null");
+            }
+            try {
+                if (inStream.available() == 0) {
+                    return Collections.emptyList();
+                }
+            } catch (IOException e) {
+                throw new ParsingException("Problem reading input stream", e);
+            }
+
+            final boolean markable = inStream.markSupported();
+            if (markable) {
+                inStream.mark(PUSHBACK_SIZE);
+            }
+
+            /* Attempt to see if this is a PKCS#7 bag. */
+            final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
+            try {
+                final byte[] buffer = new byte[PKCS7_MARKER.length];
+
+                final int len = pbis.read(buffer);
+                if (len < 0) {
+                    /* No need to reset here. The stream was empty or EOF. */
+                    throw new ParsingException("inStream is empty");
+                }
+                pbis.unread(buffer, 0, len);
+
+                if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
+                    return fromPkcs7PemInputStream(pbis);
+                }
+
+                /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */
+                if (buffer[4] == 0x06) {
+                    return fromPkcs7DerInputStream(pbis);
+                }
+            } catch (Exception e) {
+                if (markable) {
+                    try {
+                        inStream.reset();
+                    } catch (IOException ignored) {
+                    }
+                }
+                throw new ParsingException(e);
+            }
+
+            /*
+             * It wasn't, so just try to keep grabbing certificates until we
+             * can't anymore.
+             */
+            final List<T> coll = new ArrayList<T>();
+            T c;
+            do {
+                /*
+                 * If this stream supports marking, try to mark here in case
+                 * there is an error during certificate generation.
+                 */
+                if (markable) {
+                    inStream.mark(PUSHBACK_SIZE);
+                }
+
+                try {
+                    c = generateItem(pbis);
+                    coll.add(c);
+                } catch (ParsingException e) {
+                    /*
+                     * If this stream supports marking, attempt to reset it to
+                     * the mark before the failure.
+                     */
+                    if (markable) {
+                        try {
+                            inStream.reset();
+                        } catch (IOException ignored) {
+                        }
+                    }
+
+                    c = null;
+                }
+            } while (c != null);
+
+            return coll;
+        }
+
+        protected abstract T fromX509PemInputStream(InputStream pbis) throws ParsingException;
+
+        protected abstract T fromX509DerInputStream(InputStream pbis) throws ParsingException;
+
+        protected abstract List<? extends T> fromPkcs7PemInputStream(InputStream is)
+                throws ParsingException;
+
+        protected abstract List<? extends T> fromPkcs7DerInputStream(InputStream is)
+                throws ParsingException;
+    }
+
+    private Parser<OpenSSLX509Certificate> certificateParser =
+            new Parser<OpenSSLX509Certificate>() {
+                @Override
+                public OpenSSLX509Certificate fromX509PemInputStream(InputStream is)
+                        throws ParsingException {
+                    return OpenSSLX509Certificate.fromX509PemInputStream(is);
+                }
+
+                @Override
+                public OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
+                        throws ParsingException {
+                    return OpenSSLX509Certificate.fromX509DerInputStream(is);
+                }
+
+                @Override
+                public List<? extends OpenSSLX509Certificate>
+                        fromPkcs7PemInputStream(InputStream is) throws ParsingException {
+                    return OpenSSLX509Certificate.fromPkcs7PemInputStream(is);
+                }
+
+                @Override
+                public List<? extends OpenSSLX509Certificate>
+                        fromPkcs7DerInputStream(InputStream is) throws ParsingException {
+                    return OpenSSLX509Certificate.fromPkcs7DerInputStream(is);
+                }
+            };
+
+    private Parser<OpenSSLX509CRL> crlParser =
+            new Parser<OpenSSLX509CRL>() {
+                @Override
+                public OpenSSLX509CRL fromX509PemInputStream(InputStream is)
+                        throws ParsingException {
+                    return OpenSSLX509CRL.fromX509PemInputStream(is);
+                }
+
+                @Override
+                public OpenSSLX509CRL fromX509DerInputStream(InputStream is)
+                        throws ParsingException {
+                    return OpenSSLX509CRL.fromX509DerInputStream(is);
+                }
+
+                @Override
+                public List<? extends OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
+                        throws ParsingException {
+                    return OpenSSLX509CRL.fromPkcs7PemInputStream(is);
+                }
+
+                @Override
+                public List<? extends OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
+                        throws ParsingException {
+                    return OpenSSLX509CRL.fromPkcs7DerInputStream(is);
+                }
+            };
+
+    @libcore.api.IntraCoreApi
+    public OpenSSLX509CertificateFactory() {}
+
+    @Override
+    public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException {
+        try {
+            return certificateParser.generateItem(inStream);
+        } catch (ParsingException e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    @Override
+    public Collection<? extends Certificate> engineGenerateCertificates(
+            InputStream inStream) throws CertificateException {
+        try {
+            return certificateParser.generateItems(inStream);
+        } catch (ParsingException e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    @Override
+    public CRL engineGenerateCRL(InputStream inStream) throws CRLException {
+        try {
+            return crlParser.generateItem(inStream);
+        } catch (ParsingException e) {
+            throw new CRLException(e);
+        }
+    }
+
+    @Override
+    public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream) throws CRLException {
+        if (inStream == null) {
+            return Collections.emptyList();
+        }
+
+        try {
+            return crlParser.generateItems(inStream);
+        } catch (ParsingException e) {
+            throw new CRLException(e);
+        }
+    }
+
+    @Override
+    public Iterator<String> engineGetCertPathEncodings() {
+        return OpenSSLX509CertPath.getEncodingsIterator();
+    }
+
+    @Override
+    public CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException {
+        return OpenSSLX509CertPath.fromEncoding(inStream);
+    }
+
+    @Override
+    public CertPath engineGenerateCertPath(InputStream inStream, String encoding)
+            throws CertificateException {
+        return OpenSSLX509CertPath.fromEncoding(inStream, encoding);
+    }
+
+    @Override
+    public CertPath engineGenerateCertPath(List<? extends Certificate> certificates)
+            throws CertificateException {
+        final List<X509Certificate> filtered = new ArrayList<X509Certificate>(certificates.size());
+        for (int i = 0; i < certificates.size(); i++) {
+            final Certificate c = certificates.get(i);
+
+            if (!(c instanceof X509Certificate)) {
+                throw new CertificateException("Certificate not X.509 type at index " + i);
+            }
+
+            filtered.add((X509Certificate) c);
+        }
+
+        return new OpenSSLX509CertPath(filtered);
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/PSKKeyManager.java b/repackaged/common/src/main/java/com/android/org/conscrypt/PSKKeyManager.java
new file mode 100644
index 0000000..6bc09ad
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/PSKKeyManager.java
@@ -0,0 +1,177 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import java.net.Socket;
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLEngine;
+
+/**
+ * Provider of key material for pre-shared key (PSK) key exchange used in TLS-PSK cipher suites.
+ *
+ * <h3>Overview of TLS-PSK</h3>
+ *
+ * <p>TLS-PSK is a set of TLS/SSL cipher suites which rely on a symmetric pre-shared key (PSK) to
+ * secure the TLS/SSL connection and mutually authenticate its peers. These cipher suites may be
+ * a more natural fit compared to conventional public key based cipher suites in some scenarios
+ * where communication between peers is bootstrapped via a separate step (for example, a pairing
+ * step) and requires both peers to authenticate each other. In such scenarios a symmetric key (PSK)
+ * can be exchanged during the bootstrapping step, removing the need to generate and exchange public
+ * key pairs and X.509 certificates.</p>
+ *
+ * <p>When a TLS-PSK cipher suite is used, both peers have to use the same key for the TLS/SSL
+ * handshake to succeed. Thus, both peers are implicitly authenticated by a successful handshake.
+ * This removes the need to use a {@code TrustManager} in conjunction with this {@code KeyManager}.
+ * </p>
+ *
+ * <h3>Supporting multiple keys</h3>
+ *
+ * <p>A peer may have multiple keys to choose from. To help choose the right key, during the
+ * handshake the server can provide a <em>PSK identity hint</em> to the client, and the client can
+ * provide a <em>PSK identity</em> to the server. The contents of these two pieces of information
+ * are specific to application-level protocols.</p>
+ *
+ * <p><em>NOTE: Both the PSK identity hint and the PSK identity are transmitted in cleartext.
+ * Moreover, these data are received and processed prior to peer having been authenticated. Thus,
+ * they must not contain or leak key material or other sensitive information, and should be
+ * treated (e.g., parsed) with caution, as untrusted data.</em></p>
+ *
+ * <p>The high-level flow leading to peers choosing a key during TLS/SSL handshake is as follows:
+ * <ol>
+ * <li>Server receives a handshake request from client.
+ * <li>Server replies, optionally providing a PSK identity hint to client.</li>
+ * <li>Client chooses the key.</li>
+ * <li>Client provides a PSK identity of the chosen key to server.</li>
+ * <li>Server chooses the key.</li>
+ * </ol></p>
+ *
+ * <p>In the flow above, either peer can signal that they do not have a suitable key, in which case
+ * the the handshake will be aborted immediately. This may enable a network attacker who does not
+ * know the key to learn which PSK identity hints or PSK identities are supported. If this is a
+ * concern then a randomly generated key should be used in the scenario where no key is available.
+ * This will lead to the handshake aborting later, due to key mismatch -- same as in the scenario
+ * where a key is available -- making it appear to the attacker that all PSK identity hints and PSK
+ * identities are supported.</p>
+ *
+ * <h3>Maximum sizes</h3>
+ *
+ * <p>The maximum supported sizes are as follows:
+ * <ul>
+ * <li>256 bytes for keys (see {@link #MAX_KEY_LENGTH_BYTES}),</li>
+ * <li>128 bytes for PSK identity and PSK identity hint (in modified UTF-8 representation) (see
+ * {@link #MAX_IDENTITY_LENGTH_BYTES} and {@link #MAX_IDENTITY_HINT_LENGTH_BYTES}).</li>
+ * </ul></p>
+ *
+ * <h3>Example</h3>
+ * The following example illustrates how to create an {@code SSLContext} which enables the use of
+ * TLS-PSK in {@code SSLSocket}, {@code SSLServerSocket} and {@code SSLEngine} instances obtained
+ * from it.
+ * <pre> {@code
+ * PSKKeyManager myPskKeyManager = ...;
+ *
+ * SSLContext sslContext = SSLContext.getInstance("TLS");
+ * sslContext.init(
+ *         new KeyManager[] &#123;myPskKeyManager&#125;,
+ *         new TrustManager[0], // No TrustManagers needed for TLS-PSK
+ *         null // Use the default source of entropy
+ *         );
+ *
+ * SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(...);
+ * }</pre>
+ *
+ * @deprecated This abstraction is deprecated because it does not work with TLS 1.3.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Deprecated
+@Internal
+public interface PSKKeyManager extends KeyManager {
+
+    /**
+     * Maximum supported length (in bytes) for PSK identity hint (in modified UTF-8 representation).
+     */
+    int MAX_IDENTITY_HINT_LENGTH_BYTES = 128;
+
+    /** Maximum supported length (in bytes) for PSK identity (in modified UTF-8 representation). */
+    int MAX_IDENTITY_LENGTH_BYTES = 128;
+
+    /** Maximum supported length (in bytes) for PSK key. */
+    int MAX_KEY_LENGTH_BYTES = 256;
+
+    /**
+     * Gets the PSK identity hint to report to the client to help agree on the PSK for the provided
+     * socket.
+     *
+     * @return PSK identity hint to be provided to the client or {@code null} to provide no hint.
+     */
+    String chooseServerKeyIdentityHint(Socket socket);
+
+    /**
+     * Gets the PSK identity hint to report to the client to help agree on the PSK for the provided
+     * engine.
+     *
+     * @return PSK identity hint to be provided to the client or {@code null} to provide no hint.
+     */
+    String chooseServerKeyIdentityHint(SSLEngine engine);
+
+    /**
+     * Gets the PSK identity to report to the server to help agree on the PSK for the provided
+     * socket.
+     *
+     * @param identityHint identity hint provided by the server or {@code null} if none provided.
+     *
+     * @return PSK identity to provide to the server. {@code null} is permitted but will be
+     *         converted into an empty string.
+     */
+    String chooseClientKeyIdentity(String identityHint, Socket socket);
+
+    /**
+     * Gets the PSK identity to report to the server to help agree on the PSK for the provided
+     * engine.
+     *
+     * @param identityHint identity hint provided by the server or {@code null} if none provided.
+     *
+     * @return PSK identity to provide to the server. {@code null} is permitted but will be
+     *         converted into an empty string.
+     */
+    String chooseClientKeyIdentity(String identityHint, SSLEngine engine);
+
+    /**
+     * Gets the PSK to use for the provided socket.
+     *
+     * @param identityHint identity hint provided by the server to help select the key or
+     *        {@code null} if none provided.
+     * @param identity identity provided by the client to help select the key.
+     *
+     * @return key or {@code null} to signal to peer that no suitable key is available and to abort
+     *         the handshake.
+     */
+    SecretKey getKey(String identityHint, String identity, Socket socket);
+
+    /**
+     * Gets the PSK to use for the provided engine.
+     *
+     * @param identityHint identity hint provided by the server to help select the key or
+     *        {@code null} if none provided.
+     * @param identity identity provided by the client to help select the key.
+     *
+     * @return key or {@code null} to signal to peer that no suitable key is available and to abort
+     *         the handshake.
+     */
+    SecretKey getKey(String identityHint, String identity, SSLEngine engine);
+}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/PSSParameters.java b/repackaged/common/src/main/java/com/android/org/conscrypt/PSSParameters.java
new file mode 100644
index 0000000..29ddac7
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/PSSParameters.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2018 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 com.android.org.conscrypt;
+
+import java.io.IOException;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+
+/**
+ * AlgorithmParameters implementation for PSS.  The only supported encoding format is ASN.1
+ * (with X.509 accepted as an alias), as specified in RFC 4055 section 3.1.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.IntraCoreApi
+@Internal
+public class PSSParameters extends AlgorithmParametersSpi {
+
+    private PSSParameterSpec spec = PSSParameterSpec.DEFAULT;
+
+    @libcore.api.IntraCoreApi
+    public PSSParameters() {}
+
+    @Override
+    protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+            throws InvalidParameterSpecException {
+        if (algorithmParameterSpec instanceof PSSParameterSpec) {
+            this.spec = (PSSParameterSpec) algorithmParameterSpec;
+        } else {
+            throw new InvalidParameterSpecException("Only PSSParameterSpec is supported");
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes) throws IOException {
+        long readRef = 0;
+        long seqRef = 0;
+        try {
+            readRef = NativeCrypto.asn1_read_init(bytes);
+            seqRef = NativeCrypto.asn1_read_sequence(readRef);
+            int saltLength = 20;
+            String hash = OAEPParameters.readHash(seqRef);
+            String mgfHash = OAEPParameters.readMgfHash(seqRef);
+            if (NativeCrypto.asn1_read_next_tag_is(seqRef, 2)) {
+                long saltRef = 0;
+                try {
+                    saltRef = NativeCrypto.asn1_read_tagged(seqRef);
+                    saltLength = (int) NativeCrypto.asn1_read_uint64(saltRef);
+                } finally {
+                    NativeCrypto.asn1_read_free(saltRef);
+                }
+            }
+            if (NativeCrypto.asn1_read_next_tag_is(seqRef, 3)) {
+                long trailerField;
+                long trailerRef = 0;
+                try {
+                    trailerRef = NativeCrypto.asn1_read_tagged(seqRef);
+                    trailerField = (int) NativeCrypto.asn1_read_uint64(trailerRef);
+                } finally {
+                    NativeCrypto.asn1_read_free(trailerRef);
+                }
+                // 1 is the only legal value for trailerField
+                if (trailerField != 1) {
+                    throw new IOException("Error reading ASN.1 encoding");
+                }
+            }
+
+            if (!NativeCrypto.asn1_read_is_empty(seqRef)
+                    || !NativeCrypto.asn1_read_is_empty(readRef)) {
+                throw new IOException("Error reading ASN.1 encoding");
+            }
+            this.spec = new PSSParameterSpec(hash, "MGF1", new MGF1ParameterSpec(mgfHash),
+                    saltLength, 1);
+        } finally {
+            NativeCrypto.asn1_read_free(seqRef);
+            NativeCrypto.asn1_read_free(readRef);
+        }
+    }
+
+    @Override
+    protected void engineInit(byte[] bytes, String format) throws IOException {
+        if ((format == null) || format.equals("ASN.1") || format.equals("X.509")) {
+            engineInit(bytes);
+        } else {
+            throw new IOException("Unsupported format: " + format);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> aClass)
+            throws InvalidParameterSpecException {
+        if ((aClass != null) && aClass == PSSParameterSpec.class) {
+            return (T) spec;
+        } else {
+            throw new InvalidParameterSpecException("Unsupported class: " + aClass);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded() throws IOException {
+        long cbbRef = 0;
+        long seqRef = 0;
+        try {
+            cbbRef = NativeCrypto.asn1_write_init();
+            seqRef = NativeCrypto.asn1_write_sequence(cbbRef);
+            OAEPParameters.writeHashAndMgfHash(seqRef, spec.getDigestAlgorithm(),
+                    (MGF1ParameterSpec) spec.getMGFParameters());
+            // Implementations are prohibited from writing the default value for any of the fields
+            if (spec.getSaltLength() != 20) {
+                long tagRef = 0;
+                try {
+                    tagRef = NativeCrypto.asn1_write_tag(seqRef, 2);
+                    NativeCrypto.asn1_write_uint64(tagRef, spec.getSaltLength());
+                } finally {
+                    NativeCrypto.asn1_write_flush(seqRef);
+                    NativeCrypto.asn1_write_free(tagRef);
+                }
+            }
+            // 1 is the only legal value for trailerField and the default, so ignore it
+            return NativeCrypto.asn1_write_finish(cbbRef);
+        } catch (IOException e) {
+            NativeCrypto.asn1_write_cleanup(cbbRef);
+            throw e;
+        } finally {
+            NativeCrypto.asn1_write_free(seqRef);
+            NativeCrypto.asn1_write_free(cbbRef);
+        }
+    }
+
+    @Override
+    protected byte[] engineGetEncoded(String format) throws IOException {
+        if ((format == null) || format.equals("ASN.1") || format.equals("X.509")) {
+            return engineGetEncoded();
+        }
+        throw new IOException("Unsupported format: " + format);
+    }
+
+    @Override
+    protected String engineToString() {
+        return "Conscrypt PSS AlgorithmParameters";
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/PeerInfoProvider.java b/repackaged/common/src/main/java/com/android/org/conscrypt/PeerInfoProvider.java
new file mode 100644
index 0000000..d180425
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/PeerInfoProvider.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+/**
+ * A provider for the peer host and port information.
+ */
+abstract class PeerInfoProvider {
+    private static final PeerInfoProvider NULL_PEER_INFO_PROVIDER = new PeerInfoProvider() {
+        @Override
+        String getHostname() {
+            return null;
+        }
+
+        @Override
+        public String getHostnameOrIP() {
+            return null;
+        }
+
+        @Override
+        public int getPort() {
+            return -1;
+        }
+    };
+
+    /**
+     * Returns the hostname supplied during engine/socket creation. No DNS resolution is
+     * attempted before returning the hostname.
+     */
+    abstract String getHostname();
+
+    /**
+     * This method attempts to create a textual representation of the peer host or IP. Does
+     * not perform a reverse DNS lookup. This is typically used during session creation.
+     */
+    abstract String getHostnameOrIP();
+
+    /**
+     * Gets the port of the peer.
+     */
+    abstract int getPort();
+
+    static PeerInfoProvider nullProvider() {
+        return NULL_PEER_INFO_PROVIDER;
+    }
+
+    static PeerInfoProvider forHostAndPort(final String host, final int port) {
+        return new PeerInfoProvider() {
+            @Override
+            String getHostname() {
+                return host;
+            }
+
+            @Override
+            public String getHostnameOrIP() {
+                return host;
+            }
+
+            @Override
+            public int getPort() {
+                return port;
+            }
+        };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/Preconditions.java b/repackaged/common/src/main/java/com/android/org/conscrypt/Preconditions.java
new file mode 100644
index 0000000..801cc0f
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/Preconditions.java
@@ -0,0 +1,109 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+/**
+ * Static convenience methods that help a method or constructor check whether it was invoked
+ * correctly (that is, whether its <i>preconditions</i> were met).
+ */
+final class Preconditions {
+    private Preconditions() {}
+
+    /**
+     * Ensures that an object reference passed as a parameter to the calling method is not null.
+     *
+     * @param reference an object reference
+     * @param errorMessage the exception message to use if the check fails.
+     * @return the non-null reference that was validated
+     * @throws NullPointerException if {@code reference} is null
+     */
+    static <T> T checkNotNull(T reference, String errorMessage) {
+        if (reference == null) {
+            throw new NullPointerException(errorMessage);
+        }
+        return reference;
+    }
+
+    /**
+     * Ensures the truth of an expression involving one or more parameters to the calling method.
+     *
+     * @param condition to condition to be tested
+     * @param errorMessage the exception message to use if the check fails.
+     * @throws IllegalArgumentException if the condition is {@code false}
+     */
+    static void checkArgument(boolean condition, String errorMessage) {
+        if (!condition) {
+            throw new IllegalArgumentException(errorMessage);
+        }
+    }
+
+    /**
+     * Ensures the truth of an expression involving one or more parameters to the calling method.
+     *
+     * @param condition to condition to be tested
+     * @param errorMessageTemplate the format string to be passed to {@link String#format(String,
+     * Object...)}
+     * @param arg the format argument to be passed to {@link String#format(String, Object...)}
+     * @throws IllegalArgumentException if the condition is {@code false}
+     */
+    static void checkArgument(boolean condition, String errorMessageTemplate, Object arg) {
+        if (!condition) {
+            throw new IllegalArgumentException(String.format(errorMessageTemplate, arg));
+        }
+    }
+
+    /**
+     * Ensures that {@code start} and {@code end} specify a valid <i>positions</i> in an array, list
+     * or string of size {@code size}, and are in order. A position index may range from zero to
+     * {@code size}, inclusive.
+     *
+     * @param start a user-supplied index identifying a starting position in an array, list or string
+     * @param end a user-supplied index identifying a ending position in an array, list or string
+     * @param size the size of that array, list or string
+     * @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size},
+     *     or if {@code end} is less than {@code start}
+     * @throws IllegalArgumentException if {@code size} is negative
+     */
+    static void checkPositionIndexes(int start, int end, int size) {
+        // Carefully optimized for execution by hotspot (explanatory comment above)
+        if (start < 0 || end < start || end > size) {
+            throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
+        }
+    }
+
+    private static String badPositionIndexes(int start, int end, int size) {
+        if (start < 0 || start > size) {
+            return badPositionIndex(start, size, "start index");
+        }
+        if (end < 0 || end > size) {
+            return badPositionIndex(end, size, "end index");
+        }
+        // end < start
+        return String.format("end index (%s) must not be less than start index (%s)", end, start);
+    }
+
+    private static String badPositionIndex(int index, int size, String desc) {
+        if (index < 0) {
+            return String.format("%s (%s) must not be negative", desc, index);
+        } else if (size < 0) {
+            throw new IllegalArgumentException("negative size: " + size);
+        } else { // index > size
+            return String.format("%s (%s) must not be greater than size (%s)", desc, index, size);
+        }
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLClientSessionCache.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLClientSessionCache.java
new file mode 100644
index 0000000..c63861d
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLClientSessionCache.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * A persistent {@link javax.net.ssl.SSLSession} cache used by
+ * {@link javax.net.ssl.SSLSessionContext} to share client-side SSL sessions
+ * across processes. For example, this cache enables applications to
+ * persist and reuse sessions across restarts.
+ *
+ * <p>The {@code SSLSessionContext} implementation converts
+ * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
+ * session data is dependent upon the caller's implementation and is opaque to
+ * the {@code SSLClientSessionCache} implementation.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public interface SSLClientSessionCache {
+    /**
+     * Gets data from a pre-existing session for a given server host and port.
+     *
+     * @param host from {@link javax.net.ssl.SSLSession#getPeerHost()}
+     * @param port from {@link javax.net.ssl.SSLSession#getPeerPort()}
+     * @return the session data or null if none is cached
+     * @throws NullPointerException if host is null
+     */
+    byte[] getSessionData(String host, int port);
+
+    /**
+     * Stores session data for the given session.
+     *
+     * @param session to cache data for
+     * @param sessionData to cache
+     * @throws NullPointerException if session, result of
+     *  {@code session.getPeerHost()} or data is null
+     */
+    void putSessionData(SSLSession session, byte[] sessionData);
+}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLNullSession.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLNullSession.java
new file mode 100644
index 0000000..428b27b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLNullSession.java
@@ -0,0 +1,182 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * This is returned in the place of a {@link SSLSession} when no TLS connection could be negotiated,
+ * but one was requested from a method that can't throw an exception such as {@link
+ * javax.net.ssl.SSLSocket#getSession()} before {@link javax.net.ssl.SSLSocket#startHandshake()} is
+ * called.
+ */
+final class SSLNullSession implements ConscryptSession, Cloneable {
+    static final String INVALID_CIPHER = "SSL_NULL_WITH_NULL_NULL";
+
+    /*
+     * Holds default instances so class preloading doesn't create an instance of
+     * it.
+     */
+    private static class DefaultHolder {
+        static final SSLNullSession NULL_SESSION = new SSLNullSession();
+    }
+
+    private long creationTime;
+    private long lastAccessedTime;
+
+    static ConscryptSession getNullSession() {
+        return DefaultHolder.NULL_SESSION;
+    }
+
+    private SSLNullSession() {
+        creationTime = System.currentTimeMillis();
+        lastAccessedTime = creationTime;
+    }
+
+    @Override
+    public String getRequestedServerName() {
+        return null;
+    }
+
+    @Override
+    public List<byte[]> getStatusResponses() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public byte[] getPeerSignedCertificateTimestamp() {
+        return EmptyArray.BYTE;
+    }
+
+    @Override
+    public int getApplicationBufferSize() {
+        return NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH;
+    }
+
+    @Override
+    public String getCipherSuite() {
+        return INVALID_CIPHER;
+    }
+
+    @Override
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    @Override
+    public byte[] getId() {
+        return EmptyArray.BYTE;
+    }
+
+    @Override
+    public long getLastAccessedTime() {
+        return lastAccessedTime;
+    }
+
+    @Override
+    public Certificate[] getLocalCertificates() {
+        return null;
+    }
+
+    @Override
+    public Principal getLocalPrincipal() {
+        return null;
+    }
+
+    @Override
+    public int getPacketBufferSize() {
+        return NativeConstants.SSL3_RT_MAX_PACKET_SIZE;
+    }
+
+    @Override
+    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
+            throws SSLPeerUnverifiedException {
+        throw new SSLPeerUnverifiedException("No peer certificate");
+    }
+
+    @Override
+    public X509Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+        throw new SSLPeerUnverifiedException("No peer certificate");
+    }
+
+    @Override
+    public String getPeerHost() {
+        return null;
+    }
+
+    @Override
+    public int getPeerPort() {
+        return -1;
+    }
+
+    @Override
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        throw new SSLPeerUnverifiedException("No peer certificate");
+    }
+
+    @Override
+    public String getProtocol() {
+        return "NONE";
+    }
+
+    @Override
+    public SSLSessionContext getSessionContext() {
+        return null;
+    }
+
+    @Override
+    public Object getValue(String name) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public String[] getValueNames() {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public void invalidate() {
+    }
+
+    @Override
+    public boolean isValid() {
+        return false;
+    }
+
+    @Override
+    public void putValue(String name, Object value) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public void removeValue(String name) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
new file mode 100644
index 0000000..ff0e80b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLParametersImpl.java
@@ -0,0 +1,691 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Set;
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * The instances of this class encapsulate all the info
+ * about enabled cipher suites and protocols,
+ * as well as the information about client/server mode of
+ * ssl socket, whether it require/want client authentication or not,
+ * and controls whether new SSL sessions may be established by this
+ * socket or not.
+ */
+final class SSLParametersImpl implements Cloneable {
+
+    // default source of X.509 certificate based authentication keys
+    private static volatile X509KeyManager defaultX509KeyManager;
+    // default source of X.509 certificate based authentication trust decisions
+    private static volatile X509TrustManager defaultX509TrustManager;
+    // default SSL parameters
+    private static volatile SSLParametersImpl defaultParameters;
+
+    // client session context contains the set of reusable
+    // client-side SSL sessions
+    private final ClientSessionContext clientSessionContext;
+    // server session context contains the set of reusable
+    // server-side SSL sessions
+    private final ServerSessionContext serverSessionContext;
+    // source of X.509 certificate based authentication keys or null if not provided
+    private final X509KeyManager x509KeyManager;
+    // source of Pre-Shared Key (PSK) authentication keys or null if not provided.
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    private final PSKKeyManager pskKeyManager;
+    // source of X.509 certificate based authentication trust decisions or null if not provided
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    private final X509TrustManager x509TrustManager;
+
+    // protocols enabled for SSL connection
+    String[] enabledProtocols;
+    // set to indicate when obsolete protocols are filtered
+    boolean isEnabledProtocolsFiltered;
+    // The TLS 1.0-1.2 cipher suites enabled for the SSL connection.  TLS 1.3 cipher suites
+    // cannot be customized, so for simplicity this field never contains any TLS 1.3 suites.
+    String[] enabledCipherSuites;
+
+    // if the peer with this parameters tuned to work in client mode
+    private boolean client_mode = true;
+    // if the peer with this parameters tuned to require client authentication
+    private boolean need_client_auth = false;
+    // if the peer with this parameters tuned to request client authentication
+    private boolean want_client_auth = false;
+    // if the peer with this parameters allowed to cteate new SSL session
+    private boolean enable_session_creation = true;
+    // Endpoint identification algorithm (e.g., HTTPS)
+    private String endpointIdentificationAlgorithm;
+    // Whether to use the local cipher suites order
+    private boolean useCipherSuitesOrder;
+
+    // client-side only, bypasses the property based configuration, used for tests
+    private boolean ctVerificationEnabled;
+
+    // server-side only. SCT and OCSP data to send to clients which request it
+    byte[] sctExtension;
+    byte[] ocspResponse;
+
+    byte[] applicationProtocols = EmptyArray.BYTE;
+    ApplicationProtocolSelectorAdapter applicationProtocolSelector;
+    boolean useSessionTickets;
+    private Boolean useSni;
+
+    /**
+     * Whether the TLS Channel ID extension is enabled. This field is
+     * server-side only.
+     */
+    boolean channelIdEnabled;
+
+    /**
+     * Initializes the parameters. Naturally this constructor is used
+     * in SSLContextImpl.engineInit method which directly passes its
+     * parameters. In other words this constructor holds all
+     * the functionality provided by SSLContext.init method.
+     * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
+     * SecureRandom)} for more information
+     */
+    SSLParametersImpl(KeyManager[] kms, TrustManager[] tms,
+            SecureRandom sr, ClientSessionContext clientSessionContext,
+            ServerSessionContext serverSessionContext, String[] protocols)
+            throws KeyManagementException {
+        this.serverSessionContext = serverSessionContext;
+        this.clientSessionContext = clientSessionContext;
+
+        // initialize key managers
+        if (kms == null) {
+            x509KeyManager = getDefaultX509KeyManager();
+            // There's no default PSK key manager
+            pskKeyManager = null;
+        } else {
+            x509KeyManager = findFirstX509KeyManager(kms);
+            pskKeyManager = findFirstPSKKeyManager(kms);
+        }
+
+        // initialize x509TrustManager
+        if (tms == null) {
+            x509TrustManager = getDefaultX509TrustManager();
+        } else {
+            x509TrustManager = findFirstX509TrustManager(tms);
+        }
+
+        // initialize the list of cipher suites and protocols enabled by default
+        enabledProtocols = NativeCrypto.checkEnabledProtocols(
+                protocols == null ? NativeCrypto.DEFAULT_PROTOCOLS : protocols).clone();
+        boolean x509CipherSuitesNeeded = (x509KeyManager != null) || (x509TrustManager != null);
+        boolean pskCipherSuitesNeeded = pskKeyManager != null;
+        enabledCipherSuites = getDefaultCipherSuites(
+                x509CipherSuitesNeeded, pskCipherSuitesNeeded);
+
+        // We ignore the SecureRandom passed in by the caller. The native code below
+        // directly accesses /dev/urandom, which makes it irrelevant.
+    }
+
+    // Copy constructor for the purposes of changing the final fields
+    private SSLParametersImpl(ClientSessionContext clientSessionContext,
+            ServerSessionContext serverSessionContext, X509KeyManager x509KeyManager,
+            PSKKeyManager pskKeyManager, X509TrustManager x509TrustManager,
+            SSLParametersImpl sslParams) {
+        this.clientSessionContext = clientSessionContext;
+        this.serverSessionContext = serverSessionContext;
+        this.x509KeyManager = x509KeyManager;
+        this.pskKeyManager = pskKeyManager;
+        this.x509TrustManager = x509TrustManager;
+
+        this.enabledProtocols =
+                (sslParams.enabledProtocols == null) ? null : sslParams.enabledProtocols.clone();
+        this.isEnabledProtocolsFiltered = sslParams.isEnabledProtocolsFiltered;
+        this.enabledCipherSuites = (sslParams.enabledCipherSuites == null)
+                ? null
+                : sslParams.enabledCipherSuites.clone();
+        this.client_mode = sslParams.client_mode;
+        this.need_client_auth = sslParams.need_client_auth;
+        this.want_client_auth = sslParams.want_client_auth;
+        this.enable_session_creation = sslParams.enable_session_creation;
+        this.endpointIdentificationAlgorithm = sslParams.endpointIdentificationAlgorithm;
+        this.useCipherSuitesOrder = sslParams.useCipherSuitesOrder;
+        this.ctVerificationEnabled = sslParams.ctVerificationEnabled;
+        this.sctExtension =
+                (sslParams.sctExtension == null) ? null : sslParams.sctExtension.clone();
+        this.ocspResponse =
+                (sslParams.ocspResponse == null) ? null : sslParams.ocspResponse.clone();
+        this.applicationProtocols = (sslParams.applicationProtocols == null)
+                ? null
+                : sslParams.applicationProtocols.clone();
+        this.applicationProtocolSelector = sslParams.applicationProtocolSelector;
+        this.useSessionTickets = sslParams.useSessionTickets;
+        this.useSni = sslParams.useSni;
+        this.channelIdEnabled = sslParams.channelIdEnabled;
+    }
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static SSLParametersImpl getDefault() throws KeyManagementException {
+        SSLParametersImpl result = defaultParameters;
+        if (result == null) {
+            // single-check idiom
+            defaultParameters = result = new SSLParametersImpl(null,
+                                                               null,
+                                                               null,
+                                                               new ClientSessionContext(),
+                                                               new ServerSessionContext(),
+                                                               null);
+        }
+        return (SSLParametersImpl) result.clone();
+    }
+
+    /**
+     * Returns the appropriate session context.
+     */
+    AbstractSessionContext getSessionContext() {
+        return client_mode ? clientSessionContext : serverSessionContext;
+    }
+
+    /**
+     * @return client session context
+     */
+    ClientSessionContext getClientSessionContext() {
+        return clientSessionContext;
+    }
+
+    /**
+     * @return X.509 key manager or {@code null} for none.
+     */
+    X509KeyManager getX509KeyManager() {
+        return x509KeyManager;
+    }
+
+    /**
+     * @return Pre-Shared Key (PSK) key manager or {@code null} for none.
+     */
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    PSKKeyManager getPSKKeyManager() {
+        return pskKeyManager;
+    }
+
+    /**
+     * @return X.509 trust manager or {@code null} for none.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    X509TrustManager getX509TrustManager() {
+        return x509TrustManager;
+    }
+
+    /**
+     * @return the names of enabled cipher suites
+     */
+    String[] getEnabledCipherSuites() {
+        if (Arrays.asList(enabledProtocols).contains(NativeCrypto.SUPPORTED_PROTOCOL_TLSV1_3)) {
+            return SSLUtils.concat(
+                    NativeCrypto.SUPPORTED_TLS_1_3_CIPHER_SUITES, enabledCipherSuites);
+        }
+        return enabledCipherSuites.clone();
+    }
+
+    /**
+     * Sets the enabled cipher suites after filtering through OpenSSL.
+     */
+    void setEnabledCipherSuites(String[] cipherSuites) {
+        // Filter out any TLS 1.3 cipher suites the user may have passed.  Our TLS 1.3 suites
+        // are always enabled, no matter what the user requests, so we only store the 1.0-1.2
+        // suites in enabledCipherSuites.
+        enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(
+                filterFromCipherSuites(cipherSuites,
+                        NativeCrypto.SUPPORTED_TLS_1_3_CIPHER_SUITES_SET));
+    }
+
+    /**
+     * @return the set of enabled protocols
+     */
+    String[] getEnabledProtocols() {
+        return enabledProtocols.clone();
+    }
+
+    /**
+     * Sets the list of available protocols for use in SSL connection.
+     * @throws IllegalArgumentException if {@code protocols == null}
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    void setEnabledProtocols(String[] protocols) {
+        if (protocols == null) {
+            throw new IllegalArgumentException("protocols == null");
+        }
+        String[] filteredProtocols =
+                filterFromProtocols(protocols, NativeCrypto.OBSOLETE_PROTOCOL_SSLV3);
+        isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
+        enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
+    }
+
+    /**
+     * Sets the list of ALPN protocols.
+     *
+     * @param protocols the list of ALPN protocols
+     */
+    void setApplicationProtocols(String[] protocols) {
+        this.applicationProtocols = SSLUtils.encodeProtocols(protocols);
+    }
+
+    String[] getApplicationProtocols() {
+        return SSLUtils.decodeProtocols(applicationProtocols);
+    }
+
+    /**
+     * Used for server-mode only. Sets or clears the application-provided ALPN protocol selector.
+     * If set, will override the protocol list provided by {@link #setApplicationProtocols(String[])}.
+     */
+    void setApplicationProtocolSelector(ApplicationProtocolSelectorAdapter applicationProtocolSelector) {
+        this.applicationProtocolSelector = applicationProtocolSelector;
+    }
+
+    /**
+     * Tunes the peer holding this parameters to work in client mode.
+     * @param   mode if the peer is configured to work in client mode
+     */
+    void setUseClientMode(boolean mode) {
+        client_mode = mode;
+    }
+
+    /**
+     * Returns the value indicating if the parameters configured to work
+     * in client mode.
+     */
+    boolean getUseClientMode() {
+        return client_mode;
+    }
+
+    /**
+     * Tunes the peer holding this parameters to require client authentication
+     */
+    void setNeedClientAuth(boolean need) {
+        need_client_auth = need;
+        // reset the want_client_auth setting
+        want_client_auth = false;
+    }
+
+    /**
+     * Returns the value indicating if the peer with this parameters tuned
+     * to require client authentication
+     */
+    boolean getNeedClientAuth() {
+        return need_client_auth;
+    }
+
+    /**
+     * Tunes the peer holding this parameters to request client authentication
+     */
+    void setWantClientAuth(boolean want) {
+        want_client_auth = want;
+        // reset the need_client_auth setting
+        need_client_auth = false;
+    }
+
+    /**
+     * Returns the value indicating if the peer with this parameters
+     * tuned to request client authentication
+     */
+    boolean getWantClientAuth() {
+        return want_client_auth;
+    }
+
+    /**
+     * Allows/disallows the peer holding this parameters to
+     * create new SSL session
+     */
+    void setEnableSessionCreation(boolean flag) {
+        enable_session_creation = flag;
+    }
+
+    /**
+     * Returns the value indicating if the peer with this parameters
+     * allowed to cteate new SSL session
+     */
+    boolean getEnableSessionCreation() {
+        return enable_session_creation;
+    }
+
+    void setUseSessionTickets(boolean useSessionTickets) {
+        this.useSessionTickets = useSessionTickets;
+    }
+
+    /**
+     * Whether connections using this SSL connection should use the TLS
+     * extension Server Name Indication (SNI).
+     */
+    void setUseSni(boolean flag) {
+        useSni = flag;
+    }
+
+    /**
+     * Returns whether connections using this SSL connection should use the TLS
+     * extension Server Name Indication (SNI).
+     */
+    boolean getUseSni() {
+        return useSni != null ? useSni : isSniEnabledByDefault();
+    }
+
+    /**
+     * For testing only.
+     */
+    void setCTVerificationEnabled(boolean enabled) {
+        ctVerificationEnabled = enabled;
+    }
+
+    /**
+     * For testing only.
+     */
+    void setSCTExtension(byte[] extension) {
+        sctExtension = extension;
+    }
+
+    /**
+     * For testing only.
+     */
+    void setOCSPResponse(byte[] response) {
+        ocspResponse = response;
+    }
+
+    byte[] getOCSPResponse() {
+        return ocspResponse;
+    }
+
+    /**
+     * This filters {@code obsoleteProtocol} from the list of {@code protocols}
+     * down to help with app compatibility.
+     */
+    private static String[] filterFromProtocols(String[] protocols, String obsoleteProtocol) {
+        if (protocols.length == 1 && obsoleteProtocol.equals(protocols[0])) {
+            return EMPTY_STRING_ARRAY;
+        }
+
+        ArrayList<String> newProtocols = new ArrayList<String>();
+        for (String protocol : protocols) {
+            if (!obsoleteProtocol.equals(protocol)) {
+                newProtocols.add(protocol);
+            }
+        }
+        return newProtocols.toArray(EMPTY_STRING_ARRAY);
+    }
+
+    private static String[] filterFromCipherSuites(String[] cipherSuites, Set<String> toRemove) {
+        if (cipherSuites == null || cipherSuites.length == 0) {
+            return cipherSuites;
+        }
+        ArrayList<String> newCipherSuites = new ArrayList<String>(cipherSuites.length);
+        for (String cipherSuite : cipherSuites) {
+            if (!toRemove.contains(cipherSuite)) {
+                newCipherSuites.add(cipherSuite);
+            }
+        }
+        return newCipherSuites.toArray(EMPTY_STRING_ARRAY);
+    }
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    /**
+     * Returns whether Server Name Indication (SNI) is enabled by default for
+     * sockets. For more information on SNI, see RFC 6066 section 3.
+     */
+    private boolean isSniEnabledByDefault() {
+        try {
+            String enableSNI = System.getProperty("jsse.enableSNIExtension", "true");
+            if ("true".equalsIgnoreCase(enableSNI)) {
+                return true;
+            } else if ("false".equalsIgnoreCase(enableSNI)) {
+                return false;
+            } else {
+                throw new RuntimeException(
+                        "Can only set \"jsse.enableSNIExtension\" to \"true\" or \"false\"");
+            }
+        } catch (SecurityException e) {
+            return true;
+        }
+    }
+
+    /**
+     * For abstracting the X509KeyManager calls between
+     * {@link X509KeyManager#chooseClientAlias(String[], java.security.Principal[], java.net.Socket)}
+     * and
+     * {@link X509ExtendedKeyManager#chooseEngineClientAlias(String[], java.security.Principal[], javax.net.ssl.SSLEngine)}
+     */
+    interface AliasChooser {
+        String chooseClientAlias(X509KeyManager keyManager, X500Principal[] issuers,
+                String[] keyTypes);
+
+        String chooseServerAlias(X509KeyManager keyManager, String keyType);
+    }
+
+    /**
+     * For abstracting the {@code PSKKeyManager} calls between those taking an {@code SSLSocket} and
+     * those taking an {@code SSLEngine}.
+     */
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    interface PSKCallbacks {
+        String chooseServerPSKIdentityHint(PSKKeyManager keyManager);
+        String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint);
+        SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity);
+    }
+
+    /**
+     * Returns the clone of this object.
+     * @return the clone.
+     */
+    @Override
+    protected Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    SSLParametersImpl cloneWithTrustManager(X509TrustManager newTrustManager) {
+        return new SSLParametersImpl(clientSessionContext, serverSessionContext, x509KeyManager,
+                pskKeyManager, newTrustManager, this);
+    }
+
+    private static X509KeyManager getDefaultX509KeyManager() throws KeyManagementException {
+        X509KeyManager result = defaultX509KeyManager;
+        if (result == null) {
+            // single-check idiom
+            defaultX509KeyManager = result = createDefaultX509KeyManager();
+        }
+        return result;
+    }
+    private static X509KeyManager createDefaultX509KeyManager() throws KeyManagementException {
+        try {
+            String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
+            kmf.init(null, null);
+            KeyManager[] kms = kmf.getKeyManagers();
+            X509KeyManager result = findFirstX509KeyManager(kms);
+            if (result == null) {
+                throw new KeyManagementException("No X509KeyManager among default KeyManagers: "
+                        + Arrays.toString(kms));
+            }
+            return result;
+        } catch (NoSuchAlgorithmException e) {
+            throw new KeyManagementException(e);
+        } catch (KeyStoreException e) {
+            throw new KeyManagementException(e);
+        } catch (UnrecoverableKeyException e) {
+            throw new KeyManagementException(e);
+        }
+    }
+
+    /**
+     * Finds the first {@link X509KeyManager} element in the provided array.
+     *
+     * @return the first {@code X509KeyManager} or {@code null} if not found.
+     */
+    private static X509KeyManager findFirstX509KeyManager(KeyManager[] kms) {
+        for (KeyManager km : kms) {
+            if (km instanceof X509KeyManager) {
+                return (X509KeyManager)km;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Finds the first {@link PSKKeyManager} element in the provided array.
+     *
+     * @return the first {@code PSKKeyManager} or {@code null} if not found.
+     */
+    @SuppressWarnings("deprecation") // PSKKeyManager is deprecated, but in our own package
+    private static PSKKeyManager findFirstPSKKeyManager(KeyManager[] kms) {
+        for (KeyManager km : kms) {
+            if (km instanceof PSKKeyManager) {
+                return (PSKKeyManager)km;
+            } else if (km != null) {
+                try {
+                    return DuckTypedPSKKeyManager.getInstance(km);
+                } catch (NoSuchMethodException ignored) {}
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the default X.509 trust manager.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    static X509TrustManager getDefaultX509TrustManager()
+            throws KeyManagementException {
+        X509TrustManager result = defaultX509TrustManager;
+        if (result == null) {
+            // single-check idiom
+            defaultX509TrustManager = result = createDefaultX509TrustManager();
+        }
+        return result;
+    }
+
+    private static X509TrustManager createDefaultX509TrustManager()
+            throws KeyManagementException {
+        try {
+            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+            tmf.init((KeyStore) null);
+            TrustManager[] tms = tmf.getTrustManagers();
+            X509TrustManager trustManager = findFirstX509TrustManager(tms);
+            if (trustManager == null) {
+                throw new KeyManagementException(
+                        "No X509TrustManager in among default TrustManagers: "
+                                + Arrays.toString(tms));
+            }
+            return trustManager;
+        } catch (NoSuchAlgorithmException e) {
+            throw new KeyManagementException(e);
+        } catch (KeyStoreException e) {
+            throw new KeyManagementException(e);
+        }
+    }
+
+    /**
+     * Finds the first {@link X509TrustManager} element in the provided array.
+     *
+     * @return the first {@code X509ExtendedTrustManager} or
+     *         {@code X509TrustManager} or {@code null} if not found.
+     */
+    private static X509TrustManager findFirstX509TrustManager(TrustManager[] tms) {
+        for (TrustManager tm : tms) {
+            if (tm instanceof X509TrustManager) {
+                return (X509TrustManager) tm;
+            }
+        }
+        return null;
+    }
+
+    String getEndpointIdentificationAlgorithm() {
+        return endpointIdentificationAlgorithm;
+    }
+
+    void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm) {
+        this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
+    }
+
+    boolean getUseCipherSuitesOrder() {
+        return useCipherSuitesOrder;
+    }
+
+    void setUseCipherSuitesOrder(boolean useCipherSuitesOrder) {
+        this.useCipherSuitesOrder = useCipherSuitesOrder;
+    }
+
+    private static String[] getDefaultCipherSuites(
+            boolean x509CipherSuitesNeeded,
+            boolean pskCipherSuitesNeeded) {
+        if (x509CipherSuitesNeeded) {
+            // X.509 based cipher suites need to be listed.
+            if (pskCipherSuitesNeeded) {
+                // Both X.509 and PSK based cipher suites need to be listed. Because TLS-PSK is not
+                // normally used, we assume that when PSK cipher suites are requested here they
+                // should be preferred over other cipher suites. Thus, we give PSK cipher suites
+                // higher priority than X.509 cipher suites.
+                // NOTE: There are cipher suites that use both X.509 and PSK (e.g., those based on
+                // RSA_PSK key exchange). However, these cipher suites are not currently supported.
+                return SSLUtils.concat(
+                        NativeCrypto.DEFAULT_PSK_CIPHER_SUITES,
+                        NativeCrypto.DEFAULT_X509_CIPHER_SUITES,
+                        new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV});
+            } else {
+                // Only X.509 cipher suites need to be listed.
+                return SSLUtils.concat(
+                        NativeCrypto.DEFAULT_X509_CIPHER_SUITES,
+                        new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV});
+            }
+        } else if (pskCipherSuitesNeeded) {
+            // Only PSK cipher suites need to be listed.
+            return SSLUtils.concat(
+                    NativeCrypto.DEFAULT_PSK_CIPHER_SUITES,
+                    new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV});
+        } else {
+            // Neither X.509 nor PSK cipher suites need to be listed.
+            return new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV};
+        }
+    }
+
+    /**
+     * Check if SCT verification is enforced for a given hostname.
+     */
+    boolean isCTVerificationEnabled(String hostname) {
+        if (hostname == null) {
+            return false;
+        }
+
+        // Bypass the check. This is used for testing only
+        if (ctVerificationEnabled) {
+            return true;
+        }
+        return Platform.isCTVerificationRequired(hostname);
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLServerSessionCache.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLServerSessionCache.java
new file mode 100644
index 0000000..8200fe8
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLServerSessionCache.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * A persistent {@link javax.net.ssl.SSLSession} cache used by
+ * {@link javax.net.ssl.SSLSessionContext} to share server-side SSL sessions
+ * across processes. For example, this cache enables one server to resume
+ * a session started by a different server based on a session ID provided
+ * by the client.
+ *
+ * <p>The {@code SSLSessionContext} implementation converts
+ * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
+ * session data is dependent upon the caller's implementation and is opaque to
+ * the {@code SSLServerSessionCache} implementation.
+ */
+interface SSLServerSessionCache {
+    /**
+     * Gets the session data for given session ID.
+     *
+     * @param id from {@link javax.net.ssl.SSLSession#getId()}
+     * @return the session data or null if none is cached
+     * @throws NullPointerException if id is null
+     */
+    byte[] getSessionData(byte[] id);
+
+    /**
+     * Stores session data for the given session.
+     *
+     * @param session to cache data for
+     * @param sessionData to cache
+     * @throws NullPointerException if session or data is null
+     */
+    void putSessionData(SSLSession session, byte[] sessionData);
+}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SSLUtils.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLUtils.java
new file mode 100644
index 0000000..f3226e6
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SSLUtils.java
@@ -0,0 +1,582 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/*
+ * Copyright 2016 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import static java.lang.Math.min;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_ALERT;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_APPLICATION_DATA;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_CHANGE_CIPHER_SPEC;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_HANDSHAKE;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_HEADER_LENGTH;
+import static com.android.org.conscrypt.NativeConstants.SSL3_RT_MAX_PACKET_SIZE;
+
+import java.io.ByteArrayInputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.security.cert.CertificateException;
+
+/**
+ * Utility methods for SSL packet processing. Copied from the Netty project.
+ * <p>
+ * This is a public class to allow testing to occur on Android via CTS.
+ */
+final class SSLUtils {
+    static final boolean USE_ENGINE_SOCKET_BY_DEFAULT = Boolean.parseBoolean(
+            System.getProperty("com.android.org.conscrypt.useEngineSocketByDefault", "false"));
+    private static final int MAX_PROTOCOL_LENGTH = 255;
+
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+    // TODO(nathanmittler): Should these be in NativeConstants?
+    enum SessionType {
+        /**
+         * Identifies OpenSSL sessions.
+         */
+        OPEN_SSL(1),
+
+        /**
+         * Identifies OpenSSL sessions with OCSP stapled data.
+         */
+        OPEN_SSL_WITH_OCSP(2),
+
+        /**
+         * Identifies OpenSSL sessions with TLS SCT data.
+         */
+        OPEN_SSL_WITH_TLS_SCT(3);
+
+        SessionType(int value) {
+            this.value = value;
+        }
+
+        static boolean isSupportedType(int type) {
+            return type == OPEN_SSL.value || type == OPEN_SSL_WITH_OCSP.value
+                    || type == OPEN_SSL_WITH_TLS_SCT.value;
+        }
+
+        final int value;
+    }
+
+    /**
+     * States for SSL engines.
+     */
+    static final class EngineStates {
+        private EngineStates() {}
+
+        /**
+         * The engine is constructed, but the initial handshake hasn't been started
+         */
+        static final int STATE_NEW = 0;
+
+        /**
+         * The client/server mode of the engine has been set.
+         */
+        static final int STATE_MODE_SET = 1;
+
+        /**
+         * The handshake has been started
+         */
+        static final int STATE_HANDSHAKE_STARTED = 2;
+
+        /**
+         * Listeners of the handshake have been notified of completion but the handshake call
+         * hasn't returned.
+         */
+        static final int STATE_HANDSHAKE_COMPLETED = 3;
+
+        /**
+         * The handshake call returned but the listeners have not yet been notified. This is expected
+         * behaviour in cut-through mode, where SSL_do_handshake returns before the handshake is
+         * complete. We can now start writing data to the socket.
+         */
+        static final int STATE_READY_HANDSHAKE_CUT_THROUGH = 4;
+
+        /**
+         * The handshake call has returned and the listeners have been notified. Ready to begin
+         * writing data.
+         */
+        static final int STATE_READY = 5;
+
+        /**
+         * The inbound direction of the engine has been closed.
+         */
+        static final int STATE_CLOSED_INBOUND = 6;
+
+        /**
+         * The outbound direction of the engine has been closed.
+         */
+        static final int STATE_CLOSED_OUTBOUND = 7;
+
+        /**
+         * The engine has been closed.
+         */
+        static final int STATE_CLOSED = 8;
+    }
+
+    /**
+     * This is the maximum overhead when encrypting plaintext as defined by
+     * <a href="https://www.ietf.org/rfc/rfc5246.txt">rfc5264</a>,
+     * <a href="https://www.ietf.org/rfc/rfc5289.txt">rfc5289</a>, and the BoringSSL
+     * implementation itself.
+     *
+     * Please note that we use a padding of 16 here as BoringSSL uses PKCS#5 which uses 16 bytes
+     * while the spec itself allow up to 255 bytes. 16 bytes is the max for PKCS#5 (which handles it
+     * the same way as PKCS#7) as we use a block size of 16. See <a
+     * href="https://tools.ietf.org/html/rfc5652#section-6.3">rfc5652#section-6.3</a>.
+     *
+     * 16 (IV) + 48 (MAC) + 1 (Padding_length field) + 15 (Padding)
+     * + 1 (ContentType in TLSCiphertext) + 2 (ProtocolVersion) + 2 (Length)
+     * + 1 (ContentType in TLSInnerPlaintext)
+     */
+    private static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = 15 + 48 + 1 + 16 + 1 + 2 + 2 + 1;
+
+    private static final int MAX_ENCRYPTION_OVERHEAD_DIFF =
+            Integer.MAX_VALUE - MAX_ENCRYPTION_OVERHEAD_LENGTH;
+
+    /** Key type: RSA certificate. */
+    private static final String KEY_TYPE_RSA = "RSA";
+
+    /** Key type: Elliptic Curve certificate. */
+    private static final String KEY_TYPE_EC = "EC";
+
+    static X509Certificate[] decodeX509CertificateChain(byte[][] certChain)
+            throws java.security.cert.CertificateException {
+        CertificateFactory certificateFactory = getCertificateFactory();
+        int numCerts = certChain.length;
+        X509Certificate[] decodedCerts = new X509Certificate[numCerts];
+        for (int i = 0; i < numCerts; i++) {
+            decodedCerts[i] = decodeX509Certificate(certificateFactory, certChain[i]);
+        }
+        return decodedCerts;
+    }
+
+    private static CertificateFactory getCertificateFactory() {
+        try {
+            return CertificateFactory.getInstance("X.509");
+        } catch (java.security.cert.CertificateException e) {
+            return null;
+        }
+    }
+
+    private static X509Certificate decodeX509Certificate(CertificateFactory certificateFactory,
+            byte[] bytes) throws java.security.cert.CertificateException {
+        if (certificateFactory != null) {
+            return (X509Certificate) certificateFactory.generateCertificate(
+                    new ByteArrayInputStream(bytes));
+        }
+        return OpenSSLX509Certificate.fromX509Der(bytes);
+    }
+
+    /**
+     * Returns key type constant suitable for calling X509KeyManager.chooseServerAlias or
+     * X509ExtendedKeyManager.chooseEngineServerAlias. Returns {@code null} for key exchanges that
+     * do not use X.509 for server authentication.
+     */
+    static String getServerX509KeyType(long sslCipherNative) throws SSLException {
+        String kx_name = NativeCrypto.SSL_CIPHER_get_kx_name(sslCipherNative);
+        if (kx_name.equals("RSA") || kx_name.equals("DHE_RSA") || kx_name.equals("ECDHE_RSA")) {
+            return KEY_TYPE_RSA;
+        } else if (kx_name.equals("ECDHE_ECDSA")) {
+            return KEY_TYPE_EC;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Similar to getServerKeyType, but returns value given TLS
+     * ClientCertificateType byte values from a CertificateRequest
+     * message for use with X509KeyManager.chooseClientAlias or
+     * X509ExtendedKeyManager.chooseEngineClientAlias.
+     * <p>
+     * Visible for testing.
+     */
+    static String getClientKeyType(byte clientCertificateType) {
+        // See also
+        // https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-2
+        switch (clientCertificateType) {
+            case NativeConstants.TLS_CT_RSA_SIGN:
+                return KEY_TYPE_RSA; // RFC rsa_sign
+            case NativeConstants.TLS_CT_ECDSA_SIGN:
+                return KEY_TYPE_EC; // RFC ecdsa_sign
+            default:
+                return null;
+        }
+    }
+
+    static String getClientKeyTypeFromSignatureAlg(int signatureAlg) {
+        // See also
+        // https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml#tls-signaturescheme
+        switch (NativeCrypto.SSL_get_signature_algorithm_key_type(signatureAlg)) {
+            case NativeConstants.EVP_PKEY_RSA:
+                return KEY_TYPE_RSA;
+            case NativeConstants.EVP_PKEY_EC:
+                return KEY_TYPE_EC;
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Gets the supported key types for client certificates based on the
+     * {@code ClientCertificateType} values provided by the server.
+     *
+     * @param clientCertificateTypes
+     *         {@code ClientCertificateType} values provided by the server.
+     *         See https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-2.
+     * @param signatureAlgs
+     *         {@code SignatureScheme} values provided by the server.
+     *         See https://www.ietf.org/assignments/tls-parameters/tls-parameters.xml#tls-signaturescheme
+     * @return supported key types that can be used in {@code X509KeyManager.chooseClientAlias} and
+     * {@code X509ExtendedKeyManager.chooseEngineClientAlias}.  If the inputs imply a preference
+     * order, the returned set will have an iteration order that respects that preference order,
+     * otherwise it will be in an arbitrary order.
+     *
+     * Visible for testing.
+     */
+    static Set<String> getSupportedClientKeyTypes(byte[] clientCertificateTypes,
+            int[] signatureAlgs) {
+        Set<String> fromClientCerts = new HashSet<String>(clientCertificateTypes.length);
+        for (byte keyTypeCode : clientCertificateTypes) {
+            String keyType = SSLUtils.getClientKeyType(keyTypeCode);
+            if (keyType == null) {
+                // Unsupported client key type -- ignore
+                continue;
+            }
+            fromClientCerts.add(keyType);
+        }
+        // Signature algorithms are listed in preference order
+        Set<String> fromSigAlgs = new LinkedHashSet<String>(signatureAlgs.length);
+        for (int signatureAlg : signatureAlgs) {
+            String keyType = SSLUtils.getClientKeyTypeFromSignatureAlg(signatureAlg);
+            if (keyType == null) {
+                // Unsupported client key type -- ignore
+                continue;
+            }
+            fromSigAlgs.add(keyType);
+        }
+        // If both are specified, the key needs to meet both sets of requirements.  Otherwise,
+        // just meet the set of requirements that were specified.  See RFC 5246, section 7.4.4.
+        // (In TLS 1.3, certificate_types is no longer used and is never present.)
+        if (clientCertificateTypes.length > 0 && signatureAlgs.length > 0) {
+            fromSigAlgs.retainAll(fromClientCerts);
+            return fromSigAlgs;
+        } else if (signatureAlgs.length > 0) {
+            return fromSigAlgs;
+        } else {
+            return fromClientCerts;
+        }
+    }
+
+    static byte[][] encodeSubjectX509Principals(X509Certificate[] certificates)
+            throws CertificateEncodingException {
+        byte[][] principalBytes = new byte[certificates.length][];
+        for (int i = 0; i < certificates.length; i++) {
+            principalBytes[i] = certificates[i].getSubjectX500Principal().getEncoded();
+        }
+        return principalBytes;
+    }
+
+    /**
+     * Converts the peer certificates into a cert chain.
+     */
+    static javax.security.cert.X509Certificate[] toCertificateChain(X509Certificate[] certificates)
+            throws SSLPeerUnverifiedException {
+        try {
+            javax.security.cert.X509Certificate[] chain =
+                    new javax.security.cert.X509Certificate[certificates.length];
+
+            for (int i = 0; i < certificates.length; i++) {
+                byte[] encoded = certificates[i].getEncoded();
+                chain[i] = javax.security.cert.X509Certificate.getInstance(encoded);
+            }
+            return chain;
+        } catch (CertificateEncodingException e) {
+            SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
+            exception.initCause(exception);
+            throw exception;
+        } catch (CertificateException e) {
+            SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
+            exception.initCause(exception);
+            throw exception;
+        }
+    }
+
+    /**
+     * Calculates the minimum bytes required in the encrypted output buffer for the given number of
+     * plaintext source bytes.
+     */
+    static int calculateOutNetBufSize(int pendingBytes) {
+        return min(SSL3_RT_MAX_PACKET_SIZE,
+                MAX_ENCRYPTION_OVERHEAD_LENGTH + min(MAX_ENCRYPTION_OVERHEAD_DIFF, pendingBytes));
+    }
+
+    /**
+     * Wraps the given exception if it's not already a {@link SSLHandshakeException}.
+     */
+    static SSLHandshakeException toSSLHandshakeException(Throwable e) {
+        if (e instanceof SSLHandshakeException) {
+            return (SSLHandshakeException) e;
+        }
+
+        return (SSLHandshakeException) new SSLHandshakeException(e.getMessage()).initCause(e);
+    }
+
+    /**
+     * Wraps the given exception if it's not already a {@link SSLException}.
+     */
+    static SSLException toSSLException(Throwable e) {
+        if (e instanceof SSLException) {
+            return (SSLException) e;
+        }
+        return new SSLException(e);
+    }
+
+    static String toProtocolString(byte[] bytes) {
+        if (bytes == null) {
+            return null;
+        }
+        return new String(bytes, US_ASCII);
+    }
+
+    static byte[] toProtocolBytes(String protocol) {
+        if (protocol == null) {
+            return null;
+        }
+        return protocol.getBytes(US_ASCII);
+    }
+
+    /**
+     * Decodes the given list of protocols into {@link String}s.
+     * @param protocols the encoded protocol list
+     * @return the decoded protocols or {@link EmptyArray#BYTE} if {@code protocols} is
+     * empty.
+     * @throws NullPointerException if protocols is {@code null}.
+     */
+    static String[] decodeProtocols(byte[] protocols) {
+        if (protocols.length == 0) {
+            return EmptyArray.STRING;
+        }
+
+        int numProtocols = 0;
+        for (int i = 0; i < protocols.length;) {
+            int protocolLength = protocols[i];
+            if (protocolLength < 0 || protocolLength > protocols.length - i) {
+                throw new IllegalArgumentException(
+                    "Protocol has invalid length (" + protocolLength + " at position " + i
+                        + "): " + (protocols.length < 50
+                        ? Arrays.toString(protocols) : protocols.length + " byte array"));
+            }
+
+            numProtocols++;
+            i += 1 + protocolLength;
+        }
+
+        String[] decoded = new String[numProtocols];
+        for (int i = 0, d = 0; i < protocols.length;) {
+            int protocolLength = protocols[i];
+            decoded[d++] = protocolLength > 0
+                    ? new String(protocols, i + 1, protocolLength, US_ASCII)
+                    : "";
+            i += 1 + protocolLength;
+        }
+
+        return decoded;
+    }
+
+    /**
+     * Encodes a list of protocols into the wire-format (length-prefixed 8-bit strings).
+     * Requires that all strings be encoded with US-ASCII.
+     *
+     * @param protocols the list of protocols to be encoded
+     * @return the encoded form of the protocol list.
+     * @throws IllegalArgumentException if protocols is {@code null}, or if any element is
+     * {@code null} or an empty string.
+     */
+    static byte[] encodeProtocols(String[] protocols) {
+        if (protocols == null) {
+            throw new IllegalArgumentException("protocols array must be non-null");
+        }
+
+        if (protocols.length == 0) {
+            return EmptyArray.BYTE;
+        }
+
+        // Calculate the encoded length.
+        int length = 0;
+        for (int i = 0; i < protocols.length; ++i) {
+            String protocol = protocols[i];
+            if (protocol == null) {
+                throw new IllegalArgumentException("protocol[" + i + "] is null");
+            }
+            int protocolLength = protocols[i].length();
+
+            // Verify that the length is valid here, so that we don't attempt to allocate an array
+            // below if the threshold is violated.
+            if (protocolLength == 0 || protocolLength > MAX_PROTOCOL_LENGTH) {
+                throw new IllegalArgumentException(
+                    "protocol[" + i + "] has invalid length: " + protocolLength);
+            }
+
+            // Include a 1-byte prefix for each protocol.
+            length += 1 + protocolLength;
+        }
+
+        byte[] data = new byte[length];
+        for (int dataIndex = 0, i = 0; i < protocols.length; ++i) {
+            String protocol = protocols[i];
+            int protocolLength = protocol.length();
+
+            // Add the length prefix.
+            data[dataIndex++] = (byte) protocolLength;
+            for (int ci = 0; ci < protocolLength; ++ci) {
+                char c = protocol.charAt(ci);
+                if (c > Byte.MAX_VALUE) {
+                    // Enforce US-ASCII
+                    throw new IllegalArgumentException("Protocol contains invalid character: "
+                        + c + "(protocol=" + protocol + ")");
+                }
+                data[dataIndex++] = (byte) c;
+            }
+        }
+        return data;
+    }
+
+    /**
+     * Return how much bytes can be read out of the encrypted data. Be aware that this method will
+     * not increase the readerIndex of the given {@link ByteBuffer}.
+     *
+     * @param buffers The {@link ByteBuffer}s to read from. Be aware that they must have at least
+     * {@link com.android.org.conscrypt.NativeConstants#SSL3_RT_HEADER_LENGTH} bytes to read, otherwise it will
+     * throw an {@link IllegalArgumentException}.
+     * @return length The length of the encrypted packet that is included in the buffer. This will
+     * return {@code -1} if the given {@link ByteBuffer} is not encrypted at all.
+     * @throws IllegalArgumentException Is thrown if the given {@link ByteBuffer} has not at least
+     * {@link com.android.org.conscrypt.NativeConstants#SSL3_RT_HEADER_LENGTH} bytes to read.
+     */
+    static int getEncryptedPacketLength(ByteBuffer[] buffers, int offset) {
+        ByteBuffer buffer = buffers[offset];
+
+        // Check if everything we need is in one ByteBuffer. If so we can make use of the fast-path.
+        if (buffer.remaining() >= SSL3_RT_HEADER_LENGTH) {
+            return getEncryptedPacketLength(buffer);
+        }
+
+        // We need to copy 5 bytes into a temporary buffer so we can parse out the packet length
+        // easily.
+        ByteBuffer tmp = ByteBuffer.allocate(SSL3_RT_HEADER_LENGTH);
+        do {
+            buffer = buffers[offset++];
+            int pos = buffer.position();
+            int limit = buffer.limit();
+            if (buffer.remaining() > tmp.remaining()) {
+                buffer.limit(pos + tmp.remaining());
+            }
+            try {
+                tmp.put(buffer);
+            } finally {
+                // Restore the original indices.
+                buffer.limit(limit);
+                buffer.position(pos);
+            }
+        } while (tmp.hasRemaining());
+
+        // Done, flip the buffer so we can read from it.
+        tmp.flip();
+        return getEncryptedPacketLength(tmp);
+    }
+
+    private static int getEncryptedPacketLength(ByteBuffer buffer) {
+        int pos = buffer.position();
+        // SSLv3 or TLS - Check ContentType
+        switch (unsignedByte(buffer.get(pos))) {
+            case SSL3_RT_CHANGE_CIPHER_SPEC:
+            case SSL3_RT_ALERT:
+            case SSL3_RT_HANDSHAKE:
+            case SSL3_RT_APPLICATION_DATA:
+                break;
+            default:
+                // SSLv2 or bad data
+                return -1;
+        }
+
+        // SSLv3 or TLS - Check ProtocolVersion
+        int majorVersion = unsignedByte(buffer.get(pos + 1));
+        if (majorVersion != 3) {
+            // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data)
+            return -1;
+        }
+
+        // SSLv3 or TLS
+        int packetLength = unsignedShort(buffer.getShort(pos + 3)) + SSL3_RT_HEADER_LENGTH;
+        if (packetLength <= SSL3_RT_HEADER_LENGTH) {
+            // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data)
+            return -1;
+        }
+        return packetLength;
+    }
+
+    private static short unsignedByte(byte b) {
+        return (short) (b & 0xFF);
+    }
+
+    private static int unsignedShort(short s) {
+        return s & 0xFFFF;
+    }
+
+    static String[] concat(String[]... arrays) {
+        int resultLength = 0;
+        for (String[] array : arrays) {
+            resultLength += array.length;
+        }
+        String[] result = new String[resultLength];
+        int resultOffset = 0;
+        for (String[] array : arrays) {
+            System.arraycopy(array, 0, result, resultOffset, array.length);
+            resultOffset += array.length;
+        }
+        return result;
+    }
+
+    private SSLUtils() {}
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ServerSessionContext.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ServerSessionContext.java
new file mode 100644
index 0000000..1be9883
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ServerSessionContext.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import javax.net.ssl.SSLContext;
+
+/**
+ * Caches server sessions. Indexes by session ID. Users typically look up
+ * sessions using the ID provided by an SSL client.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class ServerSessionContext extends AbstractSessionContext {
+    private SSLServerSessionCache persistentCache;
+
+    ServerSessionContext() {
+        super(100);
+
+        // TODO make sure SSL_CTX does not automaticaly clear sessions we want it to cache
+        // SSL_CTX_set_session_cache_mode(sslCtxNativePointer, SSL_SESS_CACHE_NO_AUTO_CLEAR);
+
+        // TODO remove SSL_CTX session cache limit so we can manage it
+        // SSL_CTX_sess_set_cache_size(sslCtxNativePointer, 0);
+
+        // TODO override trimToSize and removeEldestEntry to use
+        // SSL_CTX_sessions to remove from native cache
+
+        // Set a trivial session id context. OpenSSL uses this to make
+        // sure you don't reuse sessions externalized with i2d_SSL_SESSION
+        // between apps. However our sessions are either in memory or
+        // exported to a app's SSLServerSessionCache.
+        NativeCrypto.SSL_CTX_set_session_id_context(sslCtxNativePointer, this, new byte[] { ' ' });
+    }
+
+    /**
+     * Applications should not use this method. Instead use {@link
+     * Conscrypt#setServerSessionCache(SSLContext, SSLServerSessionCache)}.
+     */
+    public void setPersistentCache(SSLServerSessionCache persistentCache) {
+        this.persistentCache = persistentCache;
+    }
+
+    @Override
+    NativeSslSession getSessionFromPersistentCache(byte[] sessionId) {
+        if (persistentCache != null) {
+            byte[] data = persistentCache.getSessionData(sessionId);
+            if (data != null) {
+                NativeSslSession session = NativeSslSession.newInstance(this, data, null, -1);
+                if (session != null && session.isValid()) {
+                    cacheSession(session);
+                    return session;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    void onBeforeAddSession(NativeSslSession session) {
+        // TODO: Do this in background thread.
+        if (persistentCache != null) {
+            byte[] data = session.toBytes();
+            if (data != null) {
+                persistentCache.putSessionData(session.toSSLSession(), data);
+            }
+        }
+    }
+
+    @Override
+    void onBeforeRemoveSession(NativeSslSession session) {
+        // Do nothing.
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/SessionSnapshot.java b/repackaged/common/src/main/java/com/android/org/conscrypt/SessionSnapshot.java
new file mode 100644
index 0000000..4a9d781
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/SessionSnapshot.java
@@ -0,0 +1,187 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * A snapshot of the content of another {@link ConscryptSession}. This copies everything over
+ * except for the certificates.
+ */
+final class SessionSnapshot implements ConscryptSession {
+    private final SSLSessionContext sessionContext;
+    private final byte[] id;
+    private final String requestedServerName;
+    private final List<byte[]> statusResponses;
+    private final byte[] peerTlsSctData;
+    private final long creationTime;
+    private final long lastAccessedTime;
+    private final String cipherSuite;
+    private final String protocol;
+    private final String peerHost;
+    private final int peerPort;
+
+    SessionSnapshot(ConscryptSession session) {
+        sessionContext = session.getSessionContext();
+        id = session.getId();
+        requestedServerName = session.getRequestedServerName();
+        statusResponses = session.getStatusResponses();
+        peerTlsSctData = session.getPeerSignedCertificateTimestamp();
+        creationTime = session.getCreationTime();
+        lastAccessedTime = session.getLastAccessedTime();
+        cipherSuite = session.getCipherSuite();
+        protocol = session.getProtocol();
+        peerHost = session.getPeerHost();
+        peerPort = session.getPeerPort();
+    }
+
+    @Override
+    public String getRequestedServerName() {
+        return requestedServerName;
+    }
+
+    @Override
+    public List<byte[]> getStatusResponses() {
+        List<byte[]> ret = new ArrayList<byte[]>(statusResponses.size());
+        for (byte[] resp : statusResponses) {
+            ret.add(resp.clone());
+        }
+        return ret;
+    }
+
+    @Override
+    public byte[] getPeerSignedCertificateTimestamp() {
+        return peerTlsSctData != null ? peerTlsSctData.clone() : null;
+    }
+
+    @Override
+    public byte[] getId() {
+        return id;
+    }
+
+    @Override
+    public SSLSessionContext getSessionContext() {
+        return sessionContext;
+    }
+
+    @Override
+    public long getCreationTime() {
+        return creationTime;
+    }
+
+    @Override
+    public long getLastAccessedTime() {
+        return lastAccessedTime;
+    }
+
+    @Override
+    public void invalidate() {
+        // Do nothing.
+    }
+
+    @Override
+    public boolean isValid() {
+        return false;
+    }
+
+    @Override
+    public void putValue(String s, Object o) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public Object getValue(String s) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public void removeValue(String s) {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public String[] getValueNames() {
+        throw new UnsupportedOperationException(
+                "All calls to this method should be intercepted by ProvidedSessionDecorator.");
+    }
+
+    @Override
+    public X509Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+        throw new SSLPeerUnverifiedException("No peer certificates");
+    }
+
+    @Override
+    public Certificate[] getLocalCertificates() {
+        return null;
+    }
+
+    @Override
+    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
+        throws SSLPeerUnverifiedException {
+        throw new SSLPeerUnverifiedException("No peer certificates");
+    }
+
+    @Override
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        throw new SSLPeerUnverifiedException("No peer certificates");
+    }
+
+    @Override
+    public Principal getLocalPrincipal() {
+        return null;
+    }
+
+    @Override
+    public String getCipherSuite() {
+        return cipherSuite;
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol;
+    }
+
+    @Override
+    public String getPeerHost() {
+        return peerHost;
+    }
+
+    @Override
+    public int getPeerPort() {
+        return peerPort;
+    }
+
+    @Override
+    public int getPacketBufferSize() {
+        return NativeConstants.SSL3_RT_MAX_PACKET_SIZE;
+    }
+
+    @Override
+    public int getApplicationBufferSize() {
+        return NativeConstants.SSL3_RT_MAX_PLAIN_LENGTH;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/TrustManagerFactoryImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/TrustManagerFactoryImpl.java
new file mode 100644
index 0000000..438b73f
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/TrustManagerFactoryImpl.java
@@ -0,0 +1,90 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// License from Apache Harmony:
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactorySpi;
+
+/**
+ *
+ * TrustManagerFactory service provider interface implementation.
+ *
+ * @see javax.net.ssl.TrustManagerFactorySpi
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class TrustManagerFactoryImpl extends TrustManagerFactorySpi {
+
+    private KeyStore keyStore;
+
+    /**
+     * @see javax.net.ssl.TrustManagerFactorySpi#engineInit(KeyStore)
+     */
+    @Override
+    public void engineInit(KeyStore ks) throws KeyStoreException {
+        if (ks != null) {
+            keyStore = ks;
+        } else {
+            keyStore = Platform.getDefaultCertKeyStore();
+        }
+    }
+
+    /**
+     * @see javax.net.ssl#engineInit(ManagerFactoryParameters)
+     */
+    @Override
+    public void engineInit(ManagerFactoryParameters spec)
+            throws InvalidAlgorithmParameterException {
+        throw new InvalidAlgorithmParameterException(
+                "ManagerFactoryParameters not supported");
+    }
+
+    /**
+     * @see javax.net.ssl#engineGetTrustManagers()
+     */
+    @Override
+    public TrustManager[] engineGetTrustManagers() {
+        if (keyStore == null) {
+            throw new IllegalStateException(
+                    "TrustManagerFactory is not initialized");
+        }
+        return new TrustManager[] { new TrustManagerImpl(keyStore) };
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/TrustManagerImpl.java b/repackaged/common/src/main/java/com/android/org/conscrypt/TrustManagerImpl.java
new file mode 100644
index 0000000..3e9c20a
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/TrustManagerImpl.java
@@ -0,0 +1,1051 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// License from Apache Harmony:
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Socket;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.PKIXParameters;
+import java.security.cert.PKIXRevocationChecker;
+import java.security.cert.PKIXRevocationChecker.Option;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509ExtendedTrustManager;
+import com.android.org.conscrypt.ct.CTLogStore;
+import com.android.org.conscrypt.ct.CTPolicy;
+import com.android.org.conscrypt.ct.CTVerificationResult;
+import com.android.org.conscrypt.ct.CTVerifier;
+
+/**
+ *
+ * TrustManager implementation. The implementation is based on CertPathValidator
+ * PKIX and CertificateFactory X509 implementations. This implementations should
+ * be provided by some certification provider.
+ *
+ * @see javax.net.ssl.X509ExtendedTrustManager
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public final class TrustManagerImpl extends X509ExtendedTrustManager {
+
+    private static final Logger logger = Logger.getLogger(TrustManagerImpl.class.getName());
+
+    /**
+     * Comparator used for ordering trust anchors during certificate path building.
+     */
+    private static final TrustAnchorComparator TRUST_ANCHOR_COMPARATOR =
+            new TrustAnchorComparator();
+
+    private static ConscryptHostnameVerifier defaultHostnameVerifier;
+
+    /**
+     * The AndroidCAStore if non-null, null otherwise.
+     */
+    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.
+     */
+    private final ConscryptCertStore trustedCertificateStore;
+
+    private final CertPathValidator validator;
+
+    /**
+     * An index of TrustAnchor instances that we've seen.
+     */
+    private final TrustedCertificateIndex trustedCertificateIndex;
+
+    /**
+     * An index of intermediate certificates that we've seen. These certificates are NOT implicitly
+     * trusted and must still form a valid chain to an anchor.
+     */
+    private final TrustedCertificateIndex intermediateIndex;
+
+    /**
+     * This is lazily initialized in the AndroidCAStore case since it
+     * forces us to bring all the CAs into memory. In the
+     * non-AndroidCAStore, we initialize this as part of the
+     * constructor.
+     */
+    private final X509Certificate[] acceptedIssuers;
+
+    private final Exception err;
+    private final CertificateFactory factory;
+    private final CertBlacklist blacklist;
+    private CTVerifier ctVerifier;
+    private CTPolicy ctPolicy;
+
+    private ConscryptHostnameVerifier hostnameVerifier;
+
+    // Forces CT verification to always to done. For tests.
+    private boolean ctEnabledOverride;
+
+    /**
+     * Creates X509TrustManager based on a keystore
+     *
+     * @param keyStore
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public TrustManagerImpl(KeyStore keyStore) {
+        this(keyStore, null);
+    }
+
+    public TrustManagerImpl(KeyStore keyStore, CertPinManager manager) {
+        this(keyStore, manager, null);
+    }
+
+    @libcore.api.CorePlatformApi
+    public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
+            ConscryptCertStore certStore) {
+        this(keyStore, manager, certStore, null);
+    }
+
+    public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
+            ConscryptCertStore certStore,
+                            CertBlacklist blacklist) {
+        this(keyStore, manager, certStore, blacklist, null, null, null);
+    }
+
+    /**
+     * For testing only.
+     */
+    public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
+            ConscryptCertStore certStore, CertBlacklist blacklist, CTLogStore ctLogStore,
+            CTVerifier ctVerifier, CTPolicy ctPolicy) {
+        CertPathValidator validatorLocal = null;
+        CertificateFactory factoryLocal = null;
+        KeyStore rootKeyStoreLocal = null;
+        ConscryptCertStore trustedCertificateStoreLocal = null;
+        TrustedCertificateIndex trustedCertificateIndexLocal = null;
+        X509Certificate[] acceptedIssuersLocal = null;
+        Exception errLocal = null;
+        try {
+            validatorLocal = CertPathValidator.getInstance("PKIX");
+            factoryLocal = CertificateFactory.getInstance("X509");
+
+            // if we have an AndroidCAStore, we will lazily load CAs
+            if ("AndroidCAStore".equals(keyStore.getType())
+                    && Platform.supportsConscryptCertStore()) {
+                rootKeyStoreLocal = keyStore;
+                trustedCertificateStoreLocal =
+                    (certStore != null) ? certStore : Platform.newDefaultCertStore();
+                acceptedIssuersLocal = null;
+                trustedCertificateIndexLocal = new TrustedCertificateIndex();
+            } else {
+                rootKeyStoreLocal = null;
+                trustedCertificateStoreLocal = certStore;
+                acceptedIssuersLocal = acceptedIssuers(keyStore);
+                trustedCertificateIndexLocal
+                        = new TrustedCertificateIndex(trustAnchors(acceptedIssuersLocal));
+            }
+
+        } catch (Exception e) {
+            errLocal = e;
+        }
+
+        if (blacklist == null) {
+            blacklist = Platform.newDefaultBlacklist();
+        }
+        if (ctLogStore == null) {
+            ctLogStore = Platform.newDefaultLogStore();
+        }
+
+        if (ctPolicy == null) {
+            ctPolicy = Platform.newDefaultPolicy(ctLogStore);
+        }
+
+        this.pinManager = manager;
+        this.rootKeyStore = rootKeyStoreLocal;
+        this.trustedCertificateStore = trustedCertificateStoreLocal;
+        this.validator = validatorLocal;
+        this.factory = factoryLocal;
+        this.trustedCertificateIndex = trustedCertificateIndexLocal;
+        this.intermediateIndex = new TrustedCertificateIndex();
+        this.acceptedIssuers = acceptedIssuersLocal;
+        this.err = errLocal;
+        this.blacklist = blacklist;
+        this.ctVerifier = new CTVerifier(ctLogStore);
+        this.ctPolicy = ctPolicy;
+    }
+
+    private static X509Certificate[] acceptedIssuers(KeyStore ks) {
+        try {
+            // Note that unlike the PKIXParameters code to create a Set of
+            // TrustAnchors from a KeyStore, this version takes from both
+            // TrustedCertificateEntry and PrivateKeyEntry, not just
+            // TrustedCertificateEntry, which is why TrustManagerImpl
+            // cannot just use an PKIXParameters(KeyStore)
+            // constructor.
+
+            // TODO remove duplicates if same cert is found in both a
+            // PrivateKeyEntry and TrustedCertificateEntry
+            List<X509Certificate> trusted = new ArrayList<X509Certificate>();
+            for (Enumeration<String> en = ks.aliases(); en.hasMoreElements();) {
+                final String alias = en.nextElement();
+                final X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
+                if (cert != null) {
+                    trusted.add(cert);
+                }
+            }
+            return trusted.toArray(new X509Certificate[trusted.size()]);
+        } catch (KeyStoreException e) {
+            return new X509Certificate[0];
+        }
+    }
+
+    private static Set<TrustAnchor> trustAnchors(X509Certificate[] certs) {
+        Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>(certs.length);
+        for (X509Certificate cert : certs) {
+            trustAnchors.add(new TrustAnchor(cert, null));
+        }
+        return trustAnchors;
+    }
+
+    @libcore.api.CorePlatformApi
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        checkTrusted(chain, authType, null, null, true /* client auth */);
+    }
+
+    /**
+     * For backward compatibility with older Android API that used String for the hostname only.
+     */
+    public List<X509Certificate> checkClientTrusted(X509Certificate[] chain, String authType,
+            String hostname) throws CertificateException {
+        return checkTrusted(chain, null /* ocspData */, null /* tlsSctData */, authType, hostname,
+                true);
+    }
+
+    private static SSLSession getHandshakeSessionOrThrow(SSLSocket sslSocket)
+            throws CertificateException {
+        SSLSession session = sslSocket.getHandshakeSession();
+        if (session == null) {
+            throw new CertificateException("Not in handshake; no session available");
+        }
+        return session;
+    }
+
+    @libcore.api.CorePlatformApi
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
+            throws CertificateException {
+        SSLSession session = null;
+        SSLParameters parameters = null;
+        if (socket instanceof SSLSocket) {
+            SSLSocket sslSocket = (SSLSocket) socket;
+            session = getHandshakeSessionOrThrow(sslSocket);
+            parameters = sslSocket.getSSLParameters();
+        }
+        checkTrusted(chain, authType, session, parameters, true /* client auth */);
+    }
+
+    @libcore.api.CorePlatformApi
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
+            throws CertificateException {
+        SSLSession session = engine.getHandshakeSession();
+        if (session == null) {
+            throw new CertificateException("Not in handshake; no session available");
+        }
+        checkTrusted(chain, authType, session, engine.getSSLParameters(), true /* client auth */);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        checkTrusted(chain, authType, null, null, false /* client auth */);
+    }
+
+    /**
+     * For backward compatibility with older Android API that used String for the hostname only.
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
+            String hostname) throws CertificateException {
+        return checkTrusted(chain, null /* ocspData */, null /* tlsSctData */, authType, hostname,
+                false);
+    }
+
+    /**
+     * Returns the full trusted certificate chain found from {@code certs}.
+     *
+     * Throws {@link CertificateException} when no trusted chain can be found from {@code certs}.
+     */
+    @libcore.api.CorePlatformApi
+    public List<X509Certificate> getTrustedChainForServer(X509Certificate[] certs,
+            String authType, Socket socket) throws CertificateException {
+        SSLSession session = null;
+        SSLParameters parameters = null;
+        if (socket instanceof SSLSocket) {
+            SSLSocket sslSocket = (SSLSocket) socket;
+            session = getHandshakeSessionOrThrow(sslSocket);
+            parameters = sslSocket.getSSLParameters();
+        }
+        return checkTrusted(certs, authType, session, parameters, false /* client auth */);
+    }
+
+    /**
+     * Returns the full trusted certificate chain found from {@code certs}.
+     *
+     * Throws {@link CertificateException} when no trusted chain can be found from {@code certs}.
+     */
+    @libcore.api.CorePlatformApi
+    public List<X509Certificate> getTrustedChainForServer(X509Certificate[] certs,
+            String authType, SSLEngine engine) throws CertificateException {
+        SSLSession session = engine.getHandshakeSession();
+        if (session == null) {
+            throw new CertificateException("Not in handshake; no session available");
+        }
+        return checkTrusted(certs, authType, session, engine.getSSLParameters(),
+                false /* client auth */);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
+            throws CertificateException {
+        getTrustedChainForServer(chain, authType, socket);
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
+            throws CertificateException {
+        getTrustedChainForServer(chain, authType, engine);
+    }
+
+    /**
+     * Validates whether a server is trusted. If session is given and non-null
+     * it also checks if chain is pinned appropriately for that peer 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,
+            SSLSession session) throws CertificateException {
+        return checkTrusted(chain, authType, session, null, false /* client auth */);
+    }
+
+    @libcore.api.CorePlatformApi
+    public void handleTrustStorageUpdate() {
+        if (acceptedIssuers == null) {
+            trustedCertificateIndex.reset();
+        } else {
+            trustedCertificateIndex.reset(trustAnchors(acceptedIssuers));
+        }
+    }
+
+    private List<X509Certificate> checkTrusted(X509Certificate[] certs, String authType,
+            SSLSession session, SSLParameters parameters, boolean clientAuth)
+                    throws CertificateException {
+        byte[] ocspData = null;
+        byte[] tlsSctData = null;
+        String hostname = null;
+        if (session != null) {
+            hostname = session.getPeerHost();
+            ocspData = getOcspDataFromSession(session);
+            tlsSctData = getTlsSctDataFromSession(session);
+        }
+
+        if (session != null && parameters != null) {
+            String identificationAlgorithm = parameters.getEndpointIdentificationAlgorithm();
+            if ("HTTPS".equalsIgnoreCase(identificationAlgorithm)) {
+                ConscryptHostnameVerifier verifier = getHttpsVerifier();
+                if (!verifier.verify(hostname, session)) {
+                    throw new CertificateException("No subjectAltNames on the certificate match");
+                }
+            }
+        }
+        return checkTrusted(certs, ocspData, tlsSctData, authType, hostname, clientAuth);
+    }
+
+    private byte[] getOcspDataFromSession(SSLSession session) {
+        List<byte[]> ocspResponses = null;
+        if (session instanceof ConscryptSession) {
+            ConscryptSession opensslSession = (ConscryptSession) session;
+            ocspResponses = opensslSession.getStatusResponses();
+        } else {
+            Method m_getResponses;
+            try {
+                m_getResponses = session.getClass().getDeclaredMethod("getStatusResponses");
+                m_getResponses.setAccessible(true);
+                Object rawResponses = m_getResponses.invoke(session);
+                if (rawResponses instanceof List) {
+                    ocspResponses = (List<byte[]>) rawResponses;
+                }
+            } catch (NoSuchMethodException ignored) {
+            } catch (SecurityException ignored) {
+            } catch (IllegalAccessException ignored) {
+            } catch (IllegalArgumentException ignored) {
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e.getCause());
+            }
+        }
+
+        if (ocspResponses == null || ocspResponses.isEmpty()) {
+            return null;
+        }
+
+        return ocspResponses.get(0);
+    }
+
+    private byte[] getTlsSctDataFromSession(SSLSession session) {
+        if (session instanceof ConscryptSession) {
+            ConscryptSession opensslSession = (ConscryptSession) session;
+            return opensslSession.getPeerSignedCertificateTimestamp();
+        }
+
+        byte[] data = null;
+        try {
+            Method m_getTlsSctData = session.getClass().getDeclaredMethod("getPeerSignedCertificateTimestamp");
+            m_getTlsSctData.setAccessible(true);
+            Object rawData = m_getTlsSctData.invoke(session);
+            if (rawData instanceof byte[]) {
+                data = (byte[]) rawData;
+            }
+        } catch (NoSuchMethodException ignored) {
+        } catch (SecurityException ignored) {
+        } catch (IllegalAccessException ignored) {
+        } catch (IllegalArgumentException ignored) {
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException(e.getCause());
+        }
+        return data;
+    }
+
+    private List<X509Certificate> checkTrusted(X509Certificate[] certs, byte[] ocspData,
+            byte[] tlsSctData, String authType, String host, boolean clientAuth)
+            throws CertificateException {
+        if (certs == null || certs.length == 0 || authType == null || authType.length() == 0) {
+            throw new IllegalArgumentException("null or zero-length parameter");
+        }
+        if (err != null) {
+            throw new CertificateException(err);
+        }
+        Set<X509Certificate> used = new HashSet<X509Certificate>();
+        ArrayList<X509Certificate> untrustedChain = new ArrayList<X509Certificate>();
+        ArrayList<TrustAnchor> trustedChain = new ArrayList<TrustAnchor>();
+        // Initialize the chain to contain the leaf certificate. This potentially could be a trust
+        // anchor. If the leaf is a trust anchor we still continue with path building to build the
+        // complete trusted chain for additional validation such as certificate pinning.
+        X509Certificate leaf = certs[0];
+        TrustAnchor leafAsAnchor = findTrustAnchorBySubjectAndPublicKey(leaf);
+        if (leafAsAnchor != null) {
+            trustedChain.add(leafAsAnchor);
+            used.add(leafAsAnchor.getTrustedCert());
+        } else {
+            untrustedChain.add(leaf);
+        }
+        used.add(leaf);
+        return checkTrustedRecursive(certs, ocspData, tlsSctData, host, clientAuth,
+                untrustedChain, trustedChain, used);
+    }
+
+    /**
+     * Recursively build certificate chains until a valid chain is found or all possible paths are
+     * exhausted.
+     *
+     * The chain is built in two sections, the complete trusted path is the the combination of
+     * {@code untrustedChain} and {@code trustAnchorChain}. The chain begins at the leaf
+     * certificate and ends in the final trusted root certificate.
+     *
+     * @param certs the bag of certs provided by the peer. No order is assumed.
+     * @param host the host being connected to.
+     * @param clientAuth if a client is being authorized instead of a server.
+     * @param untrustedChain the untrusted section of the chain built so far. Must be mutable.
+     * @param trustAnchorChain the trusted section of the chain built so far. Must be mutable.
+     * @param used the set certificates used so far in path building. Must be mutable.
+     *
+     * @return The entire valid chain starting with the leaf certificate. This is the
+     * concatenation of untrustedChain and trustAnchorChain.
+     *
+     * @throws CertificateException If no valid chain could be constructed. Note that there may be
+     * multiple reasons why no valid chain exists and there is no guarantee that the most severe is
+     * reported in this exception. As such applications MUST NOT use the specifics of this error
+     * for trust decisions (e.g. showing the user a click through page based on the specific error).
+     */
+    private List<X509Certificate> checkTrustedRecursive(X509Certificate[] certs, byte[] ocspData,
+            byte[] tlsSctData, String host, boolean clientAuth,
+            ArrayList<X509Certificate> untrustedChain, ArrayList<TrustAnchor> trustAnchorChain,
+            Set<X509Certificate> used) throws CertificateException {
+        CertificateException lastException = null;
+        X509Certificate current;
+        if (trustAnchorChain.isEmpty()) {
+            current = untrustedChain.get(untrustedChain.size() - 1);
+        } else {
+            current = trustAnchorChain.get(trustAnchorChain.size() - 1).getTrustedCert();
+        }
+
+        // Check that the certificate isn't blacklisted.
+        checkBlacklist(current);
+
+        // 1. If the current certificate in the chain is self-signed verify the chain as is.
+        if (current.getIssuerDN().equals(current.getSubjectDN())) {
+            return verifyChain(untrustedChain, trustAnchorChain, host, clientAuth, ocspData,
+                    tlsSctData);
+        }
+
+        // 2. Try building a chain via any trust anchors that issued the current certificate.
+        // Note that we do not stop at the first trust anchor since it is possible that the trust
+        // anchor is not self-signed and its issuer may be needed for additional validation such as
+        // certificate pinning. In the common case the first trust anchor will be self-signed or
+        // its issuer's certificate will be missing.
+        Set<TrustAnchor> anchors = findAllTrustAnchorsByIssuerAndSignature(current);
+        boolean seenIssuer = false;
+        for (TrustAnchor anchor : sortPotentialAnchors(anchors)) {
+            X509Certificate anchorCert = anchor.getTrustedCert();
+            // Avoid using certificates that have already been used.
+            if (used.contains(anchorCert)) {
+                continue;
+            }
+            seenIssuer = true;
+            used.add(anchorCert);
+            trustAnchorChain.add(anchor);
+            try {
+                return checkTrustedRecursive(certs, ocspData, tlsSctData, host, clientAuth,
+                        untrustedChain, trustAnchorChain, used);
+            } catch (CertificateException ex) {
+                lastException = ex;
+            }
+            // Could not form a valid chain via this certificate, remove it from this chain.
+            trustAnchorChain.remove(trustAnchorChain.size() - 1);
+            used.remove(anchorCert);
+        }
+
+        // 3. If we were unable to find additional trusted issuers, verify the current chain.
+        // This may happen if the root of trust is not self-signed and the issuer is not
+        // present in the trusted set.
+        if (!trustAnchorChain.isEmpty()) {
+            if (!seenIssuer) {
+                return verifyChain(untrustedChain, trustAnchorChain, host, clientAuth, ocspData,
+                        tlsSctData);
+            }
+
+            // Otherwise all chains based on the current trust anchor were rejected, fail.
+            throw lastException;
+        }
+
+        // 4. Use the certificates provided by the peer to grow the chain.
+        // Ignore the first certificate, as that is the leaf certificate.
+        for (int i = 1; i < certs.length; i++) {
+            X509Certificate candidateIssuer = certs[i];
+            // Avoid using certificates that have already been used.
+            if (used.contains(candidateIssuer)) {
+                continue;
+            }
+            if (current.getIssuerDN().equals(candidateIssuer.getSubjectDN())) {
+                // Check the strength and validity of the certificate to prune bad certificates
+                // early.
+                try {
+                    candidateIssuer.checkValidity();
+                    ChainStrengthAnalyzer.checkCert(candidateIssuer);
+                } catch (CertificateException ex) {
+                    lastException = new CertificateException("Unacceptable certificate: "
+                            + candidateIssuer.getSubjectX500Principal(), ex);
+                    continue;
+                }
+                used.add(candidateIssuer);
+                untrustedChain.add(candidateIssuer);
+                try {
+                    return checkTrustedRecursive(certs, ocspData, tlsSctData, host, clientAuth,
+                            untrustedChain, trustAnchorChain, used);
+                } catch (CertificateException ex) {
+                    lastException = ex;
+                }
+                // Could not form a valid chain via this certificate, remove it from this chain.
+                used.remove(candidateIssuer);
+                untrustedChain.remove(untrustedChain.size() - 1);
+            }
+        }
+
+        // 5. Finally try the cached intermediates to handle server that failed to send them.
+        Set<TrustAnchor> intermediateAnchors =
+                intermediateIndex.findAllByIssuerAndSignature(current);
+        for (TrustAnchor intermediate : sortPotentialAnchors(intermediateAnchors)) {
+            X509Certificate intermediateCert = intermediate.getTrustedCert();
+            // Avoid using certificates that have already been used.
+            if (used.contains(intermediateCert)) {
+                continue;
+            }
+            used.add(intermediateCert);
+            untrustedChain.add(intermediateCert);
+            try {
+                return checkTrustedRecursive(certs, ocspData, tlsSctData, host, clientAuth,
+                        untrustedChain, trustAnchorChain, used);
+            } catch (CertificateException ex) {
+                lastException = ex;
+            }
+            // Could not form a valid chain via this certificate, remove it from this chain.
+            untrustedChain.remove(untrustedChain.size() - 1);
+            used.remove(intermediateCert);
+        }
+
+        // 6. We were unable to build a valid chain, throw the last error encountered.
+        if (lastException != null) {
+            throw lastException;
+        }
+
+        // 7. If no errors were encountered above then verifyChain was never called because it was
+        // not possible to build a valid chain to a trusted certificate.
+        CertPath certPath = factory.generateCertPath(untrustedChain);
+        throw new CertificateException(new CertPathValidatorException(
+                "Trust anchor for certification path not found.", null, certPath, -1));
+    }
+
+    private List<X509Certificate> verifyChain(List<X509Certificate> untrustedChain,
+            List<TrustAnchor> trustAnchorChain, String host, boolean clientAuth, byte[] ocspData,
+            byte[] tlsSctData)
+            throws CertificateException {
+        try {
+            // build the cert path from the list of certs sans trust anchors
+            // TODO: check whether this is slow and should be replaced by a minimalistic CertPath impl
+            // since we already have built the path.
+            CertPath certPath = factory.generateCertPath(untrustedChain);
+
+            // Check that there are at least some trust anchors
+            if (trustAnchorChain.isEmpty()) {
+                throw new CertificateException(new CertPathValidatorException(
+                        "Trust anchor for certification path not found.", null, certPath, -1));
+            }
+
+            List<X509Certificate> wholeChain = new ArrayList<X509Certificate>();
+            wholeChain.addAll(untrustedChain);
+            for (TrustAnchor anchor : trustAnchorChain) {
+                wholeChain.add(anchor.getTrustedCert());
+            }
+
+            if (pinManager != null) {
+                pinManager.checkChainPinning(host, wholeChain);
+            }
+            // Check whole chain against the blacklist
+            for (X509Certificate cert : wholeChain) {
+                checkBlacklist(cert);
+            }
+
+            // Check CT (if required).
+            if (!clientAuth &&
+                    (ctEnabledOverride || (host != null && Platform
+                            .isCTVerificationRequired(host)))) {
+                checkCT(host, wholeChain, ocspData, tlsSctData);
+            }
+
+            if (untrustedChain.isEmpty()) {
+                // The chain consists of only trust anchors, skip the validator
+                return wholeChain;
+            }
+
+            ChainStrengthAnalyzer.check(untrustedChain);
+
+            // Validate the untrusted part of the chain
+            try {
+                Set<TrustAnchor> anchorSet = new HashSet<TrustAnchor>();
+                // We know that untrusted chains to the first trust anchor, only add that.
+                anchorSet.add(trustAnchorChain.get(0));
+                PKIXParameters params = new PKIXParameters(anchorSet);
+                params.setRevocationEnabled(false);
+                X509Certificate endPointCert = untrustedChain.get(0);
+                setOcspResponses(params, endPointCert, ocspData);
+                params.addCertPathChecker(
+                        new ExtendedKeyUsagePKIXCertPathChecker(clientAuth, endPointCert));
+                validator.validate(certPath, params);
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new CertificateException("Chain validation failed", e);
+            } catch (CertPathValidatorException e) {
+                throw new CertificateException("Chain validation failed", e);
+            }
+            // Add intermediate CAs to the index to tolerate sites
+            // that assume that the browser will have cached these.
+            // http://b/3404902
+            for (int i = 1; i < untrustedChain.size(); i++) {
+                intermediateIndex.index(untrustedChain.get(i));
+            }
+            return wholeChain;
+        } catch (CertificateException e) {
+            logger.fine("Rejected candidate cert chain due to error: " + e.getMessage());
+            throw e;
+        }
+    }
+
+    private void checkBlacklist(X509Certificate cert) throws CertificateException {
+        if (blacklist != null && blacklist.isPublicKeyBlackListed(cert.getPublicKey())) {
+            throw new CertificateException("Certificate blacklisted by public key: " + cert);
+        }
+    }
+
+    private void checkCT(String host, List<X509Certificate> chain, byte[] ocspData, byte[] tlsData)
+            throws CertificateException {
+        CTVerificationResult result =
+                ctVerifier.verifySignedCertificateTimestamps(chain, tlsData, ocspData);
+
+        if (!ctPolicy.doesResultConformToPolicy(result, host,
+                    chain.toArray(new X509Certificate[chain.size()]))) {
+            throw new CertificateException(
+                    "Certificate chain does not conform to required transparency policy.");
+        }
+    }
+
+    /**
+     * Sets the OCSP response data that was possibly stapled to the TLS response.
+     */
+    private void setOcspResponses(PKIXParameters params, X509Certificate cert, byte[] ocspData) {
+        if (ocspData == null) {
+            return;
+        }
+
+        PKIXRevocationChecker revChecker = null;
+        List<PKIXCertPathChecker> checkers =
+                new ArrayList<PKIXCertPathChecker>(params.getCertPathCheckers());
+        for (PKIXCertPathChecker checker : checkers) {
+            if (checker instanceof PKIXRevocationChecker) {
+                revChecker = (PKIXRevocationChecker) checker;
+                break;
+            }
+        }
+
+        if (revChecker == null) {
+            // Only new CertPathValidatorSpi instances will support the
+            // revocation checker API.
+            try {
+                revChecker = (PKIXRevocationChecker) validator.getRevocationChecker();
+            } catch (UnsupportedOperationException e) {
+                return;
+            }
+
+            checkers.add(revChecker);
+
+            /*
+             * If we add a new revocation checker, we should set the option for
+             * end-entity verification only. Otherwise the CertPathValidator will
+             * throw an exception when it can't verify the entire chain.
+             */
+            revChecker.setOptions(Collections.singleton(Option.ONLY_END_ENTITY));
+        }
+
+        revChecker.setOcspResponses(Collections.singletonMap(cert, ocspData));
+        params.setCertPathCheckers(checkers);
+    }
+
+    /**
+     * Sort potential anchors so that the most preferred for use come first.
+     *
+     * @see CertificatePriorityComparator
+     */
+    private static Collection<TrustAnchor> sortPotentialAnchors(Set<TrustAnchor> anchors) {
+        if (anchors.size() <= 1) {
+            return anchors;
+        }
+        List<TrustAnchor> sortedAnchors = new ArrayList<TrustAnchor>(anchors);
+        Collections.sort(sortedAnchors, TRUST_ANCHOR_COMPARATOR);
+        return sortedAnchors;
+    }
+
+
+    /**
+     * Comparator for sorting {@link TrustAnchor}s using a {@link CertificatePriorityComparator}.
+     */
+    private static class TrustAnchorComparator implements Comparator<TrustAnchor> {
+        private static final CertificatePriorityComparator CERT_COMPARATOR =
+                new CertificatePriorityComparator();
+        @Override
+        public int compare(TrustAnchor lhs, TrustAnchor rhs) {
+            X509Certificate lhsCert = lhs.getTrustedCert();
+            X509Certificate rhsCert = rhs.getTrustedCert();
+            return CERT_COMPARATOR.compare(lhsCert, rhsCert);
+        }
+    }
+
+    /**
+     * If an EKU extension is present in the end-entity certificate,
+     * it MUST contain an appropriate key usage. For servers, this
+     * includes anyExtendedKeyUsage, serverAuth, or the historical
+     * Server Gated Cryptography options of nsSGC or msSGC.  For
+     * clients, this includes anyExtendedKeyUsage and clientAuth.
+     */
+    private static class ExtendedKeyUsagePKIXCertPathChecker extends PKIXCertPathChecker {
+
+        private static final String EKU_OID = "2.5.29.37";
+
+        private static final String EKU_anyExtendedKeyUsage = "2.5.29.37.0";
+        private static final String EKU_clientAuth = "1.3.6.1.5.5.7.3.2";
+        private static final String EKU_serverAuth = "1.3.6.1.5.5.7.3.1";
+        private static final String EKU_nsSGC = "2.16.840.1.113730.4.1";
+        private static final String EKU_msSGC = "1.3.6.1.4.1.311.10.3.3";
+
+        private static final Set<String> SUPPORTED_EXTENSIONS
+                = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(EKU_OID)));
+
+        private final boolean clientAuth;
+        private final X509Certificate leaf;
+
+        private ExtendedKeyUsagePKIXCertPathChecker(boolean clientAuth, X509Certificate leaf) {
+            this.clientAuth = clientAuth;
+            this.leaf = leaf;
+        }
+
+        @Override
+        public void init(boolean forward) throws CertPathValidatorException {
+        }
+
+        @Override
+        public boolean isForwardCheckingSupported() {
+            return true;
+        }
+
+        @Override
+        public Set<String> getSupportedExtensions() {
+            return SUPPORTED_EXTENSIONS;
+        }
+
+        @SuppressWarnings("ReferenceEquality")
+        @Override
+        public void check(Certificate c, Collection<String> unresolvedCritExts)
+                throws CertPathValidatorException {
+            // We only want to validate the EKU on the leaf certificate.
+            if (c != leaf) {
+                return;
+            }
+            List<String> ekuOids;
+            try {
+                ekuOids = leaf.getExtendedKeyUsage();
+            } catch (CertificateParsingException e) {
+                // A malformed EKU is bad news, consider it fatal.
+                throw new CertPathValidatorException(e);
+            }
+            // We are here to check EKU, but there is none.
+            if (ekuOids == null) {
+                return;
+            }
+
+            boolean goodExtendedKeyUsage = false;
+            for (String ekuOid : ekuOids) {
+                // anyExtendedKeyUsage for clients and servers
+                if (ekuOid.equals(EKU_anyExtendedKeyUsage)) {
+                    goodExtendedKeyUsage = true;
+                    break;
+                }
+
+                // clients
+                if (clientAuth) {
+                    if (ekuOid.equals(EKU_clientAuth)) {
+                        goodExtendedKeyUsage = true;
+                        break;
+                    }
+                    continue;
+                }
+
+                // servers
+                if (ekuOid.equals(EKU_serverAuth)) {
+                    goodExtendedKeyUsage = true;
+                    break;
+                }
+                if (ekuOid.equals(EKU_nsSGC)) {
+                    goodExtendedKeyUsage = true;
+                    break;
+                }
+                if (ekuOid.equals(EKU_msSGC)) {
+                    goodExtendedKeyUsage = true;
+                    break;
+                }
+            }
+            if (goodExtendedKeyUsage) {
+                // Mark extendedKeyUsage as resolved if present.
+                unresolvedCritExts.remove(EKU_OID);
+            } else {
+                throw new CertPathValidatorException("End-entity certificate does not have a valid "
+                                                     + "extendedKeyUsage.");
+            }
+        }
+    }
+
+    /**
+     * Find all possible issuing trust anchors of {@code cert}.
+     */
+    private Set<TrustAnchor> findAllTrustAnchorsByIssuerAndSignature(X509Certificate cert) {
+        Set<TrustAnchor> indexedAnchors =
+                trustedCertificateIndex.findAllByIssuerAndSignature(cert);
+        if (!indexedAnchors.isEmpty() || trustedCertificateStore == null) {
+            return indexedAnchors;
+        }
+        Set<X509Certificate> storeAnchors = trustedCertificateStore.findAllIssuers(cert);
+        if (storeAnchors.isEmpty()) {
+            return indexedAnchors;
+        }
+        Set<TrustAnchor> result = new HashSet<TrustAnchor>(storeAnchors.size());
+        for (X509Certificate storeCert : storeAnchors) {
+            result.add(trustedCertificateIndex.index(storeCert));
+        }
+        return result;
+    }
+
+    /**
+     * Check the trustedCertificateIndex for the cert to see if it is
+     * already trusted and failing that check the KeyStore if it is
+     * available.
+     */
+    private TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {
+        TrustAnchor trustAnchor = trustedCertificateIndex.findBySubjectAndPublicKey(cert);
+        if (trustAnchor != null) {
+            return trustAnchor;
+        }
+        if (trustedCertificateStore == null) {
+            // not trusted and no TrustedCertificateStore to check
+            return null;
+        }
+        // probe KeyStore for a cert. AndroidCAStore stores its
+        // contents hashed by cert subject on the filesystem to make
+        // this faster than scanning all key store entries.
+        X509Certificate systemCert = trustedCertificateStore.getTrustAnchor(cert);
+        if (systemCert != null) {
+            // Don't index the system certificate here, that way the only place that adds anchors to
+            // the index are findAllTrustAnchorsByIssuerAndSignature.
+            // This allows findAllTrustAnchorsByIssuerAndSignature to avoid checking the
+            // TrustedCertificateStore if the TrustedCertificateIndex contains any issuers for the
+            // certificate because it will have cached all certificates contained in the
+            // TrustedCertificateStore.
+            return new TrustAnchor(systemCert, null);
+        }
+        return null;
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return (acceptedIssuers != null) ? acceptedIssuers.clone() : acceptedIssuers(rootKeyStore);
+    }
+
+    /**
+     * Set the default hostname verifier that will be used for HTTPS endpoint identification.  If
+     * {@code null} (the default), endpoint identification will use the default hostname verifier
+     * set in {@link HttpsURLConnection#setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier)}.
+     */
+    synchronized static void setDefaultHostnameVerifier(ConscryptHostnameVerifier verifier) {
+        defaultHostnameVerifier = verifier;
+    }
+
+    /**
+     * Returns the currently-set default hostname verifier.
+     *
+     * @see #setDefaultHostnameVerifier(ConscryptHostnameVerifier)
+     */
+    synchronized static ConscryptHostnameVerifier getDefaultHostnameVerifier() {
+        return defaultHostnameVerifier;
+    }
+
+    /**
+     * Set the hostname verifier that will be used for HTTPS endpoint identification.  If
+     * {@code null} (the default), endpoint identification will use the default hostname verifier
+     * set in {@link #setDefaultHostnameVerifier(ConscryptHostnameVerifier)}.
+     */
+    void setHostnameVerifier(ConscryptHostnameVerifier verifier) {
+        this.hostnameVerifier = verifier;
+    }
+
+    /**
+     * Returns the currently-set hostname verifier for this instance.
+     *
+     * @see #setHostnameVerifier(ConscryptHostnameVerifier)
+     */
+    ConscryptHostnameVerifier getHostnameVerifier() {
+        return hostnameVerifier;
+    }
+
+    private enum GlobalHostnameVerifierAdapter implements ConscryptHostnameVerifier {
+        INSTANCE;
+
+        @Override
+        public boolean verify(String hostname, SSLSession session) {
+            return HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session);
+        }
+    }
+
+    private ConscryptHostnameVerifier getHttpsVerifier() {
+        if (hostnameVerifier != null) {
+            return hostnameVerifier;
+        }
+        ConscryptHostnameVerifier defaultVerifier = getDefaultHostnameVerifier();
+        if (defaultVerifier != null) {
+            return defaultVerifier;
+        }
+        return GlobalHostnameVerifierAdapter.INSTANCE;
+    }
+
+    public void setCTEnabledOverride(boolean enabled) {
+        this.ctEnabledOverride = enabled;
+    }
+
+    // Replace the CTVerifier. For testing only.
+    public void setCTVerifier(CTVerifier verifier) {
+        this.ctVerifier = verifier;
+    }
+
+    // Replace the CTPolicy. For testing only.
+    public void setCTPolicy(CTPolicy policy) {
+        this.ctPolicy = policy;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/TrustedCertificateIndex.java b/repackaged/common/src/main/java/com/android/org/conscrypt/TrustedCertificateIndex.java
new file mode 100644
index 0000000..5df6c41
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/TrustedCertificateIndex.java
@@ -0,0 +1,212 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import java.security.PublicKey;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * Indexes {@code TrustAnchor} instances so they can be found in O(1)
+ * time instead of O(N).
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public final class TrustedCertificateIndex {
+
+    private final Map<X500Principal, List<TrustAnchor>> subjectToTrustAnchors
+            = new HashMap<X500Principal, List<TrustAnchor>>();
+
+    @libcore.api.CorePlatformApi
+    public TrustedCertificateIndex() {}
+
+    public TrustedCertificateIndex(Set<TrustAnchor> anchors) {
+        index(anchors);
+    }
+
+    private void index(Set<TrustAnchor> anchors) {
+        for (TrustAnchor anchor : anchors) {
+            index(anchor);
+        }
+    }
+
+    @libcore.api.CorePlatformApi
+    public TrustAnchor index(X509Certificate cert) {
+        TrustAnchor anchor = new TrustAnchor(cert, null);
+        index(anchor);
+        return anchor;
+    }
+
+    public void index(TrustAnchor anchor) {
+        X500Principal subject;
+        X509Certificate cert = anchor.getTrustedCert();
+        if (cert != null) {
+            subject = cert.getSubjectX500Principal();
+        } else {
+            subject = anchor.getCA();
+        }
+
+        synchronized (subjectToTrustAnchors) {
+            List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
+            if (anchors == null) {
+                anchors = new ArrayList<TrustAnchor>(1);
+                subjectToTrustAnchors.put(subject, anchors);
+            } else {
+                // Avoid indexing the same certificate multiple times
+                if (cert != null) {
+                    for (TrustAnchor entry : anchors) {
+                        if (cert.equals(entry.getTrustedCert())) {
+                            return;
+                        }
+                    }
+                }
+            }
+            anchors.add(anchor);
+        }
+    }
+
+    public void reset() {
+        synchronized (subjectToTrustAnchors) {
+            subjectToTrustAnchors.clear();
+        }
+    }
+
+    public void reset(Set<TrustAnchor> anchors) {
+        synchronized (subjectToTrustAnchors) {
+            reset();
+            index(anchors);
+        }
+    }
+
+    @libcore.api.CorePlatformApi
+    public TrustAnchor findByIssuerAndSignature(X509Certificate cert) {
+        X500Principal issuer = cert.getIssuerX500Principal();
+        synchronized (subjectToTrustAnchors) {
+            List<TrustAnchor> anchors = subjectToTrustAnchors.get(issuer);
+            if (anchors == null) {
+                return null;
+            }
+
+            for (TrustAnchor anchor : anchors) {
+                PublicKey publicKey;
+                try {
+                    X509Certificate caCert = anchor.getTrustedCert();
+                    if (caCert != null) {
+                        publicKey = caCert.getPublicKey();
+                    } else {
+                        publicKey = anchor.getCAPublicKey();
+                    }
+                    cert.verify(publicKey);
+                    return anchor;
+                } catch (Exception ignored) {
+                }
+            }
+        }
+        return null;
+    }
+
+    @libcore.api.CorePlatformApi
+    public TrustAnchor findBySubjectAndPublicKey(X509Certificate cert) {
+        X500Principal subject = cert.getSubjectX500Principal();
+        synchronized (subjectToTrustAnchors) {
+            List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
+            if (anchors == null) {
+                return null;
+            }
+            return findBySubjectAndPublicKey(cert, anchors);
+        }
+    }
+
+    private static TrustAnchor findBySubjectAndPublicKey(X509Certificate cert,
+                                                         Collection<TrustAnchor> anchors) {
+        PublicKey certPublicKey = cert.getPublicKey();
+        for (TrustAnchor anchor : anchors) {
+            PublicKey caPublicKey;
+            try {
+                X509Certificate caCert = anchor.getTrustedCert();
+                if (caCert != null) {
+                    caPublicKey = caCert.getPublicKey();
+                } else {
+                    caPublicKey = anchor.getCAPublicKey();
+                }
+                if (caPublicKey.equals(certPublicKey)) {
+                    return anchor;
+                } else {
+                    // PublicKey.equals is not required to compare keys across providers. Fall back
+                    // to checking using the encoded form.
+                    if ("X.509".equals(caPublicKey.getFormat())
+                            && "X.509".equals(certPublicKey.getFormat())) {
+                        byte[] caPublicKeyEncoded = caPublicKey.getEncoded();
+                        byte[] certPublicKeyEncoded = certPublicKey.getEncoded();
+                        if (certPublicKeyEncoded != null
+                                && caPublicKeyEncoded != null
+                                && Arrays.equals(caPublicKeyEncoded, certPublicKeyEncoded)) {
+                            return anchor;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                // can happen with unsupported public key types
+            }
+        }
+        return null;
+    }
+
+    @libcore.api.CorePlatformApi
+    public Set<TrustAnchor> findAllByIssuerAndSignature(X509Certificate cert) {
+        X500Principal issuer = cert.getIssuerX500Principal();
+        synchronized (subjectToTrustAnchors) {
+            List<TrustAnchor> anchors = subjectToTrustAnchors.get(issuer);
+            if (anchors == null) {
+                return Collections.<TrustAnchor>emptySet();
+            }
+
+            Set<TrustAnchor> result = new HashSet<TrustAnchor>();
+            for (TrustAnchor anchor : anchors) {
+                try {
+                    PublicKey publicKey;
+                    X509Certificate caCert = anchor.getTrustedCert();
+                    if (caCert != null) {
+                        publicKey = caCert.getPublicKey();
+                    } else {
+                        publicKey = anchor.getCAPublicKey();
+                    }
+                    if (publicKey == null) {
+                        continue;
+                    }
+                    cert.verify(publicKey);
+                    result.add(anchor);
+                } catch (Exception ignored) {
+                }
+            }
+            return result;
+        }
+    }
+
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/X509PublicKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/X509PublicKey.java
new file mode 100644
index 0000000..e1ea6e0
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/X509PublicKey.java
@@ -0,0 +1,88 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2013 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 com.android.org.conscrypt;
+
+import java.security.PublicKey;
+import java.util.Arrays;
+
+/**
+ * A simple but useless key class that holds X.509 public key information when
+ * the appropriate KeyFactory for the key algorithm is not available.
+ */
+final class X509PublicKey implements PublicKey {
+    private static final long serialVersionUID = -8610156854731664298L;
+
+    private final String algorithm;
+
+    private final byte[] encoded;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    X509PublicKey(String algorithm, byte[] encoded) {
+        this.algorithm = algorithm;
+        this.encoded = encoded;
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    @Override
+    public String getFormat() {
+        return "X.509";
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return encoded;
+    }
+
+    @Override
+    public String toString() {
+        return "X509PublicKey [algorithm=" + algorithm + ", encoded=" + Arrays.toString(encoded)
+                + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((algorithm == null) ? 0 : algorithm.hashCode());
+        result = prime * result + Arrays.hashCode(encoded);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        X509PublicKey other = (X509PublicKey) obj;
+        if (algorithm == null) {
+            if (other.algorithm != null)
+                return false;
+        } else if (!algorithm.equals(other.algorithm))
+            return false;
+        if (!Arrays.equals(encoded, other.encoded))
+            return false;
+        return true;
+    }
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTConstants.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTConstants.java
new file mode 100644
index 0000000..f25a414
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTConstants.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CTConstants {
+    public static final String X509_SCT_LIST_OID = "1.3.6.1.4.1.11129.2.4.2";
+    public static final String OCSP_SCT_LIST_OID = "1.3.6.1.4.1.11129.2.4.5";
+
+    public static final int VERSION_LENGTH = 1;
+    public static final int LOGID_LENGTH = 32;
+    public static final int TIMESTAMP_LENGTH = 8;
+    public static final int EXTENSIONS_LENGTH_BYTES = 2;
+
+    public static final int HASH_ALGORITHM_LENGTH = 1;
+    public static final int SIGNATURE_ALGORITHM_LENGTH = 1;
+    public static final int SIGNATURE_LENGTH_BYTES = 2;
+
+    public static final int SIGNATURE_TYPE_LENGTH = 1;
+    public static final int LOG_ENTRY_TYPE_LENGTH = 2;
+    public static final int CERTIFICATE_LENGTH_BYTES = 3;
+
+    public static final int SERIALIZED_SCT_LENGTH_BYTES = 2;
+    public static final int SCT_LIST_LENGTH_BYTES = 2;
+
+    public static final int ISSUER_KEY_HASH_LENGTH = 32;
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java
new file mode 100644
index 0000000..348f5cc
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogInfo.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.Arrays;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * Properties about a Certificate Transparency Log.
+ * This object stores information about a CT log, its public key, description and URL.
+ * It allows verification of SCTs against the log's public key.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CTLogInfo {
+    private final byte[] logId;
+    private final PublicKey publicKey;
+    private final String description;
+    private final String url;
+
+    public CTLogInfo(PublicKey publicKey, String description, String url) {
+        try {
+            this.logId = MessageDigest.getInstance("SHA-256")
+                .digest(publicKey.getEncoded());
+        } catch (NoSuchAlgorithmException e) {
+            // SHA-256 is guaranteed to be available
+            throw new RuntimeException(e);
+        }
+
+        this.publicKey = publicKey;
+        this.description = description;
+        this.url = url;
+    }
+
+    /**
+     * Get the log's ID, that is the SHA-256 hash of it's public key
+     */
+    public byte[] getID() {
+        return logId;
+    }
+
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof CTLogInfo)) {
+            return false;
+        }
+
+        CTLogInfo that = (CTLogInfo)other;
+        return
+            this.publicKey.equals(that.publicKey) &&
+            this.description.equals(that.description) &&
+            this.url.equals(that.url);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 1;
+        hash = hash * 31 + publicKey.hashCode();
+        hash = hash * 31 + description.hashCode();
+        hash = hash * 31 + url.hashCode();
+
+        return hash;
+    }
+
+    /**
+     * Verify the signature of a signed certificate timestamp for the given certificate entry
+     * against the log's public key.
+     *
+     * @return the result of the verification
+     */
+    public VerifiedSCT.Status verifySingleSCT(SignedCertificateTimestamp sct,
+                                              CertificateEntry entry) {
+        if (!Arrays.equals(sct.getLogID(), getID())) {
+            return VerifiedSCT.Status.UNKNOWN_LOG;
+        }
+
+        byte[] toVerify;
+        try {
+            toVerify = sct.encodeTBS(entry);
+        } catch (SerializationException e) {
+            return VerifiedSCT.Status.INVALID_SCT;
+        }
+
+        Signature signature;
+        try {
+            String algorithm = sct.getSignature().getAlgorithm();
+            signature = Signature.getInstance(algorithm);
+        } catch (NoSuchAlgorithmException e) {
+            return VerifiedSCT.Status.INVALID_SCT;
+        }
+
+        try {
+            signature.initVerify(publicKey);
+        } catch (InvalidKeyException e) {
+            return VerifiedSCT.Status.INVALID_SCT;
+        }
+
+        try {
+            signature.update(toVerify);
+            if (!signature.verify(sct.getSignature().getSignature())) {
+                return VerifiedSCT.Status.INVALID_SIGNATURE;
+            }
+            return VerifiedSCT.Status.VALID;
+        } catch (SignatureException e) {
+            // This only happens if the signature is not initialized,
+            // but we call initVerify just before, so it should never do
+            throw new RuntimeException(e);
+        }
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogStore.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogStore.java
new file mode 100644
index 0000000..0f6b715
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTLogStore.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public interface CTLogStore {
+    CTLogInfo getKnownLog(byte[] logId);
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTPolicy.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTPolicy.java
new file mode 100644
index 0000000..9057e7a
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTPolicy.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.security.cert.X509Certificate;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public interface CTPolicy {
+    boolean doesResultConformToPolicy(CTVerificationResult result, String hostname,
+            X509Certificate[] chain);
+}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTVerificationResult.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTVerificationResult.java
new file mode 100644
index 0000000..bfa1f59
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTVerificationResult.java
@@ -0,0 +1,49 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CTVerificationResult {
+    private final ArrayList<VerifiedSCT> validSCTs = new ArrayList<VerifiedSCT>();
+    private final ArrayList<VerifiedSCT> invalidSCTs = new ArrayList<VerifiedSCT>();
+
+    public void add(VerifiedSCT result) {
+        if (result.status == VerifiedSCT.Status.VALID) {
+            validSCTs.add(result);
+        } else {
+            invalidSCTs.add(result);
+        }
+    }
+
+    public List<VerifiedSCT> getValidSCTs() {
+        return Collections.unmodifiableList(validSCTs);
+    }
+
+    public List<VerifiedSCT> getInvalidSCTs() {
+        return Collections.unmodifiableList(invalidSCTs);
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTVerifier.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTVerifier.java
new file mode 100644
index 0000000..4f2d9b8
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CTVerifier.java
@@ -0,0 +1,261 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import com.android.org.conscrypt.Internal;
+import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.OpenSSLX509Certificate;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CTVerifier {
+    private final CTLogStore store;
+
+    public CTVerifier(CTLogStore store) {
+        this.store = store;
+    }
+
+    public CTVerificationResult verifySignedCertificateTimestamps(List<X509Certificate> chain,
+            byte[] tlsData, byte[] ocspData) throws CertificateEncodingException {
+        OpenSSLX509Certificate[] certs = new OpenSSLX509Certificate[chain.size()];
+        int i = 0;
+        for(X509Certificate cert : chain) {
+            certs[i++] = OpenSSLX509Certificate.fromCertificate(cert);
+        }
+        return verifySignedCertificateTimestamps(certs, tlsData, ocspData);
+    }
+
+    /**
+     * Verify a certificate chain for transparency.
+     * Signed timestamps are extracted from the leaf certificate, TLS extension, and stapled ocsp
+     * response, and verified against the list of known logs.
+     * @throws IllegalArgumentException if the chain is empty
+     */
+    public CTVerificationResult verifySignedCertificateTimestamps(OpenSSLX509Certificate[] chain,
+            byte[] tlsData, byte[] ocspData) throws CertificateEncodingException {
+        if (chain.length == 0) {
+            throw new IllegalArgumentException("Chain of certificates mustn't be empty.");
+        }
+
+        OpenSSLX509Certificate leaf = chain[0];
+
+        CTVerificationResult result = new CTVerificationResult();
+        List<SignedCertificateTimestamp> tlsScts = getSCTsFromTLSExtension(tlsData);
+        verifyExternalSCTs(tlsScts, leaf, result);
+
+        List<SignedCertificateTimestamp> ocspScts = getSCTsFromOCSPResponse(ocspData, chain);
+        verifyExternalSCTs(ocspScts, leaf, result);
+
+        List<SignedCertificateTimestamp> embeddedScts = getSCTsFromX509Extension(chain[0]);
+        verifyEmbeddedSCTs(embeddedScts, chain, result);
+        return result;
+    }
+
+    /**
+     * Verify a list of SCTs which were embedded from an X509 certificate.
+     * The result of the verification for each sct is added to {@code result}.
+     */
+    private void verifyEmbeddedSCTs(List<SignedCertificateTimestamp> scts,
+                                    OpenSSLX509Certificate[] chain,
+                                    CTVerificationResult result) {
+        // Avoid creating the cert entry if we don't need it
+        if (scts.isEmpty()) {
+            return;
+        }
+
+        CertificateEntry precertEntry = null;
+        if (chain.length >= 2) {
+            OpenSSLX509Certificate leaf = chain[0];
+            OpenSSLX509Certificate issuer = chain[1];
+
+            try {
+                precertEntry = CertificateEntry.createForPrecertificate(leaf, issuer);
+            } catch (CertificateException e) {
+                // Leave precertEntry as null, we handle it just below
+            }
+        }
+
+        if (precertEntry == null) {
+            markSCTsAsInvalid(scts, result);
+            return;
+        }
+
+        for (SignedCertificateTimestamp sct: scts) {
+            VerifiedSCT.Status status = verifySingleSCT(sct, precertEntry);
+            result.add(new VerifiedSCT(sct, status));
+        }
+    }
+
+    /**
+     * Verify a list of SCTs which were not embedded in an X509 certificate, that is received
+     * through the TLS or OCSP extensions.
+     * The result of the verification for each sct is added to {@code result}.
+     */
+    private void verifyExternalSCTs(List<SignedCertificateTimestamp> scts,
+                                    OpenSSLX509Certificate leaf,
+                                    CTVerificationResult result) {
+        // Avoid creating the cert entry if we don't need it
+        if (scts.isEmpty()) {
+            return;
+        }
+
+        CertificateEntry x509Entry;
+        try {
+            x509Entry = CertificateEntry.createForX509Certificate(leaf);
+        } catch (CertificateException e) {
+            markSCTsAsInvalid(scts, result);
+            return;
+        }
+
+        for (SignedCertificateTimestamp sct: scts) {
+            VerifiedSCT.Status status = verifySingleSCT(sct, x509Entry);
+            result.add(new VerifiedSCT(sct, status));
+        }
+    }
+
+    /**
+     * Verify a single SCT for the given Certificate Entry
+     */
+    private VerifiedSCT.Status verifySingleSCT(SignedCertificateTimestamp sct,
+                                                         CertificateEntry certEntry) {
+        CTLogInfo log = store.getKnownLog(sct.getLogID());
+        if (log == null) {
+            return VerifiedSCT.Status.UNKNOWN_LOG;
+        }
+
+        return log.verifySingleSCT(sct, certEntry);
+    }
+
+    /**
+     * Add every SCT in {@code scts} to {@code result} with INVALID_SCT as status
+     */
+    private void markSCTsAsInvalid(List<SignedCertificateTimestamp> scts,
+                                   CTVerificationResult result) {
+        for (SignedCertificateTimestamp sct: scts) {
+            result.add(new VerifiedSCT(sct, VerifiedSCT.Status.INVALID_SCT));
+        }
+    }
+
+    /**
+     * Parse an encoded SignedCertificateTimestampList into a list of SignedCertificateTimestamp
+     * instances, as described by RFC6962.
+     * Individual SCTs which fail to be parsed are skipped. If the data is null, or the encompassing
+     * list fails to be parsed, an empty list is returned.
+     * @param origin used to create the SignedCertificateTimestamp instances.
+     */
+    private List<SignedCertificateTimestamp> getSCTsFromSCTList(byte[] data,
+            SignedCertificateTimestamp.Origin origin) {
+        if (data == null) {
+            return Collections.emptyList();
+        }
+
+        byte[][] sctList;
+        try {
+            sctList = Serialization.readList(data, CTConstants.SCT_LIST_LENGTH_BYTES,
+                                             CTConstants.SERIALIZED_SCT_LENGTH_BYTES);
+        } catch (SerializationException e) {
+            return Collections.emptyList();
+        }
+
+        List<SignedCertificateTimestamp> scts = new ArrayList<SignedCertificateTimestamp>();
+        for (byte[] encodedSCT: sctList) {
+            try  {
+                SignedCertificateTimestamp sct = SignedCertificateTimestamp.decode(encodedSCT, origin);
+                scts.add(sct);
+            } catch (SerializationException e) {
+                // Ignore errors
+            }
+        }
+
+        return scts;
+    }
+
+    /**
+     * Extract a list of SignedCertificateTimestamp from a TLS "signed_certificate_timestamp"
+     * extension as described by RFC6962.
+     * Individual SCTs which fail to be parsed are skipped. If the data is null, or the encompassing
+     * list fails to be parsed, an empty list is returned.
+     * @param data contents of the TLS extension to be decoded
+     */
+    private List<SignedCertificateTimestamp> getSCTsFromTLSExtension(byte[] data) {
+        return getSCTsFromSCTList(data, SignedCertificateTimestamp.Origin.TLS_EXTENSION);
+    }
+
+    /**
+     * Extract a list of SignedCertificateTimestamp contained in an OCSP response.
+     * If the data is null, or parsing the OCSP response fails, an empty list is returned.
+     * Individual SCTs which fail to be parsed are skipped.
+     * @param data contents of the OCSP response
+     * @param chain certificate chain for which to get SCTs. Must contain at least the leaf and it's
+     *              issuer in order to identify the relevant SingleResponse from the OCSP response,
+     *              or an empty list is returned
+     */
+    private List<SignedCertificateTimestamp> getSCTsFromOCSPResponse(byte[] data,
+            OpenSSLX509Certificate[] chain) {
+        if (data == null || chain.length < 2) {
+            return Collections.emptyList();
+        }
+
+        byte[] extData = NativeCrypto.get_ocsp_single_extension(data, CTConstants.OCSP_SCT_LIST_OID,
+                chain[0].getContext(), chain[0],
+                chain[1].getContext(), chain[1]);
+        if (extData == null) {
+            return Collections.emptyList();
+        }
+
+        try {
+            return getSCTsFromSCTList(
+                    Serialization.readDEROctetString(
+                      Serialization.readDEROctetString(extData)),
+                    SignedCertificateTimestamp.Origin.OCSP_RESPONSE);
+        } catch (SerializationException e) {
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * Extract a list of SignedCertificateTimestamp embedded in an X509 certificate.
+     *
+     * If the certificate does not contain any SCT extension, or the encompassing encoded list fails
+     * to be parsed, an empty list is returned. Individual SCTs which fail to be parsed are ignored.
+     */
+    private List<SignedCertificateTimestamp> getSCTsFromX509Extension(OpenSSLX509Certificate leaf) {
+        byte[] extData = leaf.getExtensionValue(CTConstants.X509_SCT_LIST_OID);
+        if (extData == null) {
+            return Collections.emptyList();
+        }
+
+        try {
+            return getSCTsFromSCTList(
+                    Serialization.readDEROctetString(
+                      Serialization.readDEROctetString(extData)),
+                    SignedCertificateTimestamp.Origin.EMBEDDED);
+        } catch (SerializationException e) {
+            return Collections.emptyList();
+        }
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CertificateEntry.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CertificateEntry.java
new file mode 100644
index 0000000..69c9367
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/CertificateEntry.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.io.OutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import com.android.org.conscrypt.Internal;
+import com.android.org.conscrypt.OpenSSLX509Certificate;
+
+/**
+ * CertificateEntry structure.
+ * This structure describes part of the data which is signed over in SCTs.
+ * It is not defined by the RFC6962, but it is useful to have.
+ *
+ * It's definition would be :
+ * struct {
+ *     LogEntryType entry_type;
+ *     select(entry_type) {
+ *         case x509_entry: ASN.1Cert;
+ *         case precert_entry: PreCert;
+ *     } signed_entry;
+ * } CertificateEntry;
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CertificateEntry {
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum LogEntryType {
+        X509_ENTRY,
+        PRECERT_ENTRY
+    }
+
+    private final LogEntryType entryType;
+
+    // Only used when entryType is LOG_ENTRY_TYPE_PRECERT
+    private final byte[] issuerKeyHash;
+
+    /* If entryType == PRECERT_ENTRY, this is the encoded TBS of the precertificate.
+       If entryType == X509_ENTRY, this is the encoded leaf certificate. */
+    private final byte[] certificate;
+
+    private CertificateEntry(LogEntryType entryType, byte[] certificate, byte[] issuerKeyHash) {
+        if (entryType == LogEntryType.PRECERT_ENTRY && issuerKeyHash == null) {
+            throw new IllegalArgumentException("issuerKeyHash missing for precert entry.");
+        } else if (entryType == LogEntryType.X509_ENTRY && issuerKeyHash != null) {
+            throw new IllegalArgumentException("unexpected issuerKeyHash for X509 entry.");
+        }
+        
+        if (issuerKeyHash != null && issuerKeyHash.length != CTConstants.ISSUER_KEY_HASH_LENGTH) {
+            throw new IllegalArgumentException("issuerKeyHash must be 32 bytes long");
+        }
+
+        this.entryType = entryType;
+        this.issuerKeyHash = issuerKeyHash;
+        this.certificate = certificate;
+    }
+
+    /**
+     * @throws IllegalArgumentException if issuerKeyHash isn't 32 bytes
+     */
+    public static CertificateEntry createForPrecertificate(byte[] tbsCertificate, byte[] issuerKeyHash) {
+        return new CertificateEntry(LogEntryType.PRECERT_ENTRY, tbsCertificate, issuerKeyHash);
+    }
+
+    public static CertificateEntry createForPrecertificate(OpenSSLX509Certificate leaf,
+            OpenSSLX509Certificate issuer) throws CertificateException {
+        try {
+            if (!leaf.getNonCriticalExtensionOIDs().contains(CTConstants.X509_SCT_LIST_OID)) {
+                throw new CertificateException("Certificate does not contain embedded signed timestamps");
+            }
+
+            OpenSSLX509Certificate preCert = leaf.withDeletedExtension(CTConstants.X509_SCT_LIST_OID);
+            byte[] tbs = preCert.getTBSCertificate();
+
+            byte[] issuerKey = issuer.getPublicKey().getEncoded();
+            MessageDigest md = MessageDigest.getInstance("SHA-256");
+            md.update(issuerKey);
+            byte[] issuerKeyHash = md.digest();
+
+            return createForPrecertificate(tbs, issuerKeyHash);
+        } catch (NoSuchAlgorithmException e) {
+            // SHA-256 is guaranteed to be available
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static CertificateEntry createForX509Certificate(byte[] x509Certificate) {
+        return new CertificateEntry(LogEntryType.X509_ENTRY, x509Certificate, null);
+    }
+
+    public static CertificateEntry createForX509Certificate(X509Certificate cert)
+            throws CertificateEncodingException {
+        return createForX509Certificate(cert.getEncoded());
+    }
+
+    public LogEntryType getEntryType() {
+        return entryType;
+    }
+    public byte[] getCertificate() {
+        return certificate;
+    }
+    public byte[] getIssuerKeyHash() {
+        return issuerKeyHash;
+    }
+
+    /**
+     * TLS encode the CertificateEntry structure.
+     */
+    public void encode(OutputStream output) throws SerializationException {
+        Serialization.writeNumber(output, entryType.ordinal(), CTConstants.LOG_ENTRY_TYPE_LENGTH);
+        if (entryType == LogEntryType.PRECERT_ENTRY) {
+            Serialization.writeFixedBytes(output, issuerKeyHash);
+        }
+        Serialization.writeVariableBytes(output, certificate, CTConstants.CERTIFICATE_LENGTH_BYTES);
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/DigitallySigned.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/DigitallySigned.java
new file mode 100644
index 0000000..ea62666
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/DigitallySigned.java
@@ -0,0 +1,136 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * DigitallySigned structure, as defined by RFC5246 Section 4.7.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class DigitallySigned {
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum HashAlgorithm {
+        NONE,
+        MD5,
+        SHA1,
+        SHA224,
+        SHA256,
+        SHA384,
+        SHA512;
+
+        private static HashAlgorithm[] values = values();
+        public static HashAlgorithm valueOf(int ord) {
+            try {
+                return values[ord];
+            } catch (IndexOutOfBoundsException e) {
+                throw new IllegalArgumentException("Invalid hash algorithm " + ord, e);
+            }
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum SignatureAlgorithm {
+        ANONYMOUS,
+        RSA,
+        DSA,
+        ECDSA;
+
+        private static SignatureAlgorithm[] values = values();
+        public static SignatureAlgorithm valueOf(int ord) {
+            try {
+                return values[ord];
+            } catch (IndexOutOfBoundsException e) {
+                throw new IllegalArgumentException("Invalid signature algorithm " + ord, e);
+            }
+        }
+    }
+
+    private final HashAlgorithm hashAlgorithm;
+    private final SignatureAlgorithm signatureAlgorithm;
+    private final byte[] signature;
+
+    public DigitallySigned(HashAlgorithm hashAlgorithm,
+                           SignatureAlgorithm signatureAlgorithm,
+                           byte[] signature) {
+        this.hashAlgorithm = hashAlgorithm;
+        this.signatureAlgorithm = signatureAlgorithm;
+        this.signature = signature;
+    }
+
+    public DigitallySigned(int hashAlgorithm,
+                           int signatureAlgorithm,
+                           byte[] signature) {
+        this(
+            HashAlgorithm.valueOf(hashAlgorithm),
+            SignatureAlgorithm.valueOf(signatureAlgorithm),
+            signature
+        );
+    }
+
+    public HashAlgorithm getHashAlgorithm() {
+        return hashAlgorithm;
+    }
+    public SignatureAlgorithm getSignatureAlgorithm() {
+        return signatureAlgorithm;
+    }
+    public byte[] getSignature() {
+        return signature;
+    }
+
+    /**
+     * Get the name of the hash and signature combination.
+     * The result can be used to as the argument to {@link java.security.Signature#getInstance}.
+     */
+    public String getAlgorithm() {
+        return String.format("%swith%s", hashAlgorithm, signatureAlgorithm);
+    }
+
+    /**
+     * Decode a TLS encoded DigitallySigned structure.
+     */
+    public static DigitallySigned decode(InputStream input)
+        throws SerializationException {
+        try {
+            return new DigitallySigned(
+                Serialization.readNumber(input, CTConstants.HASH_ALGORITHM_LENGTH),
+                Serialization.readNumber(input, CTConstants.SIGNATURE_ALGORITHM_LENGTH),
+                Serialization.readVariableBytes(input, CTConstants.SIGNATURE_LENGTH_BYTES)
+            );
+        } catch (IllegalArgumentException e) {
+            throw new SerializationException(e);
+        }
+    }
+
+    /**
+     * Decode a TLS encoded DigitallySigned structure.
+     */
+    public static DigitallySigned decode(byte[] input)
+            throws SerializationException {
+        return decode(new ByteArrayInputStream(input));
+    }
+}
+
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/Serialization.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/Serialization.java
new file mode 100644
index 0000000..4b54dbf
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/Serialization.java
@@ -0,0 +1,243 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class Serialization {
+    private Serialization() {}
+
+    private static final int DER_TAG_MASK = 0x3f;
+    private static final int DER_TAG_OCTET_STRING = 0x4;
+    private static final int DER_LENGTH_LONG_FORM_FLAG = 0x80;
+
+    public static byte[] readDEROctetString(byte[] input)
+            throws SerializationException {
+        return readDEROctetString(new ByteArrayInputStream(input));
+    }
+
+    public static byte[] readDEROctetString(InputStream input)
+            throws SerializationException {
+        int tag = readByte(input) & DER_TAG_MASK;
+        if (tag != DER_TAG_OCTET_STRING) {
+            throw new SerializationException("Wrong DER tag, expected OCTET STRING, got " + tag);
+        }
+        int length;
+        int width = readNumber(input, 1);
+        if ((width & DER_LENGTH_LONG_FORM_FLAG) != 0) {
+            length = readNumber(input, width & ~DER_LENGTH_LONG_FORM_FLAG);
+        } else {
+            length = width;
+        }
+
+        return readFixedBytes(input, length);
+    }
+
+    public static byte[][] readList(byte[] input, int listWidth, int elemWidth)
+            throws SerializationException {
+        return readList(new ByteArrayInputStream(input), listWidth, elemWidth);
+    }
+
+    /**
+     * Read a variable length vector of variable sized elements as described by RFC5246 section 4.3.
+     * The vector is prefixed by its total length, in bytes and in big endian format,
+     * so is each element contained in the vector.
+     * @param listWidth the width of the vector's length field, in bytes.
+     * @param elemWidth the width of each element's length field, in bytes.
+     * @throws SerializationException if EOF is encountered.
+     */
+    public static byte[][] readList(InputStream input, int listWidth, int elemWidth)
+            throws SerializationException {
+        ArrayList<byte[]> result = new ArrayList<byte[]>();
+        byte[] data = readVariableBytes(input, listWidth);
+        input = new ByteArrayInputStream(data);
+        try {
+            while (input.available() > 0) {
+                result.add(readVariableBytes(input, elemWidth));
+            }
+        } catch (IOException e) {
+            throw new SerializationException(e);
+        }
+        return result.toArray(new byte[result.size()][]);
+    }
+
+    /**
+     * Read a length-prefixed sequence of bytes.
+     * The length must be encoded in big endian format.
+     * @param width the width of the length prefix, in bytes.
+     * @throws SerializationException if EOF is encountered, or if {@code width} is negative or
+     * greater than 4
+     */
+    public static byte[] readVariableBytes(InputStream input, int width)
+            throws SerializationException {
+        int length = readNumber(input, width);
+        return readFixedBytes(input, length);
+    }
+
+    /**
+     * Read a fixed number of bytes from the input stream.
+     * @param length the number of bytes to read.
+     * @throws SerializationException if EOF is encountered.
+     */
+    public static byte[] readFixedBytes(InputStream input, int length)
+            throws SerializationException {
+        try {
+            if (length < 0) {
+                throw new SerializationException("Negative length: " + length);
+            }
+
+            byte[] data = new byte[length];
+            int count = input.read(data);
+            if (count < length) {
+                throw new SerializationException("Premature end of input, expected " + length +
+                                                 " bytes, only read " + count);
+            }
+            return data;
+        } catch (IOException e) {
+            throw new SerializationException(e);
+        }
+    }
+
+    /**
+     * Read a number in big endian format from the input stream.
+     * This methods only supports a width of up to 4 bytes.
+     * @param width the width of the number, in bytes.
+     * @throws SerializationException if EOF is encountered, or if {@code width} is negative or
+     * greater than 4
+     */
+    public static int readNumber(InputStream input, int width) throws SerializationException {
+        if (width > 4 || width < 0) {
+            throw new SerializationException("Invalid width: " + width);
+        }
+
+        int result = 0;
+        for (int i = 0; i < width; i++) {
+            result = (result << 8) | (readByte(input) & 0xFF);
+        }
+
+        return result;
+    }
+
+    /**
+     * Read a number in big endian format from the input stream.
+     * This methods supports a width of up to 8 bytes.
+     * @param width the width of the number, in bytes.
+     * @throws SerializationException if EOF is encountered.
+     * @throws IllegalArgumentException if {@code width} is negative or greater than 8
+     */
+    public static long readLong(InputStream input, int width) throws SerializationException {
+        if (width > 8 || width < 0) {
+            throw new IllegalArgumentException("Invalid width: " + width);
+        }
+
+        long result = 0;
+        for (int i = 0; i < width; i++) {
+            result = (result << 8) | (readByte(input) & 0xFF);
+        }
+
+        return result;
+    }
+
+    /**
+     * Read a single byte from the input stream.
+     * @throws SerializationException if EOF is encountered.
+     */
+    public static byte readByte(InputStream input) throws SerializationException {
+        try {
+            int b = input.read();
+            if (b == -1) {
+                throw new SerializationException("Premature end of input, could not read byte.");
+            }
+            return (byte)b;
+        } catch (IOException e) {
+            throw new SerializationException(e);
+        }
+    }
+
+    /**
+     * Write length prefixed sequence of bytes to the ouput stream.
+     * The length prefix is encoded in big endian order.
+     * @param data the data to be written.
+     * @param width the width of the length prefix, in bytes.
+     * @throws SerializationException if the length of {@code data} is too large to fit in
+     * {@code width} bytes or {@code width} is negative.
+     */
+    public static void writeVariableBytes(OutputStream output, byte[] data, int width)
+            throws SerializationException {
+        writeNumber(output, data.length, width);
+        writeFixedBytes(output, data);
+    }
+
+    /**
+     * Write a fixed number sequence of bytes to the ouput stream.
+     * @param data the data to be written.
+     */
+    public static void writeFixedBytes(OutputStream output, byte[] data)
+            throws SerializationException {
+        try {
+            output.write(data);
+        } catch (IOException e) {
+            throw new SerializationException(e);
+        }
+    }
+
+    /**
+     * Write a number to the output stream.
+     * The number is encoded in big endian order.
+     * @param value the value to be written.
+     * @param width the width of the encoded number, in bytes
+     * @throws SerializationException if the number is too large to fit in {@code width} bytes or
+     * {@code width} is negative.
+     */
+    public static void writeNumber(OutputStream output, long value, int width)
+            throws SerializationException {
+        if (width < 0) {
+            throw new SerializationException("Negative width: " + width);
+        }
+        if (width < 8 && value >= (1L << (8 * width))) {
+            throw new SerializationException(
+                    "Number too large, " + value + " does not fit in " + width + " bytes");
+        }
+
+        try {
+            while (width > 0) {
+                long shift = (width - 1) * 8L;
+                // Java behaves weirdly if shifting by more than the variable's size
+                if (shift < Long.SIZE) {
+                    output.write((byte) ((value >> shift) & 0xFF));
+                } else {
+                    output.write(0);
+                }
+
+                width--;
+            }
+        } catch (IOException e) {
+            throw new SerializationException(e);
+        }
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/SerializationException.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/SerializationException.java
new file mode 100644
index 0000000..092f166
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/SerializationException.java
@@ -0,0 +1,42 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class SerializationException extends Exception {
+    public SerializationException() {
+    }
+
+    public SerializationException(String message) {
+        super(message);
+    }
+
+    public SerializationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public SerializationException(Throwable cause) {
+        super(cause);
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/SignedCertificateTimestamp.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/SignedCertificateTimestamp.java
new file mode 100644
index 0000000..218603b
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/SignedCertificateTimestamp.java
@@ -0,0 +1,147 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * SignedCertificateTimestamp structure, as defined by RFC6962 Section 3.2.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class SignedCertificateTimestamp {
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum Version {
+        V1
+    };
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum SignatureType {
+        CERTIFICATE_TIMESTAMP,
+        TREE_HASH
+    };
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum Origin {
+        EMBEDDED,
+        TLS_EXTENSION,
+        OCSP_RESPONSE
+    };
+
+    private final Version version;
+    private final byte[] logId;
+    private final long timestamp;
+    private final byte[] extensions;
+    private final DigitallySigned signature;
+
+    // origin is implied from the SCT's source and is not encoded in it,
+    // and affects the verification process.
+    private final Origin origin;
+
+    public SignedCertificateTimestamp(Version version, byte[] logId,
+                                      long timestamp, byte[] extensions,
+                                      DigitallySigned signature, Origin origin) {
+        this.version = version;
+        this.logId = logId;
+        this.timestamp = timestamp;
+        this.extensions = extensions;
+        this.signature = signature;
+        this.origin = origin;
+    }
+
+    public Version getVersion() {
+        return version;
+    }
+    public byte[] getLogID() {
+        return logId;
+    }
+    public long getTimestamp() {
+        return timestamp;
+    }
+    public byte[] getExtensions() {
+        return extensions;
+    }
+    public DigitallySigned getSignature() {
+        return signature;
+    }
+    public Origin getOrigin() {
+        return origin;
+    }
+
+    /**
+     * Decode a TLS encoded SignedCertificateTimestamp structure.
+     */
+    public static SignedCertificateTimestamp decode(InputStream input, Origin origin)
+            throws SerializationException {
+        int version = Serialization.readNumber(input, CTConstants.VERSION_LENGTH);
+        if (version != Version.V1.ordinal()) {
+            throw new SerializationException("Unsupported SCT version " + version);
+        }
+
+        return new SignedCertificateTimestamp(
+            Version.V1,
+            Serialization.readFixedBytes(input, CTConstants.LOGID_LENGTH),
+            Serialization.readLong(input, CTConstants.TIMESTAMP_LENGTH),
+            Serialization.readVariableBytes(input, CTConstants.EXTENSIONS_LENGTH_BYTES),
+            DigitallySigned.decode(input),
+            origin
+        );
+    }
+
+    /**
+     * Decode a TLS encoded SignedCertificateTimestamp structure.
+     */
+    public static SignedCertificateTimestamp decode(byte[] input, Origin origin)
+            throws SerializationException {
+        return decode(new ByteArrayInputStream(input), origin);
+    }
+
+    /**
+     * TLS encode the signed part of the SCT, as described by RFC6962 section 3.2.
+     */
+    public void encodeTBS(OutputStream output, CertificateEntry certEntry)
+            throws SerializationException {
+        Serialization.writeNumber(output, version.ordinal(), CTConstants.VERSION_LENGTH);
+        Serialization.writeNumber(output, SignatureType.CERTIFICATE_TIMESTAMP.ordinal(),
+                                          CTConstants.SIGNATURE_TYPE_LENGTH);
+        Serialization.writeNumber(output, timestamp, CTConstants.TIMESTAMP_LENGTH);
+        certEntry.encode(output);
+        Serialization.writeVariableBytes(output, extensions, CTConstants.EXTENSIONS_LENGTH_BYTES);
+    }
+
+    /**
+     * TLS encode the signed part of the SCT, as described by RFC6962 section 3.2.
+     */
+    public byte[] encodeTBS(CertificateEntry certEntry)
+            throws SerializationException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        encodeTBS(output, certEntry);
+        return output.toByteArray();
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ct/VerifiedSCT.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/VerifiedSCT.java
new file mode 100644
index 0000000..e68a98c
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/ct/VerifiedSCT.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import com.android.org.conscrypt.Internal;
+
+/**
+ * Verification result for a single SCT.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class VerifiedSCT {
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum Status {
+        VALID,
+        INVALID_SIGNATURE,
+        UNKNOWN_LOG,
+        INVALID_SCT
+    }
+
+    public final SignedCertificateTimestamp sct;
+    public final Status status;
+
+    public VerifiedSCT(SignedCertificateTimestamp sct, Status status) {
+        this.sct = sct;
+        this.status = status;
+    }
+}
+
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/io/IoUtils.java b/repackaged/common/src/main/java/com/android/org/conscrypt/io/IoUtils.java
new file mode 100644
index 0000000..84c3926
--- /dev/null
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/io/IoUtils.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.io;
+
+import java.io.Closeable;
+import java.io.InterruptedIOException;
+import java.net.Socket;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class IoUtils {
+    private IoUtils() {}
+
+    /**
+     * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
+     */
+    public static void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    /**
+     * Closes 'socket', ignoring any exceptions. Does nothing if 'socket' is null.
+     */
+    public static void closeQuietly(Socket socket) {
+        if (socket != null) {
+            try {
+                socket.close();
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    public static void throwInterruptedIoException() throws InterruptedIOException {
+        // This is typically thrown in response to an
+        // InterruptedException which does not leave the thread in an
+        // interrupted state, so explicitly interrupt here.
+        Thread.currentThread().interrupt();
+        // TODO: set InterruptedIOException.bytesTransferred
+        throw new InterruptedIOException();
+    }
+}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/CertPinManagerTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/CertPinManagerTest.java
new file mode 100644
index 0000000..3317765
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/CertPinManagerTest.java
@@ -0,0 +1,143 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.KeyStore;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.List;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class CertPinManagerTest {
+    private static boolean installedProvider;
+    private List<X509Certificate> expectedFullChain;
+    private X509Certificate[] chain;
+
+    @BeforeClass
+    public static void installConscrypt() {
+        installedProvider = TestUtils.installConscryptIfNotPresent();
+    }
+
+    @AfterClass
+    public static void removeConscrypt() {
+        if (installedProvider) {
+            Security.removeProvider(TestUtils.getConscryptProvider().getName());
+            installedProvider = false;
+        }
+    }
+
+    @Before
+    public void setUp() {
+        KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+        X509Certificate[] certs = (X509Certificate[]) pke.getCertificateChain();
+        expectedFullChain = Arrays.asList(certs);
+        // Leave the root out of the chain
+        chain = new X509Certificate[2];
+        chain[0] = certs[0];
+        chain[1] = certs[1];
+    }
+
+    @Test
+    public void testCertPinManagerCalled() throws Exception {
+        class TestCertPinManager implements CertPinManager {
+            public boolean called = false;
+            @Override
+            public void checkChainPinning(String hostname, List<X509Certificate> chain) {
+                called = true;
+            }
+        }
+        TestCertPinManager manager = new TestCertPinManager();
+        callCheckServerTrusted(null, manager);
+        assertTrue(manager.called);
+    }
+
+    @Test
+    public void testNullPinManager() throws Exception {
+        callCheckServerTrusted(null, null);
+    }
+
+    @Test
+    public void testFailure() throws Exception {
+        CertPinManager manager = new CertPinManager() {
+            @Override
+            public void checkChainPinning(String hostname, List<X509Certificate> chain)
+                    throws CertificateException {
+                throw new CertificateException("pin failure");
+            }
+        };
+        try {
+            callCheckServerTrusted(null, manager);
+            fail("Invalid chain was trusted");
+        } catch (CertificateException expected) {
+            assertEquals("pin failure", expected.getMessage());
+        }
+    }
+
+    @Test
+    public void testHostnameProvided() throws Exception {
+        final String expectedHostname = "example.com";
+        class TestCertPinManager implements CertPinManager {
+            public boolean hostnameMatched = false;
+            @Override
+            public void checkChainPinning(String hostname, List<X509Certificate> chain) {
+                hostnameMatched = expectedHostname.equals(hostname);
+            }
+        }
+        TestCertPinManager manager = new TestCertPinManager();
+        callCheckServerTrusted(expectedHostname, manager);
+        assertTrue(manager.hostnameMatched);
+    }
+
+    @Test
+    public void testFullChainProvided() throws Exception {
+        class TestCertPinManager implements CertPinManager {
+            public boolean fullChainProvided = false;
+            @Override
+            public void checkChainPinning(String hostname, List<X509Certificate> chain)
+                    throws CertificateException {
+                fullChainProvided = expectedFullChain.equals(chain);
+            }
+        }
+        TestCertPinManager manager = new TestCertPinManager();
+        callCheckServerTrusted(null, manager);
+        assertTrue(manager.fullChainProvided);
+    }
+
+    private void callCheckServerTrusted(String hostname, CertPinManager manager)
+            throws CertificateException {
+        TestUtils.assumeExtendedTrustManagerAvailable();
+        TrustManagerImpl tm = new TrustManagerImpl(TestKeyStore.getClient().keyStore, manager);
+        tm.checkServerTrusted(chain, "RSA", hostname);
+    }
+}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/ChainStrengthAnalyzerTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/ChainStrengthAnalyzerTest.java
new file mode 100644
index 0000000..fe968b9
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/ChainStrengthAnalyzerTest.java
@@ -0,0 +1,371 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class ChainStrengthAnalyzerTest {
+
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey rsa:2048 -sha256 -keyout k.pem -out good.pem
+    private static final String GOOD_RSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDYTCCAkmgAwIBAgIJAPFX8KGuEZcgMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV\n" +
+                            "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
+                            "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQ0MTBaFw0xMzEwMTUyMTQ0MTBa\n" +
+                            "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
+                            "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
+                            "ADCCAQoCggEBAM44hz3eTINuAIS9OYmg6DkUIj3MItn5dgbcMEdbXrhNpeWY93ho\n" +
+                            "WQFfsqcSSx28NzqKJmnX+cyinzIUfVde/qciP9P7fxRDokRsf34DJ6gXQplz6P2t\n" +
+                            "s4CWjYM+WXJrvEUgLUQ3CBV0CCrtYvG1B9wYsBdAdWkVaMxTvEt7aVxcvJYzp+KU\n" +
+                            "ME7HDg0PVxptvUExIskcqKVmW7i748AgBLhd0r1nFWLuH20d42Aowja0Wi19fWl2\n" +
+                            "SEMErDRjG8jIPUdSoOLPVLGTktEpex51xnAaZ+I7hy6zs55dq8ua/hE/v2cXIkiQ\n" +
+                            "ZXpWyvI/MaKEfeydLnNpa7J3GpH3KW93HQcCAwEAAaNQME4wHQYDVR0OBBYEFA0M\n" +
+                            "RI+3hIPCSpVVArisr3Y3/sheMB8GA1UdIwQYMBaAFA0MRI+3hIPCSpVVArisr3Y3\n" +
+                            "/sheMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFgUNyuy2qaJvgDO\n" +
+                            "plYudTrJR38O3id1B5oKOzgTEgRrfmHHfyloY4fL5gjAGNp7vdlDKSHC2Ebo23/X\n" +
+                            "Wg535MJ2296R855jaTMdkSE0+4ASpdmon1D007H0FhLyojlKVta3pqMAF1zsp0YF\n" +
+                            "Mf3V/rVMDxCOnbSnqAX0+1nW8Qm4Jgrr3AAMafZk6ypq0xuNQn+sUWuIWw3Xv5Jl\n" +
+                            "KehjnuKtMgVYkn2ItRNnUdhm2dQK+Phdb5Yg8WHXN/r9sZQdORg8FQS9TfQJmimB\n" +
+                            "CVYuqA9Dt0JJZPuO/Pd1yAxWP4NpxX1xr3lNQ5jrTO702QA3gOrscluULLzrYR50\n" +
+                            "FoAjeos=\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl ecparam -genkey -name prime256v1 -out eckey.pem && \
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey ec:eckey.pem -sha256 -keyout k.pem -out good.pem
+    private static final String GOOD_ECDSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIB1jCCAXugAwIBAgIJALhpH2C1lYeaMAoGCCqGSM49BAMCMEcxCzAJBgNVBAYT\n" +
+                            "AlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREwDwYD\n" +
+                            "VQQDDAh0ZXN0LmNvbTAeFw0xNDEwMjAyMjUyNDZaFw0xNTEwMjAyMjUyNDZaMEcx\n" +
+                            "CzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZp\n" +
+                            "bGxlMREwDwYDVQQDDAh0ZXN0LmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\n" +
+                            "BNR++2RWKGFUm+1KTLz7qxrJclPhVNM6gqInvAz2bLo7ENsD5KqN9BbmNvT4eg3y\n" +
+                            "u5i+00kiroKcm/35zhNFYamjUDBOMB0GA1UdDgQWBBRJmq9/dKkDW8n8mPzGzuo5\n" +
+                            "LcYUKjAfBgNVHSMEGDAWgBRJmq9/dKkDW8n8mPzGzuo5LcYUKjAMBgNVHRMEBTAD\n" +
+                            "AQH/MAoGCCqGSM49BAMCA0kAMEYCIQDgq5qudvY9zp3ZhVKEfMLbmwybiM15+wrC\n" +
+                            "xp6ipl+GZgIhAKbN/YfYoYlvr6z/xPrZfCZNLEaY/E01PqvD/d91Psa8\n" +
+                            "-----END CERTIFICATE-----\n";
+
+    //openssl dsaparam -genkey 1024 -out dsakey.pem && \
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey dsa:dsakey.pem -sha256 -keyout k.pem -out good.pem
+    private static final String GOOD_DSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDHTCCAtugAwIBAgIJAI4X+OBX9ap9MAsGCWCGSAFlAwQDAjBHMQswCQYDVQQG\n" +
+                            "EwJVUzERMA8GA1UECAwIVGVzdHNvdGExEjAQBgNVBAcMCVRlc3R2aWxsZTERMA8G\n" +
+                            "A1UEAwwIdGVzdC5jb20wHhcNMTQwOTAyMjA1MjUwWhcNMTUwOTAyMjA1MjUwWjBH\n" +
+                            "MQswCQYDVQQGEwJVUzERMA8GA1UECAwIVGVzdHNvdGExEjAQBgNVBAcMCVRlc3R2\n" +
+                            "aWxsZTERMA8GA1UEAwwIdGVzdC5jb20wggG2MIIBKwYHKoZIzjgEATCCAR4CgYEA\n" +
+                            "2QAjoImNX+oSkLdHPDdAzRrbdGdp665OyVBORfdnQeUHbi4WDElqUefTvIWYoDpC\n" +
+                            "Dvio284lhTSwXs8H2LKW3xV3AChzaNmPbGwWd4x8zxrE0OSQ+nXgbnBdhlUNUHpa\n" +
+                            "AnuuD31eMIDRN6o9WJ7DgksL8aEDO9DRuKUI4TNJKtECFQCB4+ccG9JUCoRh/bnb\n" +
+                            "X3cw3BV55wKBgHTmAcAt9Yu6vPdxX6NyzBMwb11kdt/3f0111WCI8nJl/+9mpRDd\n" +
+                            "snuPJUzsT00/JMH+puEN2fgOq7QxlCHtgNhX+WUtRE+QFjgvqilM+o+YEWEzeLfp\n" +
+                            "kWu/VfM6fV1B3jjmMsie1VNuitVVV1WOE7Pw0rq8m/yXQ5xft0ylhmLSA4GEAAKB\n" +
+                            "gH2Q6/2aSPh2b+ePFTLQc20EI6oU6xcyDPKfTsSYH0nUGpr4/k02spVOpHvtUe8e\n" +
+                            "1TVS0U30bzdC3bIz2fSUmeU4Kqde4IoZZ3SKjxD0jUKU4/hGuPSAMDEZfPKQIcpj\n" +
+                            "UEiqYo+r1ER2u3LdSOqu5ZkYNgT4/C7tr6+NIg1Y4sNuo1AwTjAdBgNVHQ4EFgQU\n" +
+                            "PfxTb9tJ6gh4KgFCR6q4Hng1P1AwHwYDVR0jBBgwFoAUPfxTb9tJ6gh4KgFCR6q4\n" +
+                            "Hng1P1AwDAYDVR0TBAUwAwEB/zALBglghkgBZQMEAwIDLwAwLAIUNgv+keqfh+sd\n" +
+                            "6xqIy6O1QFmjCsMCFB+MYu4K4+BrgPrrMVOnHB4MFHHo\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey rsa:2048 -md2 -keyout k.pem -out md2.pem
+    private static final String MD2_RSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDuzCCAqOgAwIBAgIJAPgJ74B13cElMA0GCSqGSIb3DQEBAgUAMEcxCzAJBgNV\n" +
+                            "BAYTAlVTMREwDwYDVQQIEwhUZXN0c290YTESMBAGA1UEBxMJVGVzdHZpbGxlMREw\n" +
+                            "DwYDVQQDEwh0ZXN0LmNvbTAeFw0xNDA5MDUwMTMwMDZaFw0xNTA5MDUwMTMwMDZa\n" +
+                            "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhUZXN0c290YTESMBAGA1UEBxMJVGVz\n" +
+                            "dHZpbGxlMREwDwYDVQQDEwh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
+                            "ADCCAQoCggEBAMHoaqm+IagQsnbI5fg1shbV4o4RMuxdOdqq35+FUuyGHRm2iUwu\n" +
+                            "0KVIX35ZGpzzfbpsOMFSy5XoRdgdG/6zEpYXTNzjGWtZQ/51cwMAVxDFAsrL7bZz\n" +
+                            "9mMEbccXOBS6P4mCAVBQmPfjf6YEP9XUFSY4FeD/sfoIwvutQDbkiUKjhUnQzkSl\n" +
+                            "JwnIURUqJOonzBVQV+slypYC9GMrXBT+gVq3QaQSkBwQHHr3SAhZfr8nKoxWlPUy\n" +
+                            "l/uliZw9LlctlqRegzGo9m1JHHft9E4mqN4DsVfHl/43XE9DVzZwFZlJ2iJ0X2yL\n" +
+                            "VXvKPTwZucdXkhl3oW6NHT/u02P9EnSTbEUCAwEAAaOBqTCBpjAdBgNVHQ4EFgQU\n" +
+                            "q1g42h7XKGGPlPbgAmmWvlAC2kMwdwYDVR0jBHAwboAUq1g42h7XKGGPlPbgAmmW\n" +
+                            "vlAC2kOhS6RJMEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhUZXN0c290YTESMBAG\n" +
+                            "A1UEBxMJVGVzdHZpbGxlMREwDwYDVQQDEwh0ZXN0LmNvbYIJAPgJ74B13cElMAwG\n" +
+                            "A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQECBQADggEBAIz1S5LVYRrmRAKfEaXf0Ja8\n" +
+                            "XyxGoE8BlM2WWHQoUO6HX+ixJBFueJT6kFJCH4NPKIZdTmhtKKOKBqJeHKiRom2L\n" +
+                            "a+p7GEGondaO/Q+8dqx+S7LUI22CaOss72DHoGFqES37KCs9P8G1gu/5GrQVgfV/\n" +
+                            "/UjESMF5/fQuFncgWfn5c6E5z7PRuYOLw3Clym1GbLUwldGeAeVqT4kcIgIKA3Rd\n" +
+                            "NqMum8A2TrJlrmtxG4OlkKdpKKjPRhYPYLtPXi/g0p8heJ8/YZSwXGQHrqqOND1F\n" +
+                            "fkc4rWxUev50cXXJ4qI8EM0zi3HpBqsqV6JgR8+VMA6MMxPQAWmGbBoztKv1r8U=\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey rsa:2048 -md4 -keyout k.pem -out md4.pem
+    private static final String MD4_RSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDYTCCAkmgAwIBAgIJAO2CvPpNFLqwMA0GCSqGSIb3DQEBAwUAMEcxCzAJBgNV\n" +
+                            "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
+                            "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xNDA5MDQyMjI1MzNaFw0xNTA5MDQyMjI1MzNa\n" +
+                            "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
+                            "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
+                            "ADCCAQoCggEBAOQHeENDnuCN08gW/CgIcIYZlD8qgHIc/QgUaHkxbMNBomiOgD8Z\n" +
+                            "D1JGtrW6ucbdD66L3Zd5gAfqgGbJ8ySrVFpgXbSpVb6C0wulPZRrm9ll4sZ5BYvg\n" +
+                            "zgFhY0TlrizaupZMV+XM3dce/EOYGnrqxWr6jOS7cX3D5Vb9NVE6g+GIW6XKw51Z\n" +
+                            "qD+GxxZ2As0lYaZ3vc/+EbiTs/UuIUTsSQvctRkvc83e2vAPtWHX+9ztOLmpSRUP\n" +
+                            "8xpganKg5JrfKlXlMXdhJipnOPcYLRMf+UD/7s13TyiQ8Qgt1/h8nirkP8mHYreM\n" +
+                            "WenY9Sqrp0FPgGTZbkSnL127mUcWiq+CyasCAwEAAaNQME4wHQYDVR0OBBYEFPSg\n" +
+                            "PNT/OJ5IrgrbA7Y0kNgqMp2uMB8GA1UdIwQYMBaAFPSgPNT/OJ5IrgrbA7Y0kNgq\n" +
+                            "Mp2uMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEDBQADggEBADg6acU5eqHUDjvG\n" +
+                            "M6L+2gMVNiTczlYItLqoibYZW88wzgxpptGKFlWzdl11TIjUaIYqZktfLAWC3Oun\n" +
+                            "C564mYPZfaIJEDKNMqcVPiZa9g/8dbctmOxAAvOGdXl+5uk5xOrAsmab7/NH+ksA\n" +
+                            "YRpcZntUzbqH33GcMP3CG2i8TM0xM3ZjKch+79asBD/vZmNK1BhsHy3LAE2H2HeA\n" +
+                            "k+YDvaBU2yKb0RuZvUmfiySiIjyLtX9JagtHVpcnCZ6pXgCuBy60nGSeP5GQ024x\n" +
+                            "GdyN37tmX7gvcazx1+uBlGtw07Uydua4868v/kgu/Ll2zY37CIY6OFi1G0mdk2Xs\n" +
+                            "28zzK8s=\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey rsa:2048 -md5 -keyout k.pem -out md5.pem
+    private static final String MD5_RSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDYTCCAkmgAwIBAgIJAJsffMf2cyx0MA0GCSqGSIb3DQEBBAUAMEcxCzAJBgNV\n" +
+                            "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
+                            "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQzMzZaFw0xMzEwMTUyMTQzMzZa\n" +
+                            "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
+                            "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
+                            "ADCCAQoCggEBAOJyiUwgf/VsdbTTdx6dsb742adeBFBY1FpSWCeQW/JVtdMephbK\n" +
+                            "AA00nu8Xq3dNx9bp8AqvzeyHi/RBsZOtb2eAsOXE3RbFy28ehDTHdG34fRQNT6kp\n" +
+                            "RUHw8wrUGovMVqS8j+iW8HfAy3sjArje0ygz2NIETlNQbEOifAJtY+AEfZwZE0/0\n" +
+                            "IMVP4hwTmIgyReJBDmAx31clwsWZSPar9x+WQfeJ3rfy5LBCtf3RUbdgnvynBHFk\n" +
+                            "FjucwoqgOOXviCWxIa0F+ZAmZJBj5+pLN/V92RXOu0c2fR3Mf68J67OJ+K4ueo1N\n" +
+                            "nBhRsulWMmGqIVjYOZQxiNzWYcOVXj3DTRMCAwEAAaNQME4wHQYDVR0OBBYEFJbY\n" +
+                            "TU06RuJaiMBs2vzx5y0MbaQOMB8GA1UdIwQYMBaAFJbYTU06RuJaiMBs2vzx5y0M\n" +
+                            "baQOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBAFEky0jLTmKefDVX\n" +
+                            "8O84KoupmQ2qQQBaQF3F5GEuhi0qJRwnmsWkCmsxPP55S67WDFp3JH+LX14UxL4T\n" +
+                            "fbG2CXHt/BF1yU3Z8JBwx3bDmfUnUOAFkO3nmByb11FyZTHMzq4jp03DexWREv4q\n" +
+                            "Ai5+5Xb56VECgCH/hnGqhQeFGhlZUcSXobVhAU+39L6azWELXxk1K4bpVxYFGn1N\n" +
+                            "uZ+dWmb6snPKDzG6J5IIX8QIs6G8H6ptj+QNoU/qTcZEnuzMJxpqMsyq10AA+bY/\n" +
+                            "VAYyXeZm3XZrtqYosDeiUdmcL0jjmyQtyOcAoVUQWj1EJuRjXg4BvI6xxRAIPWYT\n" +
+                            "EDeWHJE=\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey rsa:2048 -sha1 -keyout k.pem -out md5.pem
+    private static final String SHA1_RSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDZDCCAkygAwIBAgIJALW5K4gErucTMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV\n" +
+                            "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
+                            "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xODA0MTIxOTM1MzlaFw0xOTA0MTIxOTM1Mzla\n" +
+                            "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
+                            "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
+                            "ADCCAQoCggEBAMAphayEftP2twO/FpfUoERx9Y2DyaSMqvLND5Ay6wDXuLMN6qWX\n" +
+                            "3ljtEJW3ZVYM2gEhRIXKKUYt0lyx5EuE0VxrNOVyncr8/SQUY2tYlCSB1LLeOzGB\n" +
+                            "sYvVzEon/FUeKlRmcgae9FdqDP/t1pCwVdSxIhYxGoPt+znsbrT2UFO7yBw2WDZa\n" +
+                            "P8pLP8VeryXWLyAjX2ezxBNVpxwPBsdssrMRqX2BvsZt9pVx87weBH8Mj1lnGJL2\n" +
+                            "4ekfUonSEgT6hhCJv8G6PPvXvV2XWmGzjh+CyaEncoODa5a16JHVmq/BNtK6o/OB\n" +
+                            "YNrne86kDCzpruA69JtSYAf9YM2TU8vy6GECAwEAAaNTMFEwHQYDVR0OBBYEFHFu\n" +
+                            "2+j9+gNDXIlvtDq7P7A6JYnZMB8GA1UdIwQYMBaAFHFu2+j9+gNDXIlvtDq7P7A6\n" +
+                            "JYnZMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALnB+IOCAuWU\n" +
+                            "BEC8AtPzQaBQh2MJhzIg+0HHOGldkMX6jRGRnySf31okZMr9FjLkUMEwyylZvFI1\n" +
+                            "fFIdq7a070XAH1u4k/Xx7xi7R0+sfnceaLrt1nvOyhEjitLzLT/+zblMrvY+PvpF\n" +
+                            "JkUNSKbd8XkSSMvV3U4bmkAZfP/LIJ8juSrNwzsfIu7IPBq+3yPFZpBR/UNH/NhP\n" +
+                            "/9OmD8bLwSer9xAcWFT3JVljtaHmL3D+mP/Q1n2lsb7VhrZ4XESLN8thWxWddRC7\n" +
+                            "/72ObwvnJIPGB4Knybv8qee02ZDZRKcjFp872FeIkpHMfG/G/kwQiNzvA6cmwTYQ\n" +
+                            "QeVc5iP8Lqo=\n" +
+                            "-----END CERTIFICATE-----";
+
+
+    //openssl ecparam -genkey -name prime256v1 -out eckey.pem && \
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey ec:eckey.pem -sha1 -keyout k.pem -out sha1.pem
+    private static final String SHA1_ECDSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIB1zCCAX2gAwIBAgIJAKS+GaTWit91MAkGByqGSM49BAEwRzELMAkGA1UEBhMC\n" +
+                            "VVMxETAPBgNVBAgMCFRlc3Rzb3RhMRIwEAYDVQQHDAlUZXN0dmlsbGUxETAPBgNV\n" +
+                            "BAMMCHRlc3QuY29tMB4XDTE4MDQxMjE5NDAyMloXDTE5MDQxMjE5NDAyMlowRzEL\n" +
+                            "MAkGA1UEBhMCVVMxETAPBgNVBAgMCFRlc3Rzb3RhMRIwEAYDVQQHDAlUZXN0dmls\n" +
+                            "bGUxETAPBgNVBAMMCHRlc3QuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\n" +
+                            "VYHDIpvFu7UBWsfF9G8L5V5Cj+wIGHXIUIYp/GVri9bCTZBkLMqcoNyYKWDKDQb5\n" +
+                            "sKuo/CCSo5+1dPSjy8gm8KNTMFEwHQYDVR0OBBYEFI8coJOBd83LFcwx7ypFc7F0\n" +
+                            "B7clMB8GA1UdIwQYMBaAFI8coJOBd83LFcwx7ypFc7F0B7clMA8GA1UdEwEB/wQF\n" +
+                            "MAMBAf8wCQYHKoZIzj0EAQNJADBGAiEAjXa+FcLuU4jRVf93c4vY8EmATcjFrb4h\n" +
+                            "bKrvFxXMUpkCIQCllGWVU3j8Np8DxX0MK2Af/5h8O4zlr9DvPUpCsggaQw==\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl dsaparam -out dsakey.pem -genkey 1024 && \
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey dsa:dsakey.pem -sha1 -keyout k.pem -out sha1.pem
+    private static final String SHA1_DSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIDHzCCAt2gAwIBAgIJAPO9edaSntPLMAkGByqGSM44BAMwRzELMAkGA1UEBhMC\n" +
+                            "VVMxETAPBgNVBAgMCFRlc3Rzb3RhMRIwEAYDVQQHDAlUZXN0dmlsbGUxETAPBgNV\n" +
+                            "BAMMCHRlc3QuY29tMB4XDTE4MDQxMjE5NTAyN1oXDTE5MDQxMjE5NTAyN1owRzEL\n" +
+                            "MAkGA1UEBhMCVVMxETAPBgNVBAgMCFRlc3Rzb3RhMRIwEAYDVQQHDAlUZXN0dmls\n" +
+                            "bGUxETAPBgNVBAMMCHRlc3QuY29tMIIBtzCCASwGByqGSM44BAEwggEfAoGBAMZy\n" +
+                            "BYuw9s+UFLnrErRwysU2dfcY0tv4b8FIi63JtF12kTborQkyxilNtDDtBVEA0mKE\n" +
+                            "13dvd8JQx2+d6LwHSiaaS2n2/XofVn61HmDNPns1zV8m9XvUX8Cqmz0+1dgyZx0Y\n" +
+                            "dP+eg2BjfhfX/6tXWXMd2t2+y3sJalLh9KeC/LftAhUA2RmeKHbNMj9pC9wOj8Yj\n" +
+                            "u239Q1ECgYEAhnfB/Z2S/lYc2c78PU2DcChXsj+Mp8ITUwTVg+G4+WvqGzX6FFzr\n" +
+                            "9/eTrn+rPLkKDJonHW/OZyVFK2mVQ/s5xE8Wn9YDUYkNPlJ/dFB+okmhZE8hDRwF\n" +
+                            "LsgtrLgJqpOEw54b37hyqdvk2vtHI+ANU+jZONRdsmWT9HZ0ryJGqY8DgYQAAoGA\n" +
+                            "U8tXEXYh4oCAGLG+S7aNI73LN+a/n0r1aSJM8XuNExZus/eaXCHqEreUi/SBXVEm\n" +
+                            "UJEXnsRwzLyErE24yBlQzLBoMbHqJnIOJRmxjrQ7xo9vivo53woIbxHSRdWlzfwW\n" +
+                            "14yR5dSVDEVI30TTT/zAoNIWvegHXO2LCeEZ/ilLPxCjUzBRMB0GA1UdDgQWBBQB\n" +
+                            "cKP86kuQ/GEG+n0NdJK7A9uBOTAfBgNVHSMEGDAWgBQBcKP86kuQ/GEG+n0NdJK7\n" +
+                            "A9uBOTAPBgNVHRMBAf8EBTADAQH/MAkGByqGSM44BAMDMQAwLgIVAIIMd1qgBuGf\n" +
+                            "zY7SmaNFYmeQV2qpAhUAkPFti47uD7JjdAEqJ/nFMhYcolQ=\n" +
+                            "-----END CERTIFICATE-----";
+
+
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey rsa:512 -sha256 -keyout k.pem -out short.pem
+    private static final String SHORT_RSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIB1zCCAYGgAwIBAgIJAOxaz9TreDNIMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV\n" +
+                            "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
+                            "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQzMjNaFw0xMzEwMTUyMTQzMjNa\n" +
+                            "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
+                            "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC\n" +
+                            "QQCoMgxK9HG0L+hXEht1mKq6ApN3+3lmIEVUcWQKL7EMmn9+L6rVSJyOAGwpTVG7\n" +
+                            "eZ5uulC0Lkm5/bzKFSrCf1jlAgMBAAGjUDBOMB0GA1UdDgQWBBTda66RZsgUvR4e\n" +
+                            "2RSsq65K1xcz0jAfBgNVHSMEGDAWgBTda66RZsgUvR4e2RSsq65K1xcz0jAMBgNV\n" +
+                            "HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EAZWYgoNDn6yEzcmWgsYnG3w2BT6fL\n" +
+                            "Npi0+APKWkwxnEJk1kgpdeSTMgaHAphQ8qksHnSgeBAJSs2ZCQMinVPgOg==\n" +
+                            "-----END CERTIFICATE-----";
+
+    //openssl dsaparam -genkey 768 -out dsakey.pem && \
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey dsa:dsakey.pem -sha256 -keyout k.pem -out short.pem
+    private static final String SHORT_DSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIICuDCCAnWgAwIBAgIJAMQeQVxVNTKRMAsGCWCGSAFlAwQDAjBHMQswCQYDVQQG\n" +
+                            "EwJVUzERMA8GA1UECAwIVGVzdHNvdGExEjAQBgNVBAcMCVRlc3R2aWxsZTERMA8G\n" +
+                            "A1UEAwwIdGVzdC5jb20wHhcNMTQwOTAyMjAzNjQ4WhcNMTUwOTAyMjAzNjQ4WjBH\n" +
+                            "MQswCQYDVQQGEwJVUzERMA8GA1UECAwIVGVzdHNvdGExEjAQBgNVBAcMCVRlc3R2\n" +
+                            "aWxsZTERMA8GA1UEAwwIdGVzdC5jb20wggFQMIHoBgcqhkjOOAQBMIHcAmEApVZC\n" +
+                            "vx5pcu5CjEv0n5M0PVxnX/4ZkJn8EAnkgn5P37KxDm7dIHcMw71Epd+l7hP4TLUV\n" +
+                            "etW9VOu1ybo+hOMr3IGqlaMVHxL5VWk6DGFjo5ZplF5QGQt+hqFYX8agruoFAhUA\n" +
+                            "xsTsmLlEe97rZm2UfNt51tXoQgECYA1dMDAfVUqfC06LJ0O5Q2RmjbkqCLfwiXvq\n" +
+                            "q0LVqxQJBVzmjbWoNRdmZpzhjOfMQ2bpQwTj+M4t2YPGifQTgumUolutWGEs7jxU\n" +
+                            "HcybdA8/3fqubZ/pEKrz1FhjIReuJgNjAAJgEWAocKA/8Q7pFQ7tkJDUTctU7ZUN\n" +
+                            "O9eUqghBkJAaHhjq8GJ/UIoPuS8PCz19/xDZICMhbKpobi+z/sy3atZLtcrrUhN1\n" +
+                            "XBgEPD6aWSP3qEBzz2a6MqL6RegDL3ldrRMjo1AwTjAdBgNVHQ4EFgQUk7IR6KN+\n" +
+                            "Lb8ZlDs4v1pKtmQans0wHwYDVR0jBBgwFoAUk7IR6KN+Lb8ZlDs4v1pKtmQans0w\n" +
+                            "DAYDVR0TBAUwAwEB/zALBglghkgBZQMEAwIDMAAwLQIUG9is/MhJ0qXggCtPiOdH\n" +
+                            "UZSNrCgCFQDBb443MntlcWrx5gV7YRd52k0Yug==\n" +
+                            "-----END CERTIFICATE-----";
+
+    //ecparam -genkey -name secp128r1 -out eckey.pem && \
+    //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
+    //-newkey ec:eckey.pem -sha256 -keyout k.pem -out short.pem
+    private static final String SHORT_ECDSA_PEM = "" +
+                            "-----BEGIN CERTIFICATE-----\n" +
+                            "MIIBkTCCAVigAwIBAgIJAKogErAsYuahMAoGCCqGSM49BAMCMEcxCzAJBgNVBAYT\n" +
+                            "AlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREwDwYD\n" +
+                            "VQQDDAh0ZXN0LmNvbTAeFw0xNDA5MDIyMDQ1MjdaFw0xNTA5MDIyMDQ1MjdaMEcx\n" +
+                            "CzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZp\n" +
+                            "bGxlMREwDwYDVQQDDAh0ZXN0LmNvbTA2MBAGByqGSM49AgEGBSuBBAAcAyIABE9Z\n" +
+                            "bL28dyGE/sRmSUB0kqdsmkaKaC7gu+9A4CLDO5kJo1AwTjAdBgNVHQ4EFgQU7f+b\n" +
+                            "vrGRimukkorDkERufEFRaj0wHwYDVR0jBBgwFoAU7f+bvrGRimukkorDkERufEFR\n" +
+                            "aj0wDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgMnADAkAhBXRMkfHNexPXaqzJwT\n" +
+                            "9eAwAhAzX+1NE+FY0kk74wH83Cz0\n" +
+                            "-----END CERTIFICATE-----";
+
+
+    @Test
+    public void testMD2() throws Exception {
+        assertBad(MD2_RSA_PEM, "Weak hash check did not fail as expected");
+    }
+
+    @Test
+    public void testMD4() throws Exception {
+        assertBad(MD4_RSA_PEM, "Weak hash check did not fail as expected");
+    }
+
+    @Test
+    public void testMD5() throws Exception {
+        assertBad(MD5_RSA_PEM, "Weak hash check did not fail as expected");
+    }
+
+    @Test
+    public void testSHA1() throws Exception {
+        assertBad(SHA1_RSA_PEM, "Weak SHA1 RSA signature did not fail as expected");
+        assertBad(SHA1_ECDSA_PEM, "Weak SHA1 ECDSA signature did not fail as expected");
+        assertBad(SHA1_DSA_PEM, "Weak SHA1 DSA signature did not fail as expected");
+    }
+
+    @Test
+    public void testRsa512() throws Exception {
+        assertBad(SHORT_RSA_PEM, "Short RSA modulus check did not fail as expected");
+    }
+
+    @Test
+    public void testDsa768() throws Exception {
+        assertBad(SHORT_DSA_PEM, "Short DSA key check did not fail as expected");
+    }
+
+    @Test
+    public void testEcdsa128() throws Exception {
+        assertBad(SHORT_ECDSA_PEM, "Short EC key check did not fail as expected");
+    }
+
+    @Test
+    public void testGoodChain() throws Exception {
+        assertGood(GOOD_RSA_PEM);
+        assertGood(GOOD_DSA_PEM);
+        assertGood(GOOD_ECDSA_PEM);
+    }
+
+    private static void assertBad(String pem, String msg) throws Exception {
+        try {
+            check(createCert(pem));
+            fail(msg);
+        } catch (CertificateException expected) {
+        } catch (NoSuchAlgorithmException expected) {
+            // Some weak EC groups can no longer be parsed.
+        }
+    }
+
+    private static void assertGood(String pem) throws Exception {
+        check(createCert(pem));
+    }
+
+    private static void check(X509Certificate cert) throws Exception {
+        X509Certificate[] chain = {cert};
+        ChainStrengthAnalyzer.check(chain);
+    }
+
+    private static X509Certificate createCert(String pem) throws Exception {
+        CertificateFactory cf = CertificateFactory.getInstance("X509");
+        InputStream pemInput = new ByteArrayInputStream(pem.getBytes("UTF-8"));
+        return (X509Certificate) cf.generateCertificate(pemInput);
+    }
+}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java
new file mode 100644
index 0000000..40ca21e
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java
@@ -0,0 +1,486 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509TrustManager;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class TrustManagerImplTest {
+
+    /**
+     * Ensure that our non-standard behavior of learning to trust new
+     * intermediate CAs does not regress. http://b/3404902
+     */
+    @Test
+    public void testLearnIntermediate() throws Exception {
+        TestUtils.assumeExtendedTrustManagerAvailable();
+        // 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 };
+
+        // Normal behavior
+        assertValid(chain3,   trustManager(root));
+        assertValid(chain2,   trustManager(root));
+        assertInvalid(chain1, trustManager(root));
+        assertValid(chain3,   trustManager(intermediate));
+        assertValid(chain2,   trustManager(intermediate));
+        assertValid(chain1,   trustManager(intermediate));
+        assertValid(chain3,   trustManager(server));
+        assertValid(chain2,   trustManager(server));
+        assertValid(chain1,   trustManager(server));
+
+        // non-standard behavior
+        X509TrustManager tm = trustManager(root);
+        // fail on short chain with only root trusted
+        assertInvalid(chain1, tm);
+        // succeed on longer chain, learn intermediate
+        assertValid(chain2, tm);
+        // now we can validate the short chain
+        assertValid(chain1, tm);
+    }
+
+    // We should ignore duplicate cruft in the certificate chain
+    // See https://code.google.com/p/android/issues/detail?id=52295 http://b/8313312
+    @Test
+    public void testDuplicateInChain() throws Exception {
+        TestUtils.assumeExtendedTrustManagerAvailable();
+        // 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[] chain4 = new X509Certificate[] { server, intermediate,
+                                                           server, intermediate
+        };
+        assertValid(chain4, trustManager(root));
+    }
+
+    @Test
+    public void testGetFullChain() throws Exception {
+        TestUtils.assumeExtendedTrustManagerAvailable();
+        // 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", new FakeSSLSession("purple.com"));
+        assertEquals(Arrays.asList(chain3), certs);
+        certs = tmi.checkServerTrusted(chain1, "RSA", new FakeSSLSession("purple.com"));
+        assertEquals(Arrays.asList(chain3), certs);
+    }
+
+    @Test
+    public void testHttpsEndpointIdentification() throws Exception {
+        TestUtils.assumeExtendedTrustManagerAvailable();
+
+        KeyStore.PrivateKeyEntry pke = TestKeyStore.getServerHostname().getPrivateKey("RSA", "RSA");
+        X509Certificate[] chain = (X509Certificate[]) pke.getCertificateChain();
+        X509Certificate root = chain[2];
+        TrustManagerImpl tmi = (TrustManagerImpl) trustManager(root);
+
+        String goodHostname = TestKeyStore.CERT_HOSTNAME;
+        String badHostname = "definitelywrong.nopenopenope";
+
+        // The default hostname verifier on OpenJDK rejects all hostnames, so use our own
+        javax.net.ssl.HostnameVerifier oldDefault = HttpsURLConnection.getDefaultHostnameVerifier();
+        try {
+            HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+
+            SSLParameters params = new SSLParameters();
+
+            // Without endpoint identification this should pass despite the mismatched hostname
+            params.setEndpointIdentificationAlgorithm(null);
+
+            List<X509Certificate> certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+
+            // Turn on endpoint identification
+            params.setEndpointIdentificationAlgorithm("HTTPS");
+
+            try {
+                tmi.getTrustedChainForServer(chain, "RSA",
+                        new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params));
+            } catch (CertificateException expected) {
+            }
+
+            certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(goodHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+
+            // Override the global default hostname verifier with a Conscrypt-specific one that
+            // always passes.  Both scenarios should pass.
+            Conscrypt.setDefaultHostnameVerifier(new ConscryptHostnameVerifier() {
+                @Override
+                public boolean verify(String s, SSLSession sslSession) {
+                    return true;
+                }
+            });
+
+            certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+
+            certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(goodHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+
+            // Now set an instance-specific verifier on the trust manager.  The bad hostname should
+            // fail again.
+            Conscrypt.setHostnameVerifier(tmi, new TestHostnameVerifier());
+
+            try {
+                tmi.getTrustedChainForServer(chain, "RSA",
+                        new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params));
+            } catch (CertificateException expected) {
+            }
+
+            certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(goodHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+
+            // Remove the instance-specific verifier, and both should pass again.
+            Conscrypt.setHostnameVerifier(tmi, null);
+
+            certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+
+            certs = tmi.getTrustedChainForServer(chain, "RSA",
+                    new FakeSSLSocket(new FakeSSLSession(goodHostname, chain), params));
+            assertEquals(Arrays.asList(chain), certs);
+        } finally {
+            Conscrypt.setDefaultHostnameVerifier(null);
+            HttpsURLConnection.setDefaultHostnameVerifier(oldDefault);
+        }
+    }
+
+    private X509TrustManager trustManager(X509Certificate ca) throws Exception {
+        KeyStore keyStore = TestKeyStore.createKeyStore();
+        keyStore.setCertificateEntry("alias", ca);
+
+        return new TrustManagerImpl(keyStore);
+    }
+
+    private void assertValid(X509Certificate[] chain, X509TrustManager tm) throws Exception {
+        if (tm instanceof TrustManagerImpl) {
+            TrustManagerImpl tmi = (TrustManagerImpl) tm;
+            tmi.checkServerTrusted(chain, "RSA");
+        }
+        tm.checkServerTrusted(chain, "RSA");
+    }
+
+    private void assertInvalid(X509Certificate[] chain, X509TrustManager tm) {
+        try {
+            tm.checkClientTrusted(chain, "RSA");
+            fail();
+        } catch (CertificateException expected) {
+            // Expected.
+        }
+        try {
+            tm.checkServerTrusted(chain, "RSA");
+            fail();
+        } catch (CertificateException expected) {
+            // Expected.
+        }
+    }
+
+    private static class FakeSSLSession implements SSLSession {
+        private final String hostname;
+        private final X509Certificate[] peerCerts;
+
+        FakeSSLSession(String hostname) {
+            this.hostname = hostname;
+            peerCerts = null;
+        }
+
+        FakeSSLSession(String hostname, X509Certificate[] peerCerts) {
+            this.hostname = hostname;
+            this.peerCerts = peerCerts.clone();
+        }
+
+        @Override
+        public int getApplicationBufferSize() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getCipherSuite() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public long getCreationTime() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public byte[] getId() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public long getLastAccessedTime() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Certificate[] getLocalCertificates() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Principal getLocalPrincipal() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int getPacketBufferSize() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public javax.security.cert.X509Certificate[] getPeerCertificateChain()
+                throws SSLPeerUnverifiedException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+            if (peerCerts == null) {
+                throw new SSLPeerUnverifiedException("Null peerCerts");
+            } else {
+                return peerCerts.clone();
+            }
+        }
+
+        @Override
+        public String getPeerHost() {
+            return hostname;
+        }
+
+        @Override
+        public int getPeerPort() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getProtocol() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SSLSessionContext getSessionContext() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Object getValue(String name) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getValueNames() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void invalidate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isValid() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void putValue(String name, Object value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void removeValue(String name) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class FakeSSLSocket extends SSLSocket {
+        private final SSLSession session;
+        private final SSLParameters parameters;
+
+        public FakeSSLSocket(SSLSession session, SSLParameters parameters) {
+            this.session = session;
+            this.parameters = parameters;
+        }
+
+        @Override
+        public SSLParameters getSSLParameters() {
+            return parameters;
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getEnabledCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setEnabledCipherSuites(String[] strings) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getSupportedProtocols() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getEnabledProtocols() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setEnabledProtocols(String[] strings) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SSLSession getSession() {
+            return session;
+        }
+
+        @Override
+        public SSLSession getHandshakeSession() {
+            return session;
+        }
+
+        @Override
+        public void addHandshakeCompletedListener(
+                HandshakeCompletedListener handshakeCompletedListener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void removeHandshakeCompletedListener(
+                HandshakeCompletedListener handshakeCompletedListener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void startHandshake() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setUseClientMode(boolean b) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean getUseClientMode() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setNeedClientAuth(boolean b) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean getNeedClientAuth() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setWantClientAuth(boolean b) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean getWantClientAuth() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setEnableSessionCreation(boolean b) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean getEnableSessionCreation() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private static class TestHostnameVerifier
+            extends com.android.org.conscrypt.javax.net.ssl.TestHostnameVerifier
+            implements ConscryptHostnameVerifier {}
+}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
new file mode 100644
index 0000000..ac153fb
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/CTVerifierTest.java
@@ -0,0 +1,197 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import static com.android.org.conscrypt.TestUtils.openTestFile;
+import static com.android.org.conscrypt.TestUtils.readTestFile;
+import static org.junit.Assert.assertEquals;
+
+import java.security.PublicKey;
+import java.security.Security;
+import java.util.Arrays;
+import com.android.org.conscrypt.OpenSSLX509Certificate;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class CTVerifierTest {
+    private static boolean installedProvider;
+    private OpenSSLX509Certificate ca;
+    private OpenSSLX509Certificate cert;
+    private OpenSSLX509Certificate certEmbedded;
+    private CTVerifier ctVerifier;
+
+    @BeforeClass
+    public static void installConscrypt() {
+        installedProvider = TestUtils.installConscryptIfNotPresent();
+    }
+
+    @AfterClass
+    public static void removeConscrypt() {
+        if (installedProvider) {
+            Security.removeProvider(TestUtils.getConscryptProvider().getName());
+            installedProvider = false;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        ca = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("ca-cert.pem"));
+        cert = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("cert.pem"));
+        certEmbedded = OpenSSLX509Certificate.fromX509PemInputStream(
+                openTestFile("cert-ct-embedded.pem"));
+
+        PublicKey key = TestUtils.readPublicKeyPemFile("ct-server-key-public.pem");
+
+        final CTLogInfo log = new CTLogInfo(key, "Test Log", "foo");
+        CTLogStore store = new CTLogStore() {
+            @Override
+            public CTLogInfo getKnownLog(byte[] logId) {
+                if (Arrays.equals(logId, log.getID())) {
+                    return log;
+                } else {
+                    return null;
+                }
+            }
+        };
+
+        ctVerifier = new CTVerifier(store);
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withOCSPResponse() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        byte[] ocspResponse = readTestFile("ocsp-response.der");
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, null, ocspResponse);
+        assertEquals(1, result.getValidSCTs().size());
+        assertEquals(0, result.getInvalidSCTs().size());
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withTLSExtension() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list");
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
+        assertEquals(1, result.getValidSCTs().size());
+        assertEquals(0, result.getInvalidSCTs().size());
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withEmbeddedExtension() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { certEmbedded, ca };
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, null, null);
+        assertEquals(1, result.getValidSCTs().size());
+        assertEquals(0, result.getInvalidSCTs().size());
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withoutTimestamp() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, null, null);
+        assertEquals(0, result.getValidSCTs().size());
+        assertEquals(0, result.getInvalidSCTs().size());
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withInvalidSignature() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-invalid");
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
+        assertEquals(0, result.getValidSCTs().size());
+        assertEquals(1, result.getInvalidSCTs().size());
+        assertEquals(VerifiedSCT.Status.INVALID_SIGNATURE,
+                     result.getInvalidSCTs().get(0).status);
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withUnknownLog() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-unknown");
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
+        assertEquals(0, result.getValidSCTs().size());
+        assertEquals(1, result.getInvalidSCTs().size());
+        assertEquals(VerifiedSCT.Status.UNKNOWN_LOG,
+                     result.getInvalidSCTs().get(0).status);
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withInvalidEncoding() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        // Just some garbage data which will fail to deserialize
+        byte[] tlsExtension = new byte[] { 1, 2, 3, 4 };
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, null);
+        assertEquals(0, result.getValidSCTs().size());
+        assertEquals(0, result.getInvalidSCTs().size());
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withInvalidOCSPResponse() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        // Just some garbage data which will fail to deserialize
+        byte[] ocspResponse = new byte[] { 1, 2, 3, 4 };
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, null, ocspResponse);
+        assertEquals(0, result.getValidSCTs().size());
+        assertEquals(0, result.getInvalidSCTs().size());
+    }
+
+    @Test
+    public void test_verifySignedCertificateTimestamps_withMultipleTimestamps() throws Exception {
+        OpenSSLX509Certificate[] chain = new OpenSSLX509Certificate[] { cert, ca };
+
+        byte[] tlsExtension = readTestFile("ct-signed-timestamp-list-invalid");
+        byte[] ocspResponse = readTestFile("ocsp-response.der");
+
+        CTVerificationResult result =
+            ctVerifier.verifySignedCertificateTimestamps(chain, tlsExtension, ocspResponse);
+        assertEquals(1, result.getValidSCTs().size());
+        assertEquals(1, result.getInvalidSCTs().size());
+        assertEquals(SignedCertificateTimestamp.Origin.OCSP_RESPONSE,
+                     result.getValidSCTs().get(0).sct.getOrigin());
+        assertEquals(SignedCertificateTimestamp.Origin.TLS_EXTENSION,
+                     result.getInvalidSCTs().get(0).sct.getOrigin());
+    }
+}
+
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/ct/SerializationTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/SerializationTest.java
new file mode 100644
index 0000000..7dabf84
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/ct/SerializationTest.java
@@ -0,0 +1,229 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SerializationTest {
+
+    @Test
+    public void test_decode_SignedCertificateTimestamp() throws Exception {
+        byte[] in = new byte[] {
+            0x00,                            // version
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // log id
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+            0x01, 0x02, 0x03, 0x04,          // timestamp
+            0x05, 0x06, 0x07, 0x08,
+            0x00, 0x00,                      // extensions length
+            0x04, 0x03,                      // hash & signature algorithm
+            0x00, 0x04,                      // signature length
+            0x12, 0x34, 0x56, 0x78           // signature
+        };
+
+        SignedCertificateTimestamp sct
+            = SignedCertificateTimestamp.decode(in, SignedCertificateTimestamp.Origin.EMBEDDED);
+
+        assertEquals(SignedCertificateTimestamp.Version.V1, sct.getVersion());
+        assertEquals(0x0102030405060708L, sct.getTimestamp());
+        assertEquals(0, sct.getExtensions().length);
+        assertEquals(DigitallySigned.HashAlgorithm.SHA256,
+                     sct.getSignature().getHashAlgorithm());
+        assertEquals(DigitallySigned.SignatureAlgorithm.ECDSA,
+                     sct.getSignature().getSignatureAlgorithm());
+        assertTrue(Arrays.equals(new byte[] { 0x12, 0x34, 0x56, 0x78},
+                     sct.getSignature().getSignature()));
+        assertEquals(SignedCertificateTimestamp.Origin.EMBEDDED, sct.getOrigin());
+    }
+
+    @Test
+    public void test_decode_invalid_SignedCertificateTimestamp() throws Exception {
+        byte[] sct = new byte[] {
+            0x00,                            // version
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // log id
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+            0x01, 0x02, 0x03, 0x04,          // timestamp
+            0x05, 0x06, 0x07, 0x08,
+            0x00, 0x00,                      // extensions length
+            0x04, 0x03,                      // hash & signature algorithm
+            0x00, 0x04,                      // signature length
+            0x12, 0x34, 0x56, 0x78           // signature
+        };
+
+        // Make sure the original decodes fine
+        SignedCertificateTimestamp.decode(sct, SignedCertificateTimestamp.Origin.EMBEDDED);
+
+        // Perform various modification to it, and make sure it throws an exception on decoding
+        try {
+            byte[] in = sct.clone();
+            in[0] = 1; // Modify version field
+            SignedCertificateTimestamp.decode(in, SignedCertificateTimestamp.Origin.EMBEDDED);
+            fail("SerializationException not thrown on unsupported version");
+        } catch (SerializationException e) {}
+
+        try {
+            byte[] in = sct.clone();
+            in[41] = 1; // Modify extensions lemgth
+            SignedCertificateTimestamp.decode(in, SignedCertificateTimestamp.Origin.EMBEDDED);
+            fail("SerializationException not thrown on invalid extensions length");
+        } catch (SerializationException e) {}
+    }
+
+    @Test
+    public void test_decode_DigitallySigned() throws Exception {
+        byte[] in = new byte[] {
+            0x04, 0x03,            // hash & signature algorithm
+            0x00, 0x04,            // signature length
+            0x12, 0x34, 0x56, 0x78 // signature
+        };
+
+        DigitallySigned dst = DigitallySigned.decode(in);
+        assertEquals(DigitallySigned.HashAlgorithm.SHA256, dst.getHashAlgorithm());
+        assertEquals(DigitallySigned.SignatureAlgorithm.ECDSA, dst.getSignatureAlgorithm());
+        assertEqualByteArrays(new byte[] { 0x12, 0x34, 0x56, 0x78}, dst.getSignature());
+    }
+
+    @Test
+    public void test_decode_invalid_DigitallySigned() throws Exception {
+        try {
+            DigitallySigned.decode(new byte[] {
+                0x07, 0x03,            // hash & signature algorithm
+                0x00, 0x04,            // signature length
+                0x12, 0x34, 0x56, 0x78 // signature
+            });
+            fail("SerializationException not thrown on invalid hash type");
+        } catch (SerializationException e) {}
+
+        try {
+            DigitallySigned.decode(new byte[] {
+                0x04, 0x04,            // hash & signature algorithm
+                0x00, 0x04,            // signature length
+                0x12, 0x34, 0x56, 0x78 // signature
+            });
+            fail("SerializationException not thrown on invalid signature type");
+        } catch (SerializationException e) {}
+
+        try {
+            DigitallySigned.decode(new byte[] {
+                0x07, 0x03,            // hash & signature algorithm
+                0x64, 0x35,            // signature length
+                0x12, 0x34, 0x56, 0x78 // signature
+            });
+            fail("SerializationException not thrown on invalid signature length");
+        } catch (SerializationException e) {}
+
+        try {
+            DigitallySigned.decode(new byte[] {
+                0x07, 0x03,            // hash & signature algorithm
+            });
+            fail("SerializationException not thrown on missing signature");
+        } catch (SerializationException e) {}
+    }
+
+    @Test
+    public void test_encode_CertificateEntry_X509Certificate() throws Exception {
+        // Use a dummy certificate. It doesn't matter, CertificateEntry doesn't care about the contents.
+        CertificateEntry entry = CertificateEntry.createForX509Certificate(new byte[] { 0x12, 0x34, 0x56, 0x78 });
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        entry.encode(output);
+
+        assertEqualByteArrays(new byte[] {
+            0x00, 0x00,            // entry_type
+            0x00, 0x00, 0x04,      // x509_entry length
+            0x12, 0x34, 0x56, 0x78 // x509_entry
+        }, output.toByteArray());
+    }
+
+    @Test
+    public void test_encode_CertificateEntry_PreCertificate() throws Exception {
+        // Use a dummy certificate and issuer key hash. It doesn't matter,
+        // CertificateEntry doesn't care about the contents.
+        CertificateEntry entry = CertificateEntry.createForPrecertificate(new byte[] { 0x12, 0x34, 0x56, 0x78 },
+                                                          new byte[32]);
+
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        entry.encode(output);
+
+        assertEqualByteArrays(new byte[] {
+            0x00, 0x01,                      // entry_type
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // issuer key hash
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+            0x00, 0x00, 0x04,                // precert_entry length
+            0x12, 0x34, 0x56, 0x78           // precert_entry
+        }, output.toByteArray());
+    }
+
+    @Test
+    public void test_readDEROctetString() throws Exception {
+        byte[] in, expected;
+
+        in = new byte[] {
+            0x04, // TAG
+            0x06, // length
+            0x01, 0x02, 0x03, 0x04, 0x05, 0x05 // data
+        };
+        expected = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x05 };
+        assertEqualByteArrays(expected, Serialization.readDEROctetString(in));
+
+        in = new byte[203];
+        in[0] = 0x04; // TAG
+        in[1] = (byte)0x81; // long length flag
+        in[2] = (byte)200; // length
+        in[3] = 0x45; // data, the rest is just zeros
+
+        expected = new byte[200];
+        expected[0] = 0x45;
+        assertEqualByteArrays(expected, Serialization.readDEROctetString(in));
+
+        try {
+            in = new byte[] {
+                0x12, // wrong tag
+                0x06, // length
+                0x01, 0x02, 0x03, 0x04, 0x05, 0x05 // data
+            };
+            Serialization.readDEROctetString(in);
+            fail("SerializationException not thrown on invalid tag.");
+        } catch (SerializationException e) {}
+
+        try {
+            in = new byte[] {
+                0x04, // wrong tag
+                0x06, // length
+                0x01, 0x02 // data
+            };
+            Serialization.readDEROctetString(in);
+            fail("SerializationException not thrown on invalid length.");
+        } catch (SerializationException e) {}
+    }
+
+    public static void assertEqualByteArrays(byte[] expected, byte[] actual) {
+        assertEquals(Arrays.toString(expected), Arrays.toString(actual));
+    }
+}
+
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParameterGeneratorTestDH.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParameterGeneratorTestDH.java
new file mode 100644
index 0000000..8ec1867
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParameterGeneratorTestDH.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParameterGeneratorTestDH extends
+        AbstractAlgorithmParameterGeneratorTest {
+
+    public AlgorithmParameterGeneratorTestDH() {
+        super("DH", new AlgorithmParameterKeyAgreementHelper("DH"));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParameterGeneratorTestDSA.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParameterGeneratorTestDSA.java
new file mode 100644
index 0000000..bd192f3
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParameterGeneratorTestDSA.java
@@ -0,0 +1,33 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.spec.DSAParameterSpec;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParameterGeneratorTestDSA extends
+        AbstractAlgorithmParameterGeneratorTest {
+
+    public AlgorithmParameterGeneratorTestDSA() {
+        super("DSA", new AlgorithmParameterSignatureHelper<DSAParameterSpec>("DSA", DSAParameterSpec.class));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersPSSTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersPSSTest.java
new file mode 100644
index 0000000..2c47180
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersPSSTest.java
@@ -0,0 +1,263 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersPSSTest {
+
+    // ASN.1 DER-encoded forms of DEFAULT_SPEC and WEIRD_SPEC were generated using
+    // Bouncy Castle 1.52 AlgorithmParameters of type "PSS" and checked for correctness
+    // using ASN.1 DER decoder.
+    private static final PSSParameterSpec DEFAULT_SPEC = PSSParameterSpec.DEFAULT;
+    private static final byte[] DEFAULT_SPEC_DER_ENCODED = TestUtils.decodeHex("3000");
+
+    private static final PSSParameterSpec WEIRD_SPEC =
+            new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
+    private static final byte[] WEIRD_SPEC_DER_ENCODED =
+            TestUtils.decodeHex(
+                    "3034a00f300d06096086480165030402040500a11c301a06092a864886f70d010108300d060960"
+                    + "86480165030402010500a203020120");
+
+    /** Truncated SEQUENCE (one more byte needed at the end) */
+    private static final byte[] BROKEN_SPEC1_DER_ENCODED =
+            TestUtils.decodeHex(
+                    "303aa00f300d06096086480165030402030500a11c301a06092a864886f70d010108300d060960"
+                    + "86480165030402020500a20302011ba303020103");
+
+    /** Payload of SEQUENCE extends beyond the SEQUENCE. */
+    private static final byte[] BROKEN_SPEC2_DER_ENCODED =
+            TestUtils.decodeHex(
+                    "3037a00f300d06096086480165030402030500a11c301a06092a864886f70d010108300d060960"
+                    + "86480165030402020500a20302011ba303020103");
+
+    @Test
+    public void testGetInstance() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        assertNotNull(params);
+    }
+
+    @Test
+    public void testGetAlgorithm() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        assertEquals("PSS", params.getAlgorithm());
+    }
+
+    @Test
+    public void testGetProvider() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        params.init(DEFAULT_SPEC);
+        assertNotNull(params.getProvider());
+    }
+
+    @Test
+    public void testInitFailsWhenAlreadyInitialized() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        params.init(DEFAULT_SPEC);
+        try {
+            params.init(DEFAULT_SPEC);
+            fail();
+        } catch (InvalidParameterSpecException expected) {}
+        try {
+            params.init(DEFAULT_SPEC_DER_ENCODED);
+            fail();
+        } catch (IOException expected) {}
+        try {
+            params.init(DEFAULT_SPEC_DER_ENCODED, "ASN.1");
+            fail();
+        } catch (IOException expected) {}
+    }
+
+    @Test
+    public void testInitWithPSSParameterSpec() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        params.init(WEIRD_SPEC);
+        assertPSSParameterSpecEquals(WEIRD_SPEC, params.getParameterSpec(PSSParameterSpec.class));
+    }
+
+    @Test
+    public void testInitWithDerEncoded() throws Exception {
+        assertInitWithDerEncoded(WEIRD_SPEC_DER_ENCODED, WEIRD_SPEC);
+        assertInitWithDerEncoded(DEFAULT_SPEC_DER_ENCODED, DEFAULT_SPEC);
+    }
+
+    private void assertInitWithDerEncoded(
+            byte[] encoded, PSSParameterSpec expected) throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        params.init(encoded);
+        assertPSSParameterSpecEquals(expected, params.getParameterSpec(PSSParameterSpec.class));
+
+        params = AlgorithmParameters.getInstance("PSS");
+        params.init(encoded, "ASN.1");
+        assertPSSParameterSpecEquals(expected, params.getParameterSpec(PSSParameterSpec.class));
+    }
+
+    @Test
+    public void testGetEncodedThrowsWhenNotInitialized() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        try {
+            params.getEncoded();
+            fail();
+        } catch (IOException expected) {}
+        try {
+            params.getEncoded("ASN.1");
+            fail();
+        } catch (IOException expected) {}
+    }
+
+    @Test
+    public void testGetEncoded() throws Exception {
+        assertGetEncoded(WEIRD_SPEC, WEIRD_SPEC_DER_ENCODED);
+        assertGetEncoded(DEFAULT_SPEC, DEFAULT_SPEC_DER_ENCODED);
+    }
+
+    private void assertGetEncoded(PSSParameterSpec spec, byte[] expectedEncoded) throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        params.init(spec);
+        byte[] encoded = params.getEncoded("ASN.1");
+        assertTrue(Arrays.equals(expectedEncoded, encoded));
+        // Assert that getEncoded() returns ASN.1 form.
+        assertTrue(Arrays.equals(encoded, params.getEncoded()));
+    }
+
+    @Test
+    public void testGetEncodedWithBrokenInput() throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("PSS");
+        try {
+            params.init(BROKEN_SPEC1_DER_ENCODED);
+            fail();
+        } catch (IOException expected) {
+        } catch (IllegalArgumentException expected) {
+            // Bouncy Castle incorrectly throws an IllegalArgumentException instead of IOException.
+            if (!"BC".equals(params.getProvider().getName())) {
+                throw new RuntimeException(
+                        "Unexpected exception. Provider: " + params.getProvider(),
+                        expected);
+            }
+        }
+
+        params = AlgorithmParameters.getInstance("PSS");
+        try {
+            params.init(BROKEN_SPEC2_DER_ENCODED);
+            fail();
+        } catch (IOException expected) {
+        } catch (IllegalArgumentException expected) {
+            // Bouncy Castle incorrectly throws an IllegalArgumentException instead of IOException.
+            if (!"BC".equals(params.getProvider().getName())) {
+                throw new RuntimeException(
+                        "Unexpected exception. Provider: " + params.getProvider(),
+                        expected);
+            }
+        }
+    }
+
+    private static void assertPSSParameterSpecEquals(
+        PSSParameterSpec spec1, PSSParameterSpec spec2) {
+        assertEquals(
+                getDigestAlgorithmCanonicalName(spec1.getDigestAlgorithm()),
+                getDigestAlgorithmCanonicalName(spec2.getDigestAlgorithm()));
+        assertEquals(
+                getMGFAlgorithmCanonicalName(spec1.getMGFAlgorithm()),
+                getMGFAlgorithmCanonicalName(spec2.getMGFAlgorithm()));
+
+        AlgorithmParameterSpec spec1MgfParams = spec1.getMGFParameters();
+        assertNotNull(spec1MgfParams);
+        if (!(spec1MgfParams instanceof MGF1ParameterSpec)) {
+            fail("Unexpected type of MGF parameters: " + spec1MgfParams.getClass().getName());
+        }
+        MGF1ParameterSpec spec1Mgf1Params = (MGF1ParameterSpec) spec1MgfParams;
+        AlgorithmParameterSpec spec2MgfParams = spec2.getMGFParameters();
+        assertNotNull(spec2MgfParams);
+        if (!(spec2MgfParams instanceof MGF1ParameterSpec)) {
+            fail("Unexpected type of MGF parameters: " + spec2MgfParams.getClass().getName());
+        }
+        MGF1ParameterSpec spec2Mgf1Params = (MGF1ParameterSpec) spec2MgfParams;
+
+        assertEquals(
+                getDigestAlgorithmCanonicalName(spec1Mgf1Params.getDigestAlgorithm()),
+                getDigestAlgorithmCanonicalName(spec2Mgf1Params.getDigestAlgorithm()));
+        assertEquals(spec1.getSaltLength(), spec2.getSaltLength());
+        assertEquals(spec1.getTrailerField(), spec2.getTrailerField());
+    }
+
+    // All the craziness with supporting OIDs is needed because Bouncy Castle, when parsing from
+    // ASN.1 form, returns PSSParameterSpec instances which use OIDs instead of JCA standard names
+    // for digest algorithms and MGF algorithms.
+    private static final Map<String, String> DIGEST_OID_TO_NAME = new TreeMap<String, String>(
+            String.CASE_INSENSITIVE_ORDER);
+    private static final Map<String, String> DIGEST_NAME_TO_OID = new TreeMap<String, String>(
+            String.CASE_INSENSITIVE_ORDER);
+
+    private static void addDigestOid(String algorithm, String oid) {
+        DIGEST_OID_TO_NAME.put(oid, algorithm);
+        DIGEST_NAME_TO_OID.put(algorithm, oid);
+    }
+
+    static {
+        addDigestOid("SHA-1", "1.3.14.3.2.26");
+        addDigestOid("SHA-224", "2.16.840.1.101.3.4.2.4");
+        addDigestOid("SHA-256", "2.16.840.1.101.3.4.2.1");
+        addDigestOid("SHA-384", "2.16.840.1.101.3.4.2.2");
+        addDigestOid("SHA-512", "2.16.840.1.101.3.4.2.3");
+    }
+
+    private static String getDigestAlgorithmCanonicalName(String algorithm) {
+        if (DIGEST_NAME_TO_OID.containsKey(algorithm)) {
+            return algorithm.toUpperCase(Locale.US);
+        }
+
+        String nameByOid = DIGEST_OID_TO_NAME.get(algorithm);
+        if (nameByOid != null) {
+            return nameByOid;
+        }
+
+        return algorithm;
+    }
+
+    private static String getMGFAlgorithmCanonicalName(String name) {
+        if ("MGF1".equalsIgnoreCase(name)) {
+            return name.toUpperCase(Locale.US);
+        } else if ("1.2.840.113549.1.1.8".equals(name)) {
+            return "MGF1";
+        } else {
+            return name;
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestAES.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestAES.java
new file mode 100644
index 0000000..df55013
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestAES.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import javax.crypto.spec.IvParameterSpec;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestAES extends AbstractAlgorithmParametersTest {
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private static final byte[] parameterData = new byte[] {
+        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
+        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
+        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
+        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
+
+    // See README.ASN1 for how to understand and reproduce this data
+
+    // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
+    private static final String ENCODED_DATA = "BBAECGjI/2Ry9QQIaMj/ZHL1";
+
+    public AlgorithmParametersTestAES() {
+        super("AES", new AlgorithmParameterSymmetricHelper("AES", "CBC/PKCS5PADDING", 128), new IvParameterSpec(parameterData));
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        ServiceTester.test("AlgorithmParameters")
+                .withAlgorithm("AES")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        AlgorithmParameters params = AlgorithmParameters.getInstance("AES", p);
+
+                        params.init(new IvParameterSpec(parameterData));
+                        assertEquals(ENCODED_DATA, TestUtils.encodeBase64(params.getEncoded()));
+
+                        params = AlgorithmParameters.getInstance("AES", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA));
+                        assertArrayEquals(parameterData,
+                                params.getParameterSpec(IvParameterSpec.class).getIV());
+                    }
+                });
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDES.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDES.java
new file mode 100644
index 0000000..603981c
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDES.java
@@ -0,0 +1,70 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.org.conscrypt.TestUtils;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import javax.crypto.spec.IvParameterSpec;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestDES extends AbstractAlgorithmParametersTest {
+
+    private static final byte[] parameterData = new byte[] {
+        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
+        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
+
+    // See README.ASN1 for how to understand and reproduce this data
+
+    // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5
+    private static final String ENCODED_DATA = "BAgECGjI/2Ry9Q==";
+
+    public AlgorithmParametersTestDES() {
+        super("DES", new AlgorithmParameterSymmetricHelper("DES", "CBC/PKCS5PADDING", 56), new IvParameterSpec(parameterData));
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        ServiceTester.test("AlgorithmParameters")
+                .withAlgorithm("DES")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        AlgorithmParameters params = AlgorithmParameters.getInstance("DES", p);
+
+                        params.init(new IvParameterSpec(parameterData));
+                        assertEquals(ENCODED_DATA, TestUtils.encodeBase64(params.getEncoded()));
+
+                        params = AlgorithmParameters.getInstance("DES", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA));
+                        assertArrayEquals(parameterData,
+                                params.getParameterSpec(IvParameterSpec.class).getIV());
+                    }
+                });
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDESede.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDESede.java
new file mode 100644
index 0000000..37ab2be
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDESede.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import javax.crypto.spec.IvParameterSpec;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestDESede extends AbstractAlgorithmParametersTest {
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private static final byte[] parameterData = new byte[] {
+        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
+        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5 };
+
+    // See README.ASN1 for how to understand and reproduce this data
+
+    // asn1=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5
+    private static final String ENCODED_DATA = "BAgECGjI/2Ry9Q==";
+
+    public AlgorithmParametersTestDESede() {
+        super("DESede", new AlgorithmParameterSymmetricHelper("DESede", "CBC/PKCS5PADDING", 112), new IvParameterSpec(parameterData));
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        ServiceTester.test("AlgorithmParameters")
+                .withAlgorithm("DESEDE")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        AlgorithmParameters params = AlgorithmParameters.getInstance("DESede", p);
+
+                        params.init(new IvParameterSpec(parameterData));
+                        assertEquals(ENCODED_DATA, TestUtils.encodeBase64(params.getEncoded()));
+
+                        params = AlgorithmParameters.getInstance("DESede", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA));
+                        assertArrayEquals(parameterData,
+                                params.getParameterSpec(IvParameterSpec.class).getIV());
+                    }
+                });
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDH.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDH.java
new file mode 100644
index 0000000..b6429d0
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDH.java
@@ -0,0 +1,67 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.math.BigInteger;
+import javax.crypto.spec.DHParameterSpec;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestDH extends AbstractAlgorithmParametersTest {
+
+    private static final byte[] P = new byte[] {
+            (byte) 0x00, (byte) 0xB8, (byte) 0xA4, (byte) 0x06, (byte) 0x10,
+            (byte) 0xA2, (byte) 0x8B, (byte) 0xD2, (byte) 0xC0, (byte) 0xB6,
+            (byte) 0x87, (byte) 0xFF, (byte) 0x15, (byte) 0xBA, (byte) 0x18,
+            (byte) 0xE9, (byte) 0x7D, (byte) 0x77, (byte) 0x9F, (byte) 0xAF,
+            (byte) 0x6F, (byte) 0x0B, (byte) 0xA4, (byte) 0xB6, (byte) 0x2B,
+            (byte) 0x35, (byte) 0xE2, (byte) 0x01, (byte) 0x66, (byte) 0x41,
+            (byte) 0x05, (byte) 0xE7, (byte) 0x6A, (byte) 0x62, (byte) 0x19,
+            (byte) 0x94, (byte) 0x18, (byte) 0x46, (byte) 0xBA, (byte) 0x60,
+            (byte) 0x2E, (byte) 0x5A, (byte) 0x48, (byte) 0x6C, (byte) 0x4B,
+            (byte) 0xBF, (byte) 0x8C, (byte) 0xBF, (byte) 0xB9, (byte) 0xEE,
+            (byte) 0xCC, (byte) 0x35, (byte) 0x89, (byte) 0x18, (byte) 0x02,
+            (byte) 0x18, (byte) 0xFE, (byte) 0xF4, (byte) 0x02, (byte) 0x3B,
+            (byte) 0x5E, (byte) 0x8A, (byte) 0x42, (byte) 0xB3, (byte) 0x39};
+
+    private static final byte[] Q = new byte[] {
+            (byte) 0x00, (byte) 0x87, (byte) 0xE2, (byte) 0xD1, (byte) 0x8A,
+            (byte) 0x23, (byte) 0x90, (byte) 0x3A, (byte) 0x0F, (byte) 0xC8,
+            (byte) 0x38, (byte) 0xA8, (byte) 0x65, (byte) 0x35, (byte) 0x89,
+            (byte) 0x4F, (byte) 0x4B, (byte) 0xB3, (byte) 0xBF, (byte) 0x18,
+            (byte) 0x3C, (byte) 0x3B, (byte) 0xD8, (byte) 0x72, (byte) 0xC3,
+            (byte) 0xCF, (byte) 0xC9, (byte) 0xA7, (byte) 0x39, (byte) 0x7E,
+            (byte) 0x9C, (byte) 0x69, (byte) 0xDA, (byte) 0xDE, (byte) 0x8E,
+            (byte) 0x96, (byte) 0x9D, (byte) 0x44, (byte) 0xC1, (byte) 0x1E,
+            (byte) 0x58, (byte) 0xC7, (byte) 0xFC, (byte) 0x40, (byte) 0x1B,
+            (byte) 0xE8, (byte) 0x23, (byte) 0xF3, (byte) 0x6B, (byte) 0x95,
+            (byte) 0x68, (byte) 0x29, (byte) 0x93, (byte) 0x35, (byte) 0x05,
+            (byte) 0xC5, (byte) 0xCB, (byte) 0xB8, (byte) 0x57, (byte) 0x8F,
+            (byte) 0xB9, (byte) 0xC3, (byte) 0x36, (byte) 0x09, (byte) 0x51};
+
+    private static final int l = 511;
+
+    public AlgorithmParametersTestDH() {
+        super("DH", new AlgorithmParameterKeyAgreementHelper("DH"),
+                new DHParameterSpec(new BigInteger(P), new BigInteger(Q), l));
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDSA.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDSA.java
new file mode 100644
index 0000000..f6585fc
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestDSA.java
@@ -0,0 +1,152 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.org.conscrypt.TestUtils;
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import java.security.spec.DSAParameterSpec;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestDSA extends AbstractAlgorithmParametersTest {
+
+    /*
+     * Parameters generated with OpenSSL:
+     * openssl dsaparam -genkey 1024 -C
+     */
+    private static final byte[] P = new byte[] {
+            (byte) 0xE6, (byte) 0x41, (byte) 0x58, (byte) 0x77, (byte) 0x76,
+            (byte) 0x5A, (byte) 0x4A, (byte) 0x53, (byte) 0xF1, (byte) 0xD6,
+            (byte) 0xC8, (byte) 0x7D, (byte) 0x67, (byte) 0x1F, (byte) 0x2F,
+            (byte) 0xFA, (byte) 0xDE, (byte) 0xB7, (byte) 0xAA, (byte) 0xCD,
+            (byte) 0xD7, (byte) 0x5D, (byte) 0xD0, (byte) 0xE9, (byte) 0xB1,
+            (byte) 0xDA, (byte) 0xFE, (byte) 0x42, (byte) 0xBE, (byte) 0xCC,
+            (byte) 0x42, (byte) 0x52, (byte) 0x2E, (byte) 0x01, (byte) 0xD2,
+            (byte) 0x16, (byte) 0xB1, (byte) 0x5B, (byte) 0xC4, (byte) 0x42,
+            (byte) 0xF9, (byte) 0x55, (byte) 0x0F, (byte) 0xE2, (byte) 0xD5,
+            (byte) 0x01, (byte) 0xD2, (byte) 0x7E, (byte) 0x22, (byte) 0xF6,
+            (byte) 0xC1, (byte) 0xFE, (byte) 0x5C, (byte) 0x6A, (byte) 0xCF,
+            (byte) 0x82, (byte) 0x1B, (byte) 0x5C, (byte) 0x46, (byte) 0x66,
+            (byte) 0x8B, (byte) 0xAF, (byte) 0xDF, (byte) 0x44, (byte) 0xE2,
+            (byte) 0x0E, (byte) 0xA3, (byte) 0x58, (byte) 0xF7, (byte) 0xA3,
+            (byte) 0x24, (byte) 0xE3, (byte) 0x84, (byte) 0xA6, (byte) 0x16,
+            (byte) 0xE0, (byte) 0xCA, (byte) 0x72, (byte) 0x55, (byte) 0x07,
+            (byte) 0xA0, (byte) 0x99, (byte) 0x7B, (byte) 0xF8, (byte) 0xB1,
+            (byte) 0x5A, (byte) 0x84, (byte) 0x36, (byte) 0x5A, (byte) 0xC8,
+            (byte) 0x6A, (byte) 0xFE, (byte) 0xA6, (byte) 0xB4, (byte) 0x1B,
+            (byte) 0x3A, (byte) 0x0A, (byte) 0x00, (byte) 0x6B, (byte) 0x72,
+            (byte) 0xDC, (byte) 0x0C, (byte) 0xD1, (byte) 0x09, (byte) 0x25,
+            (byte) 0x11, (byte) 0x68, (byte) 0x6B, (byte) 0x75, (byte) 0xDE,
+            (byte) 0x2C, (byte) 0x1A, (byte) 0xC2, (byte) 0x3A, (byte) 0xCB,
+            (byte) 0xA0, (byte) 0x17, (byte) 0xCA, (byte) 0x2D, (byte) 0xEE,
+            (byte) 0xA2, (byte) 0x5A, (byte) 0x9D, (byte) 0x1F, (byte) 0x33,
+            (byte) 0x1B, (byte) 0x07, (byte) 0x6D,
+    };
+    private static final byte[] Q = new byte[] {
+            (byte) 0x9B, (byte) 0x39, (byte) 0xD0, (byte) 0x02, (byte) 0x0F,
+            (byte) 0xE9, (byte) 0x96, (byte) 0x16, (byte) 0xC5, (byte) 0x25,
+            (byte) 0xF7, (byte) 0x94, (byte) 0xA9, (byte) 0x2C, (byte) 0xD0,
+            (byte) 0x25, (byte) 0x5B, (byte) 0x6E, (byte) 0xE0, (byte) 0x8F,
+    };
+    private static final byte[] G = new byte[] {
+            (byte) 0x5E, (byte) 0x9C, (byte) 0x95, (byte) 0x5F, (byte) 0x7E,
+            (byte) 0x91, (byte) 0x47, (byte) 0x4D, (byte) 0x68, (byte) 0xA4,
+            (byte) 0x1C, (byte) 0x44, (byte) 0x3B, (byte) 0xEC, (byte) 0x0A,
+            (byte) 0x7E, (byte) 0x59, (byte) 0x54, (byte) 0xF7, (byte) 0xEF,
+            (byte) 0x42, (byte) 0xFB, (byte) 0x63, (byte) 0x95, (byte) 0x08,
+            (byte) 0x2F, (byte) 0x4A, (byte) 0xD3, (byte) 0xBC, (byte) 0x79,
+            (byte) 0x9D, (byte) 0xBA, (byte) 0xD8, (byte) 0x8A, (byte) 0x83,
+            (byte) 0x84, (byte) 0xAE, (byte) 0x5B, (byte) 0x26, (byte) 0x80,
+            (byte) 0xB3, (byte) 0xFB, (byte) 0x9C, (byte) 0xA3, (byte) 0xCF,
+            (byte) 0xF4, (byte) 0x0A, (byte) 0xD5, (byte) 0xB6, (byte) 0x65,
+            (byte) 0x65, (byte) 0x1A, (byte) 0x4F, (byte) 0xC0, (byte) 0x86,
+            (byte) 0x3B, (byte) 0xE6, (byte) 0xFB, (byte) 0x4E, (byte) 0x9E,
+            (byte) 0x49, (byte) 0x0A, (byte) 0x8C, (byte) 0x77, (byte) 0x2D,
+            (byte) 0x93, (byte) 0x0B, (byte) 0xCA, (byte) 0x81, (byte) 0x07,
+            (byte) 0x09, (byte) 0xC4, (byte) 0x71, (byte) 0xFD, (byte) 0xC8,
+            (byte) 0xC7, (byte) 0xD1, (byte) 0xA3, (byte) 0xD0, (byte) 0xBB,
+            (byte) 0x7D, (byte) 0x92, (byte) 0x74, (byte) 0x8B, (byte) 0x3B,
+            (byte) 0x2A, (byte) 0x45, (byte) 0x1F, (byte) 0x5D, (byte) 0x85,
+            (byte) 0x90, (byte) 0xE3, (byte) 0xFB, (byte) 0x0E, (byte) 0x16,
+            (byte) 0xBA, (byte) 0x8A, (byte) 0xDE, (byte) 0x10, (byte) 0x0F,
+            (byte) 0xE0, (byte) 0x0F, (byte) 0x37, (byte) 0xA7, (byte) 0xC1,
+            (byte) 0xDC, (byte) 0xBC, (byte) 0x00, (byte) 0xB8, (byte) 0x24,
+            (byte) 0x0F, (byte) 0xF6, (byte) 0x5F, (byte) 0xB1, (byte) 0xA8,
+            (byte) 0x9A, (byte) 0xDB, (byte) 0x9F, (byte) 0x36, (byte) 0x54,
+            (byte) 0x45, (byte) 0xBD, (byte) 0xC0, (byte) 0xE8, (byte) 0x27,
+            (byte) 0x82, (byte) 0xC9, (byte) 0x75,
+    };
+
+    // The ASN.1 module for DSA is defined in RFC 3279 section 3. See README.ASN1 for how
+    // to understand and reproduce this data.
+
+    // asn1=SEQUENCE:dsa
+    // [dsa]
+    // p=INT:0xE6415877765A4A53F1D6C87D671F2FFADEB7AACDD75DD0E9B1DAFE42BECC42522E01D216B15BC442F9550FE2D501D27E22F6C1FE5C6ACF821B5C46668BAFDF44E20EA358F7A324E384A616E0CA725507A0997BF8B15A84365AC86AFEA6B41B3A0A006B72DC0CD1092511686B75DE2C1AC23ACBA017CA2DEEA25A9D1F331B076D
+    // q=INT:0x9B39D0020FE99616C525F794A92CD0255B6EE08F
+    // g=INT:0x5E9C955F7E91474D68A41C443BEC0A7E5954F7EF42FB6395082F4AD3BC799DBAD88A8384AE5B2680B3FB9CA3CFF40AD5B665651A4FC0863BE6FB4E9E490A8C772D930BCA810709C471FDC8C7D1A3D0BB7D92748B3B2A451F5D8590E3FB0E16BA8ADE100FE00F37A7C1DCBC00B8240FF65FB1A89ADB9F365445BDC0E82782C975
+    private static final String ENCODED_DATA = "MIIBHgKBgQDmQVh3dlpKU/HWyH1nHy/63reqzddd0Omx2v5"
+            + "CvsxCUi4B0haxW8RC+VUP4tUB0n4i9sH+XGrPghtcRmaLr99E4g6jWPejJOOEphbgynJVB6CZe/ixWoQ"
+            + "2Wshq/qa0GzoKAGty3AzRCSURaGt13iwawjrLoBfKLe6iWp0fMxsHbQIVAJs50AIP6ZYWxSX3lKks0CV"
+            + "bbuCPAoGAXpyVX36RR01opBxEO+wKfllU9+9C+2OVCC9K07x5nbrYioOErlsmgLP7nKPP9ArVtmVlGk/"
+            + "Ahjvm+06eSQqMdy2TC8qBBwnEcf3Ix9Gj0Lt9knSLOypFH12FkOP7Dha6it4QD+APN6fB3LwAuCQP9l+"
+            + "xqJrbnzZURb3A6CeCyXU=";
+
+    public AlgorithmParametersTestDSA() {
+        super("DSA", new AlgorithmParameterSignatureHelper<DSAParameterSpec>(
+                "DSA", DSAParameterSpec.class), new DSAParameterSpec(
+                new BigInteger(1, P), new BigInteger(1, Q), new BigInteger(1, G)));
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        ServiceTester.test("AlgorithmParameters")
+                .withAlgorithm("DSA")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        AlgorithmParameters params = AlgorithmParameters.getInstance("DSA", p);
+
+                        DSAParameterSpec spec = new DSAParameterSpec(
+                                new BigInteger(1, P), new BigInteger(1, Q), new BigInteger(1, G));
+
+                        params.init(spec);
+                        assertEquals(ENCODED_DATA, TestUtils.encodeBase64(params.getEncoded()));
+
+                        params = AlgorithmParameters.getInstance("DSA", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA));
+                        DSAParameterSpec derivedSpec =
+                                params.getParameterSpec(DSAParameterSpec.class);
+
+                        assertEquals(new BigInteger(1, P), derivedSpec.getP());
+                        assertEquals(new BigInteger(1, Q), derivedSpec.getQ());
+                        assertEquals(new BigInteger(1, G), derivedSpec.getG());
+                    }
+                });
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestGCM.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestGCM.java
new file mode 100644
index 0000000..7ab64bc
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestGCM.java
@@ -0,0 +1,120 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import javax.crypto.spec.GCMParameterSpec;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestGCM extends AbstractAlgorithmParametersTest {
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private static final byte[] IV = new byte[] {
+        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8,
+        (byte) 0xFF, (byte) 0x64, (byte) 0x72, (byte) 0xF5,
+        (byte) 0x04, (byte) 0x08, (byte) 0x68, (byte) 0xC8 };
+
+    private static final int TLEN = 96;
+    private static final int SUN_ALT_TLEN = 128;
+
+    // The ASN.1 encoding for GCM params (specified in RFC 5084 section 3.2) specifies
+    // a default value of 12 for TLEN, so both values with and without TLEN should work.
+    // See README.ASN1 for how to understand and reproduce this data.
+
+    // asn1=SEQUENCE:gcm
+    // [gcm]
+    // iv=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
+    private static final String ENCODED_DATA_NO_TLEN = "MA4EDAQIaMj/ZHL1BAhoyA==";
+
+    // asn1=SEQUENCE:gcm
+    // [gcm]
+    // iv=FORMAT:HEX,OCTETSTRING:040868C8FF6472F5040868C8
+    // tlen=INT:12
+    private static final String ENCODED_DATA_TLEN = "MBEEDAQIaMj/ZHL1BAhoyAIBDA==";
+
+    public AlgorithmParametersTestGCM() {
+        super("GCM", new AlgorithmParameterSymmetricHelper("AES", "GCM/NOPADDING", 128), new GCMParameterSpec(TLEN, IV));
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        ServiceTester.test("AlgorithmParameters")
+                .withAlgorithm("GCM")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        AlgorithmParameters params = AlgorithmParameters.getInstance("GCM", p);
+
+                        params.init(new GCMParameterSpec(TLEN, IV));
+                        String encoded = TestUtils.encodeBase64(params.getEncoded());
+                        assertTrue("Encoded: " + encoded,
+                                encoded.equals(ENCODED_DATA_TLEN)
+                                        || encoded.equals(ENCODED_DATA_NO_TLEN));
+
+                        params = AlgorithmParameters.getInstance("GCM", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_NO_TLEN));
+                        GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
+                        if (!p.getName().equals("SunJCE")) {
+                            assertEquals(TLEN, spec.getTLen());
+                        } else {
+                            // In some cases the SunJCE provider uses 128 as the default instead of
+                            // 96
+                            assertTrue(spec.getTLen() == TLEN || spec.getTLen() == SUN_ALT_TLEN);
+                        }
+                        assertArrayEquals(IV, spec.getIV());
+
+                        params = AlgorithmParameters.getInstance("GCM", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_TLEN));
+                        spec = params.getParameterSpec(GCMParameterSpec.class);
+                        assertEquals(TLEN, spec.getTLen());
+                        assertArrayEquals(IV, spec.getIV());
+                    }
+                });
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java
new file mode 100644
index 0000000..2176981
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/AlgorithmParametersTestOAEP.java
@@ -0,0 +1,259 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import java.security.spec.MGF1ParameterSpec;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+import javax.crypto.spec.PSource.PSpecified;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class AlgorithmParametersTestOAEP extends AbstractAlgorithmParametersTest {
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    // The ASN.1 encoding for OAEP params (specified in RFC 4055 section 4.1) specifies
+    // default values for all parameters, so we need to consider encodings with those
+    // values both explicitly specified and unspecified.  When encoding values, it is required
+    // that default values are left empty, but implementations must be able to parse explicitly-
+    // specified defaults as well.
+    //
+    // See README.ASN1 for how to understand and reproduce this data.
+
+    // asn1=SEQUENCE
+    private static final String ENCODED_DATA_ALL_DEFAULTS = "MAA=";
+
+    // asn1=SEQUENCE:oaep
+    // [oaep]
+    // hashFunc=EXP:0,SEQUENCE:sha1
+    // maskGenFunc=EXP:1,SEQUENCE:mgf1
+    // pSourceFunc=EXP:2,SEQUENCE:pSpecified
+    // [mgf1]
+    // oid=OID:1.2.840.113549.1.1.8
+    // params=SEQUENCE:sha1
+    // [pSpecified]
+    // oid=OID:1.2.840.113549.1.1.9
+    // val=OCTETSTRING:
+    // [sha1]
+    // oid=OID:sha1
+    // params=NULL
+    private static final String ENCODED_DATA_EXPLICIT_DEFAULTS =
+            "MDigCzAJBgUrDgMCGgUAoRgwFgYJKoZIhvcNAQEIMAkGBSsOAwIaBQCiDzANBgkqhkiG9w0BAQkEAA==";
+
+    // Base64 version of ASN.1-encoded data with none of the default values.  Specifically:
+    // SHA-256 hashFunc, MGF1-SHA-384 maskGenFunc, and [1, 2, 3, 4] pSourceFunc
+
+    // asn1=SEQUENCE:oaep
+    // [oaep]
+    // hashFunc=EXP:0,SEQUENCE:sha256
+    // maskGenFunc=EXP:1,SEQUENCE:mgf1
+    // pSourceFunc=EXP:2,SEQUENCE:pSpecified
+    // [sha256]
+    // oid=OID:sha256
+    // params=NULL
+    // [mgf1]
+    // oid=OID:1.2.840.113549.1.1.8
+    // params=SEQUENCE:sha384
+    // [sha384]
+    // oid=OID:sha384
+    // params=NULL
+    // [pSpecified]
+    // oid=OID:1.2.840.113549.1.1.9
+    // val=FORMAT:HEX,OCTETSTRING:01020304
+    private static final String ENCODED_DATA_NON_DEFAULTS = "MESgDzANBglghkgBZQMEAgEFAKEc"
+            + "MBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKITMBEGCSqGSIb3DQEBCQQEAQIDBA==";
+
+    // Base64 version of ASN.1-encoded data with some default and some non-default values.
+    // Specifically, SHA-1 hashFunc (default), MGF1-SHA-512 maskGenFunc (non-default),
+    // empty pSourceFunc (default)
+
+    // asn1=SEQUENCE:oaep
+    // [oaep]
+    // maskGenFunc=EXP:1,SEQUENCE:mgf1
+    // [mgf1]
+    // oid=OID:1.2.840.113549.1.1.8
+    // params=SEQUENCE:sha512
+    // [sha512]
+    // oid=OID:sha512
+    // params=NULL
+    private static final String ENCODED_DATA_MIXED = "MB6hHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIDBQA=";
+
+    // Base64 version of the same ASN.1-encoded data as ENCODED_DATA_MIXED, but with the
+    // default values explicitly specified.
+
+    // asn1=SEQUENCE:oaep
+    // [oaep]
+    // hashFunc=EXP:0,SEQUENCE:sha1
+    // maskGenFunc=EXP:1,SEQUENCE:mgf1
+    // pSourceFunc=EXP:2,SEQUENCE:pSpecified
+    // [sha1]
+    // oid=OID:sha1
+    // params=NULL
+    // [mgf1]
+    // oid=OID:1.2.840.113549.1.1.8
+    // params=SEQUENCE:sha512
+    // [pSpecified]
+    // oid=OID:1.2.840.113549.1.1.9
+    // val=OCTETSTRING:
+    // [sha512]
+    // oid=OID:sha512
+    // params=NULL
+    private static final String ENCODED_DATA_MIXED_EXPLICIT_DEFAULTS = "MDygCzAJBgUrDgMCGgUAoRww"
+            + "GgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAog8wDQYJKoZIhvcNAQEJBAA=";
+
+    public AlgorithmParametersTestOAEP() {
+        super("OAEP", new AlgorithmParameterAsymmetricHelper("RSA/ECB/OAEPPadding"), new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        ServiceTester.test("AlgorithmParameters")
+                .withAlgorithm("OAEP")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP", p);
+
+                        OAEPParameterSpec spec = new OAEPParameterSpec("SHA-1", "MGF1",
+                                MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
+                        params.init(spec);
+                        if (!p.getName().equals("SunJCE")) {
+                            assertEquals(ENCODED_DATA_ALL_DEFAULTS,
+                                    TestUtils.encodeBase64(params.getEncoded()));
+                        } else {
+                            // SunJCE encodes the defaults explicitly, which is not allowed by RFC
+                            // 4055.
+                            assertEquals(ENCODED_DATA_EXPLICIT_DEFAULTS,
+                                    TestUtils.encodeBase64(params.getEncoded()));
+                        }
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        spec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA384,
+                                new PSource.PSpecified(new byte[] {1, 2, 3, 4}));
+                        params.init(spec);
+                        assertEquals(ENCODED_DATA_NON_DEFAULTS,
+                                TestUtils.encodeBase64(params.getEncoded()));
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        spec = new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA512,
+                                PSource.PSpecified.DEFAULT);
+                        params.init(spec);
+                        if (!p.getName().equals("SunJCE")) {
+                            assertEquals(ENCODED_DATA_MIXED,
+                                    TestUtils.encodeBase64(params.getEncoded()));
+                        } else {
+                            // SunJCE encodes the defaults explicitly, which is not allowed by RFC
+                            // 4055.
+                            assertEquals(ENCODED_DATA_MIXED_EXPLICIT_DEFAULTS,
+                                    TestUtils.encodeBase64(params.getEncoded()));
+                        }
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_ALL_DEFAULTS));
+                        OAEPParameterSpec producedSpec =
+                                params.getParameterSpec(OAEPParameterSpec.class);
+
+                        assertEquals("SHA-1", producedSpec.getDigestAlgorithm());
+                        assertEquals("MGF1", producedSpec.getMGFAlgorithm());
+                        assertEquals(MGF1ParameterSpec.SHA1.getDigestAlgorithm(),
+                                ((MGF1ParameterSpec) producedSpec.getMGFParameters())
+                                        .getDigestAlgorithm());
+                        assertArrayEquals(PSpecified.DEFAULT.getValue(),
+                                ((PSpecified) producedSpec.getPSource()).getValue());
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_EXPLICIT_DEFAULTS));
+                        producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
+
+                        assertEquals("SHA-1", producedSpec.getDigestAlgorithm());
+                        assertEquals("MGF1", producedSpec.getMGFAlgorithm());
+                        assertEquals(MGF1ParameterSpec.SHA1.getDigestAlgorithm(),
+                                ((MGF1ParameterSpec) producedSpec.getMGFParameters())
+                                        .getDigestAlgorithm());
+                        assertArrayEquals(PSpecified.DEFAULT.getValue(),
+                                ((PSpecified) producedSpec.getPSource()).getValue());
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_NON_DEFAULTS));
+                        producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
+
+                        assertEquals("SHA-256", producedSpec.getDigestAlgorithm());
+                        assertEquals("MGF1", producedSpec.getMGFAlgorithm());
+                        assertEquals(MGF1ParameterSpec.SHA384.getDigestAlgorithm(),
+                                ((MGF1ParameterSpec) producedSpec.getMGFParameters())
+                                        .getDigestAlgorithm());
+                        assertArrayEquals(new byte[] {1, 2, 3, 4},
+                                ((PSpecified) producedSpec.getPSource()).getValue());
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_MIXED));
+                        producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
+
+                        assertEquals("SHA-1", producedSpec.getDigestAlgorithm());
+                        assertEquals("MGF1", producedSpec.getMGFAlgorithm());
+                        assertEquals(MGF1ParameterSpec.SHA512.getDigestAlgorithm(),
+                                ((MGF1ParameterSpec) producedSpec.getMGFParameters())
+                                        .getDigestAlgorithm());
+                        assertArrayEquals(PSpecified.DEFAULT.getValue(),
+                                ((PSpecified) producedSpec.getPSource()).getValue());
+
+                        params = AlgorithmParameters.getInstance("OAEP", p);
+                        params.init(TestUtils.decodeBase64(ENCODED_DATA_MIXED_EXPLICIT_DEFAULTS));
+                        producedSpec = params.getParameterSpec(OAEPParameterSpec.class);
+
+                        assertEquals("SHA-1", producedSpec.getDigestAlgorithm());
+                        assertEquals("MGF1", producedSpec.getMGFAlgorithm());
+                        assertEquals(MGF1ParameterSpec.SHA512.getDigestAlgorithm(),
+                                ((MGF1ParameterSpec) producedSpec.getMGFParameters())
+                                        .getDigestAlgorithm());
+                        assertArrayEquals(PSpecified.DEFAULT.getValue(),
+                                ((PSpecified) producedSpec.getPSource()).getValue());
+                    }
+                });
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestDH.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestDH.java
new file mode 100644
index 0000000..c316d94
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestDH.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.KeyPair;
+import javax.crypto.spec.DHPrivateKeySpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyFactoryTestDH extends AbstractKeyFactoryTest<DHPublicKeySpec, DHPrivateKeySpec> {
+
+    public KeyFactoryTestDH() {
+        super("DH", DHPublicKeySpec.class, DHPrivateKeySpec.class);
+    }
+
+    @Override
+    protected void check(KeyPair keyPair) throws Exception {
+        new KeyAgreementHelper("DH").test(keyPair);
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestDSA.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestDSA.java
new file mode 100644
index 0000000..d4e6984
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestDSA.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.KeyPair;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyFactoryTestDSA extends
+        AbstractKeyFactoryTest<DSAPublicKeySpec, DSAPrivateKeySpec> {
+
+    public KeyFactoryTestDSA() {
+        super("DSA", DSAPublicKeySpec.class, DSAPrivateKeySpec.class);
+    }
+
+    @Override
+    protected void check(KeyPair keyPair) throws Exception {
+        new SignatureHelper("DSA").test(keyPair);
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
new file mode 100644
index 0000000..15593ca
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyFactoryTestRSA extends
+        AbstractKeyFactoryTest<RSAPublicKeySpec, RSAPrivateKeySpec> {
+
+    @SuppressWarnings("unchecked")
+    public KeyFactoryTestRSA() {
+        super("RSA", RSAPublicKeySpec.class, RSAPrivateKeySpec.class);
+    }
+
+    @Override
+    protected void check(KeyPair keyPair) throws Exception {
+        new CipherAsymmetricCryptHelper("RSA").test(keyPair);
+    }
+
+    @Test
+    public void testExtraBufferSpace_Private() throws Exception {
+        PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+        byte[] encoded = privateKey.getEncoded();
+        byte[] longBuffer = new byte[encoded.length + 147];
+        System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
+        KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
+    }
+
+    @Test
+    public void testExtraBufferSpace_Public() throws Exception {
+        PublicKey publicKey = DefaultKeys.getPublicKey("RSA");
+        byte[] encoded = publicKey.getEncoded();
+        byte[] longBuffer = new byte[encoded.length + 147];
+        System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
+        KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(longBuffer));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java
new file mode 100644
index 0000000..5687b44
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java
@@ -0,0 +1,468 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyPairGeneratorTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    @Test
+    public void test_getInstance() throws Exception {
+        ServiceTester
+                .test("KeyPairGenerator")
+                // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for
+                // signature verification. It's OKish not to test here because it's tested by
+                // cts/tests/tests/keystore.
+                .skipProvider("AndroidKeyStore")
+                // The SunEC provider tries to pass a sun-only AlgorithmParameterSpec to the default
+                // AlgorithmParameters:EC when its KeyPairGenerator is initialized.  Since Conscrypt
+                // is the highest-ranked provider when running our tests, its implementation of
+                // AlgorithmParameters:EC is returned, and it doesn't understand the special
+                // AlgorithmParameterSpec, so the KeyPairGenerator can't be initialized.
+                .skipProvider("SunEC")
+                // The SunPKCS11-NSS provider on OpenJDK 7 attempts to delegate to the SunEC
+                // provider, which doesn't exist on OpenJDK 7, and thus totally fails.  This appears
+                // to be a bug introduced into later revisions of OpenJDK 7.
+                .skipProvider("SunPKCS11-NSS")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider provider, String algorithm) throws Exception {
+                        AlgorithmParameterSpec params = null;
+
+                        if ("DH".equals(algorithm) || "DiffieHellman".equalsIgnoreCase(algorithm)) {
+                            params = getDHParams();
+                        }
+                        // KeyPairGenerator.getInstance(String)
+                        KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(algorithm);
+                        assertEquals(algorithm, kpg1.getAlgorithm());
+                        if (params != null) {
+                            kpg1.initialize(params);
+                        }
+                        test_KeyPairGenerator(kpg1);
+
+                        // KeyPairGenerator.getInstance(String, Provider)
+                        KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(algorithm, provider);
+                        assertEquals(algorithm, kpg2.getAlgorithm());
+                        assertEquals(provider, kpg2.getProvider());
+                        if (params != null) {
+                            kpg2.initialize(params);
+                        }
+                        test_KeyPairGenerator(kpg2);
+
+                        // KeyPairGenerator.getInstance(String, String)
+                        KeyPairGenerator kpg3 =
+                                KeyPairGenerator.getInstance(algorithm, provider.getName());
+                        assertEquals(algorithm, kpg3.getAlgorithm());
+                        assertEquals(provider, kpg3.getProvider());
+                        if (params != null) {
+                            kpg3.initialize(params);
+                        }
+                        test_KeyPairGenerator(kpg3);
+                    }
+                });
+    }
+
+    private static final Map<String, List<Integer>> KEY_SIZES
+            = new HashMap<String, List<Integer>>();
+    private static void putKeySize(String algorithm, int keySize) {
+        algorithm = algorithm.toUpperCase();
+        List<Integer> keySizes = KEY_SIZES.get(algorithm);
+        if (keySizes == null) {
+            keySizes = new ArrayList<Integer>();
+            KEY_SIZES.put(algorithm, keySizes);
+        }
+        keySizes.add(keySize);
+    }
+    private static List<Integer> getKeySizes(String algorithm) throws Exception {
+        algorithm = algorithm.toUpperCase();
+        List<Integer> keySizes = KEY_SIZES.get(algorithm);
+        if (keySizes == null) {
+            throw new Exception("Unknown key sizes for KeyPairGenerator." + algorithm);
+        }
+        return keySizes;
+    }
+    static {
+        putKeySize("DSA", 512);
+        putKeySize("DSA", 512+64);
+        putKeySize("DSA", 1024);
+        putKeySize("RSA", 512);
+        putKeySize("RSASSA-PSS", 512);
+        putKeySize("DH", 512);
+        putKeySize("DH", 512+64);
+        putKeySize("DH", 1024);
+        putKeySize("DiffieHellman", 512);
+        putKeySize("DiffieHellman", 512+64);
+        putKeySize("DiffieHellman", 1024);
+        putKeySize("EC", 224);
+        putKeySize("EC", 256);
+        putKeySize("EC", 384);
+        putKeySize("EC", 521);
+    }
+
+    /** Elliptic Curve Crypto named curves that should be supported. */
+    private static final String[] EC_NAMED_CURVES = {
+        // NIST P-256 aka SECG secp256r1 aka ANSI X9.62 prime256v1
+        "secp256r1", "prime256v1",
+        // NIST P-521 aka SECG secp521r1
+        "secp521r1",
+    };
+
+    private void test_KeyPairGenerator(KeyPairGenerator kpg) throws Exception {
+        // without a call to initialize
+        test_KeyPair(kpg, kpg.genKeyPair());
+        test_KeyPair(kpg, kpg.generateKeyPair());
+
+        String algorithm = kpg.getAlgorithm();
+
+        // TODO: detect if we're running in vogar and run the full test
+        if ("DH".equals(algorithm) || "DiffieHellman".equalsIgnoreCase(algorithm)) {
+            // Disabled because this takes too long on devices.
+            // TODO: Re-enable DH test. http://b/5513723.
+            return;
+        }
+
+        List<Integer> keySizes = getKeySizes(algorithm);
+        for (int keySize : keySizes) {
+            // TODO(flooey): Remove when we don't support Java 6 anymore
+            if ("DSA".equals(algorithm)
+                    && ("SUN".equalsIgnoreCase(kpg.getProvider().getName())
+                        || "SunPKCS11-NSS".equalsIgnoreCase(kpg.getProvider().getName()))
+                    && keySize != 512 && keySize != 1024) {
+                // The Sun provider doesn't support DSA in all the key sizes, so ignore
+                // the uncommon ones.
+                continue;
+            }
+            if ("EC".equals(algorithm)
+                    && "SunPKCS11-NSS".equalsIgnoreCase(kpg.getProvider().getName())
+                    && keySize == 224) {
+                // TODO(flooey): Remove when we stop supporting Java 6
+                // This Sun provider doesn't support 224-bit EC keys
+                continue;
+            }
+            kpg.initialize(keySize);
+            test_KeyPair(kpg, kpg.genKeyPair());
+            test_KeyPair(kpg, kpg.generateKeyPair());
+
+            kpg.initialize(keySize, (SecureRandom) null);
+            test_KeyPair(kpg, kpg.genKeyPair());
+            test_KeyPair(kpg, kpg.generateKeyPair());
+
+            kpg.initialize(keySize, new SecureRandom());
+            test_KeyPair(kpg, kpg.genKeyPair());
+            test_KeyPair(kpg, kpg.generateKeyPair());
+        }
+
+        if ("EC".equals(algorithm) || "ECDH".equals(algorithm) || "ECDSA".equals(algorithm)) {
+            if ("SunPKCS11-NSS".equalsIgnoreCase(kpg.getProvider().getName())) {
+                // SunPKCS11 doesn't support some of the named curves that we expect, so it
+                // fails.  Skip it.
+                return;
+            }
+            for (String curveName : EC_NAMED_CURVES) {
+                kpg.initialize(new ECGenParameterSpec(curveName));
+                test_KeyPair(kpg, kpg.genKeyPair());
+                test_KeyPair(kpg, kpg.generateKeyPair());
+
+                kpg.initialize(new ECGenParameterSpec(curveName), (SecureRandom) null);
+                test_KeyPair(kpg, kpg.genKeyPair());
+                test_KeyPair(kpg, kpg.generateKeyPair());
+
+                kpg.initialize(new ECGenParameterSpec(curveName), new SecureRandom());
+                test_KeyPair(kpg, kpg.genKeyPair());
+                test_KeyPair(kpg, kpg.generateKeyPair());
+            }
+        }
+    }
+
+    private void test_KeyPair(KeyPairGenerator kpg, KeyPair kp) throws Exception {
+        assertNotNull(kp);
+        test_Key(kpg, kp.getPrivate());
+        test_Key(kpg, kp.getPublic());
+    }
+
+    private void test_Key(KeyPairGenerator kpg, Key k) throws Exception {
+        String expectedAlgorithm = kpg.getAlgorithm().toUpperCase(Locale.ROOT);
+        if (StandardNames.IS_RI && expectedAlgorithm.equals("DIFFIEHELLMAN")) {
+            expectedAlgorithm = "DH";
+        }
+        assertEquals(expectedAlgorithm, k.getAlgorithm().toUpperCase());
+        if (expectedAlgorithm.equals("DH")) {
+            if (k instanceof DHPublicKey) {
+                DHPublicKey dhPub = (DHPublicKey) k;
+                assertEquals(dhPub.getParams().getP(), getDHParams().getP());
+            } else if (k instanceof DHPrivateKey) {
+                DHPrivateKey dhPriv = (DHPrivateKey) k;
+                assertEquals(dhPriv.getParams().getP(), getDHParams().getP());
+            } else {
+                fail("not a public or private key!?");
+            }
+        }
+        if (kpg.getProvider().getName().equalsIgnoreCase("SunMSCAPI")
+                && expectedAlgorithm.equals("RSA")) {
+            // The SunMSCAPI RSA keys don't provide encoded versions at all, nor are they
+            // serializable, so just skip them.
+            return;
+        }
+        assertNotNull(k.getEncoded());
+        assertNotNull(k.getFormat());
+
+        // Test serialization
+        // SunPKCS11-NSS on Java 6 replaces serialized keys with one from the default provider,
+        // so the deserialized key doesn't match the original.
+        if (!kpg.getProvider().getName().equalsIgnoreCase("SunPKCS11-NSS")) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream(16384);
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(k);
+
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            Key inflatedKey = (Key) ois.readObject();
+
+            assertEquals("Provider: " + kpg.getProvider(), k, inflatedKey);
+        }
+
+        test_KeyWithAllKeyFactories(k);
+    }
+
+    private void test_KeyWithAllKeyFactories(Key k) throws Exception {
+        byte[] encoded = k.getEncoded();
+
+        String keyAlgo = k.getAlgorithm();
+        for (Provider p : Security.getProviders()) {
+            Set<Provider.Service> services = p.getServices();
+            for (Provider.Service service : services) {
+                if (!"KeyFactory".equals(service.getType())) {
+                    continue;
+                }
+                if (!service.getAlgorithm().equals(keyAlgo)) {
+                    continue;
+                }
+                if (p.getName().equalsIgnoreCase("AndroidKeyStore")) {
+                    // AndroidKeyStore only works with its own keys
+                    continue;
+                }
+                if ("EC".equals(k.getAlgorithm())
+                        && "SunPKCS11-NSS".equalsIgnoreCase(p.getName())) {
+                    // SunPKCS11 doesn't support some of the named curves that we expect, so it
+                    // fails.  Skip testing that combination.
+                    continue;
+                }
+                if ("DH".equals(k.getAlgorithm())
+                        && "SunPKCS11-NSS".equalsIgnoreCase(p.getName())) {
+                    // SunPKCS11 omits the privateValueLength field from the DHParameter
+                    // structure in its encoded keys, unlike every other provider seen,
+                    // so ignore it.
+                    continue;
+                }
+
+                if ("PKCS#8".equals(k.getFormat())) {
+                    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
+                    KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p);
+                    PrivateKey privKey = kf.generatePrivate(spec);
+                    assertNotNull(k.getAlgorithm() + ", provider=" + p.getName(), privKey);
+
+                    /*
+                     * EC keys are unique because they can have explicit parameters or a curve
+                     * name. Check them specially so this test can continue to function.
+                     */
+                    if (k instanceof ECPrivateKey) {
+                        assertECPrivateKeyEquals((ECPrivateKey) k, (ECPrivateKey) privKey);
+                    } else {
+                        assertEquals(k.getAlgorithm() + ", provider=" + p.getName(),
+                                TestUtils.encodeBase64(encoded),
+                                TestUtils.encodeBase64(privKey.getEncoded()));
+                    }
+                } else if ("X.509".equals(k.getFormat())) {
+                    X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
+                    KeyFactory kf = KeyFactory.getInstance(k.getAlgorithm(), p);
+                    PublicKey pubKey = kf.generatePublic(spec);
+                    assertNotNull(pubKey);
+                    assertEquals(k.getAlgorithm() + ", provider=" + p.getName(),
+                            TestUtils.encodeBase64(encoded),
+                            TestUtils.encodeBase64(pubKey.getEncoded()));
+                }
+            }
+        }
+    }
+
+    private static void assertECPrivateKeyEquals(ECPrivateKey expected, ECPrivateKey actual) {
+        assertEquals(expected.getS(), actual.getS());
+        assertECParametersEquals(expected.getParams(), actual.getParams());
+    }
+
+    private static void assertECParametersEquals(ECParameterSpec expected, ECParameterSpec actual) {
+        assertEquals(expected.getCurve(), actual.getCurve());
+        assertEquals(expected.getGenerator(), actual.getGenerator());
+        assertEquals(expected.getOrder(), actual.getOrder());
+        assertEquals(expected.getCofactor(), actual.getCofactor());
+    }
+
+    /**
+     * DH parameters pre-generated so that the test doesn't take too long.
+     * These parameters were generated with:
+     *
+     * openssl gendh 512 | openssl dhparams -C
+     */
+    private static DHParameterSpec getDHParams() {
+        BigInteger p = new BigInteger("E7AB1768BD75CD24700960FFA32D3F1557344E587101237532CC641646ED7A7C104743377F6D46251698B665CE2A6CBAB6714C2569A7D2CA22C0CF03FA40AC93", 16);
+        BigInteger g = new BigInteger("02", 16);
+        return new DHParameterSpec(p, g, 512);
+    }
+
+    private static final BigInteger DSA_P = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9,
+        (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe,
+        (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e,
+        (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c,
+        (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85,
+        (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8,
+        (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6,
+        (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44,
+        (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8,
+        (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c,
+        (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9,
+        (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3,
+        (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c,
+        (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58,
+        (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b,
+        (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40,
+        (byte) 0x23,
+    });
+
+    private static final BigInteger DSA_Q = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50,
+        (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01,
+        (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f,
+    });
+
+    private static final BigInteger DSA_G = new BigInteger(new byte[] {
+        (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e,
+        (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10,
+        (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21,
+        (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e,
+        (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b,
+        (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc,
+        (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80,
+        (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e,
+        (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a,
+        (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8,
+        (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31,
+        (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e,
+        (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b,
+        (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81,
+        (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e,
+        (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51,
+    });
+
+    @Test
+    public void testDSAGeneratorWithParams() throws Exception {
+        final DSAParameterSpec dsaSpec = new DSAParameterSpec(DSA_P, DSA_Q, DSA_G);
+
+        ServiceTester.test("KeyPairGenerator").withAlgorithm("DSA").run(new ServiceTester.Test() {
+            @Override
+            public void test(Provider p, String algorithm) throws Exception {
+                final KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", p);
+                kpg.initialize(dsaSpec);
+                KeyPair pair = kpg.generateKeyPair();
+                DSAPrivateKey privKey = (DSAPrivateKey) pair.getPrivate();
+                DSAPublicKey pubKey = (DSAPublicKey) pair.getPublic();
+
+                DSAParams actualParams = privKey.getParams();
+                assertNotNull("DSA params should not be null", actualParams);
+
+                assertEquals("DSA P should be the same as supplied", DSA_P, actualParams.getP());
+                assertEquals("DSA Q should be the same as supplied", DSA_Q, actualParams.getQ());
+                assertEquals("DSA G should be the same as supplied", DSA_G, actualParams.getG());
+
+                actualParams = pubKey.getParams();
+                assertNotNull("DSA params should not be null", actualParams);
+
+                assertEquals("DSA P should be the same as supplied", DSA_P, actualParams.getP());
+                assertEquals("DSA Q should be the same as supplied", DSA_Q, actualParams.getQ());
+                assertEquals("DSA G should be the same as supplied", DSA_G, actualParams.getG());
+            }
+        });
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestDH.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestDH.java
new file mode 100644
index 0000000..16b23f7
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestDH.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyPairGeneratorTestDH extends AbstractKeyPairGeneratorTest {
+
+    public KeyPairGeneratorTestDH() {
+        super("DH", new KeyAgreementHelper("DH"));
+    }
+
+    // Broken Test: Takes ages due to DH computations. Disabling for now.
+    @Override
+    public void testKeyPairGenerator() throws Exception {
+        super.testKeyPairGenerator();
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestDSA.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestDSA.java
new file mode 100644
index 0000000..b97adce
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestDSA.java
@@ -0,0 +1,32 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyPairGeneratorTestDSA extends AbstractKeyPairGeneratorTest {
+
+    public KeyPairGeneratorTestDSA() {
+        super("DSA", new SignatureHelper("DSA"));
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestRSA.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestRSA.java
new file mode 100644
index 0000000..2e9d074
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTestRSA.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyPairGeneratorTestRSA extends AbstractKeyPairGeneratorTest {
+
+    @SuppressWarnings("unchecked")
+    public KeyPairGeneratorTestRSA() {
+        super("RSA", new CipherAsymmetricCryptHelper("RSA"));
+    }
+
+}
+
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/MessageDigestTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/MessageDigestTest.java
new file mode 100644
index 0000000..83590e9
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/MessageDigestTest.java
@@ -0,0 +1,282 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public final class MessageDigestTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private final byte[] sha_456 = {
+            -24,   9, -59, -47,  -50,  -92, 123, 69, -29,  71,
+              1, -46,  63,  96, -118, -102,  88,  3,  77, -55
+    };
+
+    @Test
+    public void testShaReset() throws NoSuchAlgorithmException {
+        MessageDigest sha = MessageDigest.getInstance("SHA");
+        sha.update(new byte[] { 1, 2, 3 });
+        sha.reset();
+        sha.update(new byte[] { 4, 5, 6 });
+        assertEquals(Arrays.toString(sha_456), Arrays.toString(sha.digest()));
+    }
+
+    @Test
+    public void test_getInstance() throws Exception {
+        ServiceTester.test("MessageDigest").run(new ServiceTester.Test() {
+            @Override
+            public void test(Provider provider, String algorithm) throws Exception {
+                // MessageDigest.getInstance(String)
+                MessageDigest md1 = MessageDigest.getInstance(algorithm);
+                assertEquals(algorithm, md1.getAlgorithm());
+                test_MessageDigest(md1);
+
+                // MessageDigest.getInstance(String, Provider)
+                MessageDigest md2 = MessageDigest.getInstance(algorithm, provider);
+                assertEquals(algorithm, md2.getAlgorithm());
+                assertEquals(provider, md2.getProvider());
+                test_MessageDigest(md2);
+
+                // MessageDigest.getInstance(String, String)
+                MessageDigest md3 = MessageDigest.getInstance(algorithm, provider.getName());
+                assertEquals(algorithm, md3.getAlgorithm());
+                assertEquals(provider, md3.getProvider());
+                test_MessageDigest(md3);
+            }
+        });
+    }
+
+    private static final Map<String, Map<String, byte[]>> EXPECTATIONS
+            = new HashMap<String, Map<String, byte[]>>();
+    private static void putExpectation(String algorithm, String inputName, byte[] expected) {
+        algorithm = algorithm.toUpperCase();
+        Map<String, byte[]> expectations = EXPECTATIONS.get(algorithm);
+        if (expectations == null) {
+            expectations = new HashMap<String, byte[]>();
+            EXPECTATIONS.put(algorithm, expectations);
+        }
+        expectations.put(inputName, expected);
+    }
+    private static Map<String, byte[]> getExpectations(String algorithm) throws Exception {
+        algorithm = algorithm.toUpperCase();
+        Map<String, byte[]> expectations = EXPECTATIONS.get(algorithm);
+        if (expectations == null) {
+            throw new Exception("No expectations for MessageDigest." + algorithm);
+        }
+        return expectations;
+    }
+    private static final String INPUT_EMPTY = "empty";
+    private static final String INPUT_256MB = "256mb";
+    static {
+        // INPUT_EMPTY
+        putExpectation("MD2",
+                       INPUT_EMPTY,
+                       new byte[] { -125, 80, -27, -93, -30, 76, 21, 61,
+                                    -14, 39, 92, -97, -128, 105, 39, 115 });
+        putExpectation("MD5",
+                       INPUT_EMPTY,
+                       new byte[] { -44, 29, -116, -39, -113, 0, -78, 4,
+                                    -23, -128, 9, -104, -20, -8, 66, 126 });
+        putExpectation("SHA",
+                       INPUT_EMPTY,
+                       new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
+                                    50, 85, -65, -17, -107, 96, 24, -112,
+                                    -81, -40, 7, 9});
+        putExpectation("SHA1",
+                       INPUT_EMPTY,
+                       new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
+                                    50, 85, -65, -17, -107, 96, 24, -112,
+                                    -81, -40, 7, 9});
+        putExpectation("SHA-1",
+                       INPUT_EMPTY,
+                       new byte[] { -38, 57, -93, -18, 94, 107, 75, 13,
+                                    50, 85, -65, -17, -107, 96, 24, -112,
+                                    -81, -40, 7, 9});
+        putExpectation("SHA-224",
+                       INPUT_EMPTY,
+                       new byte[] { -47, 74, 2, -116, 42, 58, 43, -55, 71,
+                                    97, 2, -69, 40, -126, 52, -60, 21,
+                                    -94, -80, 31, -126, -114, -90, 42,
+                                    -59, -77, -28, 47});
+        putExpectation("SHA-256",
+                       INPUT_EMPTY,
+                       new byte[] { -29, -80, -60, 66, -104, -4, 28, 20,
+                                    -102, -5, -12, -56, -103, 111, -71, 36,
+                                    39, -82, 65, -28, 100, -101, -109, 76,
+                                    -92, -107, -103, 27, 120, 82, -72, 85 });
+        putExpectation("SHA-384",
+                       INPUT_EMPTY,
+                       new byte[] { 56, -80, 96, -89, 81, -84, -106, 56,
+                                    76, -39, 50, 126, -79, -79, -29, 106,
+                                    33, -3, -73, 17, 20, -66, 7, 67,
+                                    76, 12, -57, -65, 99, -10, -31, -38,
+                                    39, 78, -34, -65, -25, 111, 101, -5,
+                                    -43, 26, -46, -15, 72, -104, -71, 91 });
+        putExpectation("SHA-512",
+                       INPUT_EMPTY,
+                       new byte[] { -49, -125, -31, 53, 126, -17, -72, -67,
+                                    -15, 84, 40, 80, -42, 109, -128, 7,
+                                    -42, 32, -28, 5, 11, 87, 21, -36,
+                                    -125, -12, -87, 33, -45, 108, -23, -50,
+                                    71, -48, -47, 60, 93, -123, -14, -80,
+                                    -1, -125, 24, -46, -121, 126, -20, 47,
+                                    99, -71, 49, -67, 71, 65, 122, -127,
+                                    -91, 56, 50, 122, -7, 39, -38, 62 });
+        putExpectation("SHA-512/224", INPUT_EMPTY,
+                TestUtils.decodeHex("6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4"));
+        putExpectation("SHA-512/256", INPUT_EMPTY,
+                TestUtils.decodeHex(
+                        "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"));
+        putExpectation("SHA3-224", INPUT_EMPTY,
+                TestUtils.decodeHex("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"));
+        putExpectation("SHA3-256", INPUT_EMPTY,
+                TestUtils.decodeHex(
+                        "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"));
+        putExpectation("SHA3-384", INPUT_EMPTY,
+                TestUtils.decodeHex(
+                        "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"
+                        + "c3713831264adb47fb6bd1e058d5f004"));
+        putExpectation("SHA3-512", INPUT_EMPTY,
+                TestUtils.decodeHex(
+                        "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"
+                        + "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"));
+
+        // Regression test for a SHA-1 problem with inputs larger than 256 MiB. http://b/4501620
+        // In mid-2013 this takes 3 minutes even on the host, so let's not run it on devices.
+        if (System.getenv("ANDROID_BUILD_TOP") != null) {
+            // INPUT_256MB
+            putExpectation("MD2",
+                           INPUT_256MB,
+                           new byte[] { -63, -120, 6, 67, 12, -87, -39, -11,
+                                        -67, -3, -31, -41, -91, 16, -35, 91 });
+            putExpectation("MD5",
+                           INPUT_256MB,
+                           new byte[] { 31, 80, 57, -27, 11, -42, 107, 41,
+                                        12, 86, 104, 77, -123, 80, -58, -62 });
+            putExpectation("SHA",
+                           INPUT_256MB,
+                           new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
+                                        -33, 108, -120, 71, -76, -86, 105, 101,
+                                        86, 108, 92, 117 });
+            putExpectation("SHA-1",
+                           INPUT_256MB,
+                           new byte[] { 123, -111, -37, -36, 86, -59, 120, 30,
+                                        -33, 108, -120, 71, -76, -86, 105, 101,
+                                        86, 108, 92, 117 });
+            putExpectation("SHA-224",
+                           INPUT_256MB,
+                           new byte[] { -78, 82, 5, -71, 57, 119, 77, -32,
+                                        -62, -74, -40, 64, -57, 79, 40, 116,
+                                        -18, 48, -69, 45, 18, -94, 111, 114,
+                                        -45, -93, 43, -11 });
+            putExpectation("SHA-256",
+                           INPUT_256MB,
+                           new byte[] { -90, -41, 42, -57, 105, 15, 83, -66,
+                                        106, -28, 107, -88, -123, 6, -67, -105,
+                                        48, 42, 9, 63, 113, 8, 71, 43,
+                                        -39, -17, -61, -50, -3, -96, 100, -124 });
+            putExpectation("SHA-384",
+                           INPUT_256MB,
+                           new byte[] { 71, 72, 77, -83, -110, 22, -118, -18,
+                                        -58, 119, 115, 74, -67, -36, 84, 122,
+                                        -105, -67, -75, 15, -33, 37, 78, -95,
+                                        4, 118, -53, 106, 65, -115, -19, 121,
+                                        -59, -94, -45, -111, -124, 35, 35, 60,
+                                        67, -34, 62, 106, -16, 122, -110, -14 });
+            putExpectation("SHA-512",
+                           INPUT_256MB,
+                           new byte[] { 36, 7, -120, 39, -87, -87, 84, -40,
+                                        -66, 114, 62, -73, 107, 101, -117, -12,
+                                        -124, 20, 109, 103, -92, 125, 111, 102,
+                                        12, 114, -68, 100, 30, 25, -88, 62,
+                                        108, 56, 9, -107, 89, -25, -50, 118,
+                                        -87, 100, 13, 37, -14, 66, -40, -97,
+                                        105, -27, 79, -62, 53, -31, 83, 40,
+                                        4, 57, 90, -81, 63, -77, -42, 113 });
+        }
+    }
+
+    private void test_MessageDigest(MessageDigest md) throws Exception {
+        String algorithm = md.getAlgorithm();
+        for (Map.Entry<String, byte[]> expectation : getExpectations(algorithm).entrySet()) {
+            String inputName = expectation.getKey();
+            byte[] expected = expectation.getValue();
+            byte[] actual;
+            if (inputName.equals(INPUT_EMPTY)) {
+                actual = md.digest();
+            } else if (inputName.equals(INPUT_256MB)) {
+                byte[] mb = new byte[1 * 1024 * 1024];
+                for (int i = 0; i < 256; i++) {
+                    md.update(mb);
+                }
+                actual = md.digest();
+            } else {
+                throw new AssertionError(inputName);
+            }
+            assertEquals(algorithm, javaBytes(expected), javaBytes(actual));
+            assertEquals(algorithm, expected.length, md.getDigestLength());
+        }
+    }
+
+    private String javaBytes(byte[] bytes) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("new byte[] { ");
+        for (byte b : bytes) {
+            buf.append(b);
+            buf.append(", ");
+        }
+        buf.append(" }");
+        return buf.toString();
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java
new file mode 100644
index 0000000..ada0405
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java
@@ -0,0 +1,3224 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.testing.BrokenProvider;
+import com.android.org.conscrypt.testing.OpaqueProvider;
+import dalvik.system.VMRuntime;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.ProviderException;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SignatureTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    // 20 bytes for DSA
+    private final byte[] DATA = new byte[20];
+
+    @Test
+    public void test_getInstance() throws Exception {
+        ServiceTester
+                .test("Signature")
+                // Do not test AndroidKeyStore's Signature. It needs an AndroidKeyStore-specific
+                // key. It's OKish not to test AndroidKeyStore's Signature here because it's tested
+                // by cts/tests/test/keystore.
+                .skipProvider("AndroidKeyStore")
+                .skipProvider("AndroidKeyStoreBCWorkaround")
+                // The SunMSCAPI is very strange, including only supporting its own keys,
+                // so don't test it.
+                .skipProvider("SunMSCAPI")
+                // SunPKCS11-NSS has a problem where failed verifications can leave the
+                // operation open, which results in future init() calls to throw an exception.
+                // This appears to be a problem in the underlying library (see
+                // https://bugs.openjdk.java.net/browse/JDK-8044554), but skip verifying it all
+                // the same.
+                .skipProvider("SunPKCS11-NSS")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider provider, String algorithm) throws Exception {
+                        KeyPair kp = keyPair(algorithm);
+                        // Signature.getInstance(String)
+                        Signature sig1 = Signature.getInstance(algorithm);
+                        assertEquals(algorithm, sig1.getAlgorithm());
+                        test_Signature(sig1, kp);
+
+                        // Signature.getInstance(String, Provider)
+                        Signature sig2 = Signature.getInstance(algorithm, provider);
+                        assertEquals(algorithm, sig2.getAlgorithm());
+                        assertEquals(provider, sig2.getProvider());
+                        test_Signature(sig2, kp);
+
+                        // Signature.getInstance(String, String)
+                        Signature sig3 = Signature.getInstance(algorithm, provider.getName());
+                        assertEquals(algorithm, sig3.getAlgorithm());
+                        assertEquals(provider, sig3.getProvider());
+                        test_Signature(sig3, kp);
+                    }
+                });
+    }
+
+    private final Map<String, KeyPair> keypairAlgorithmToInstance
+            = new HashMap<String, KeyPair>();
+
+    private KeyPair keyPair(String sigAlgorithm) throws Exception {
+        String sigAlgorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
+        if (sigAlgorithmUpperCase.endsWith("ENCRYPTION")) {
+            sigAlgorithm = sigAlgorithm.substring(0, sigAlgorithm.length()-"ENCRYPTION".length());
+            sigAlgorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
+        }
+
+        String kpAlgorithm;
+        // note ECDSA must be before DSA
+        if (sigAlgorithmUpperCase.endsWith("ECDSA")
+                || sigAlgorithmUpperCase.endsWith("ECDSAINP1363FORMAT")) {
+            kpAlgorithm = "EC";
+        } else if (sigAlgorithmUpperCase.endsWith("DSA")
+                || sigAlgorithmUpperCase.endsWith("DSAINP1363FORMAT")) {
+            kpAlgorithm = "DSA";
+        } else if (sigAlgorithmUpperCase.endsWith("RSA")
+                || sigAlgorithmUpperCase.endsWith("RSA/PSS")
+                || sigAlgorithmUpperCase.endsWith("RSASSA-PSS")) {
+            kpAlgorithm = "RSA";
+        } else {
+            throw new Exception("Unknown KeyPair algorithm for Signature algorithm "
+                                + sigAlgorithm);
+        }
+
+        KeyPair kp = keypairAlgorithmToInstance.get(kpAlgorithm);
+        if (kp == null) {
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpAlgorithm);
+            if (kpAlgorithm.equals("DSA")) {
+                kpg.initialize(1024);
+            }
+            kp = kpg.generateKeyPair();
+            keypairAlgorithmToInstance.put(kpAlgorithm, kp);
+        }
+        return kp;
+    }
+
+    private AlgorithmParameterSpec getAlgParamSpec(String algorithm) {
+        if (algorithm.equalsIgnoreCase("RSASSA-PSS")) {
+            return PSSParameterSpec.DEFAULT;
+        }
+        return null;
+    }
+
+    private void test_Signature(Signature sig, KeyPair keyPair) throws Exception {
+        AlgorithmParameterSpec params = getAlgParamSpec(sig.getAlgorithm());
+        sig.initSign(keyPair.getPrivate());
+        if (params != null) {
+            sig.setParameter(params);
+        }
+        sig.update(DATA);
+        byte[] signature = sig.sign();
+        assertNotNull(sig.getAlgorithm(), signature);
+        assertTrue(sig.getAlgorithm(), signature.length > 0);
+
+        sig.initVerify(keyPair.getPublic());
+        if (params != null) {
+            sig.setParameter(params);
+        }
+        sig.update(DATA);
+        assertTrue(sig.getAlgorithm(), sig.verify(signature));
+
+        // After verify, should be reusable as if we are after initVerify
+        sig.update(DATA);
+        assertTrue(sig.getAlgorithm(), sig.verify(signature));
+
+        /*
+         * The RI appears to clear out the input data in RawDSA while calling
+         * verify a second time.
+         */
+        if (StandardNames.IS_RI
+                && ("NONEwithDSA".equalsIgnoreCase(sig.getAlgorithm())
+                        || "NONEwithDSAinP1363Format".equalsIgnoreCase(sig.getAlgorithm())
+                        || "RawDSA".equalsIgnoreCase(sig.getAlgorithm()))) {
+            try {
+                sig.verify(signature);
+                fail("Expected RI to have a NONEwithDSA bug");
+            } catch (SignatureException bug) {
+            }
+        } else if (StandardNames.IS_RI && "NONEwithECDSA".equalsIgnoreCase(sig.getAlgorithm())
+                && "SunPKCS11-NSS".equalsIgnoreCase(sig.getProvider().getName())) {
+            // This provider doesn't work properly
+            try {
+                sig.verify(signature);
+                fail("Expected RI to have a NONEwithECDSA bug");
+            } catch (ProviderException bug) {
+            }
+        } else {
+            // Calling Signature.verify a second time should not throw
+            // http://code.google.com/p/android/issues/detail?id=34933
+            sig.verify(signature);
+        }
+
+        if (Conscrypt.isConscrypt(sig.getProvider())) {
+            testSignature_MultipleThreads_Misuse(sig, keyPair.getPrivate());
+        }
+    }
+
+    private static final byte[] PK_BYTES = TestUtils.decodeHex(
+            "30819f300d06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce3001"
+            + "2604218320c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc6"
+            + "4f202fca21099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e6698603901262619"
+            + "4840e0896b1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301"
+            + "0001");
+    private static final byte[] CONTENT = TestUtils.decodeHex(
+            "f2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95030b93ce7260423e5c00"
+            + "fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc00fabd44657669636573"
+            + "00faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f53d19693d480de767e5fb"
+            + "976f3562324006372300fabdfd04e1f51ef3aa00fa8d00000001a203e202859471968cc68835f8a6"
+            + "8dde10f53d19693d480de767e5fb976f356232400637230002bab504e1f51ef5810002c29d28463f"
+            + "0003da8d000001e201eaf2fa9d73656e00fa01edc12e73656e2e7670632e6432004867268c46dd95"
+            + "030b93ce7260423e5c00fabd4d656d6265727300fa018dc12e73656e2e7670632e643100d7c258dc"
+            + "00fabd4465766963657300faa54b65797300fa02b5c12e4d2e4b009471968cc68835f8a68dde10f5"
+            + "3d19693d480de767e5fb976f3562324006372300fabdfd04e1f51ef3aa000003e202859471968cc6"
+            + "8835f8a68dde10f53d19693d480de767e5fb976f3562324006372300000000019a0a9530819f300d"
+            + "06092a864886f70d010101050003818d0030818902818100cd769d178f61475fce30012604218320"
+            + "c77a427121d3b41dd76756c8fc0c428cd15cb754adc85466f47547b1c85623d9c17fc64f202fca21"
+            + "099caf99460c824ad657caa8c2db34996838d32623c4f23c8b6a4e66986039012626194840e0896b"
+            + "1a6ec4f6652484aad04569bb6a885b822a10d700224359c632dc7324520cbb3d020301000100");
+    private static final byte[] SIGNATURE = TestUtils.decodeHex(
+            "b4016456148cd2e9f580470aad63d19c1fee52b38c9dcb5b4d61a7ca369a7277497775d106d86394"
+            + "a69229184333b5a3e6261d5bcebdb02530ca9909f4d790199eae7c140f7db39dee2232191bdf0bfb"
+            + "34fdadc44326b9b3f3fa828652bab07f0362ac141c8c3784ebdec44e0b156a5e7bccdc81a56fe954"
+            + "56ac8c0e4ae12d97");
+
+
+    /**
+     * This should actually fail because the ASN.1 encoding is incorrect. It is
+     * missing the NULL in the AlgorithmIdentifier field.
+     * <p>
+     * http://code.google.com/p/android/issues/detail?id=18566 <br/>
+     * http://b/5038554
+     */
+    @Test
+    public void test18566_AlgorithmOid_MissingNull_Failure() throws Exception {
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(PK_BYTES);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        PublicKey pk = keyFactory.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA");
+        sig.initVerify(pk);
+        sig.update(CONTENT);
+        assertFalse(sig.verify(SIGNATURE));
+    }
+
+    /*
+     * Test vectors generated with this private key:
+     *
+     * -----BEGIN RSA PRIVATE KEY-----
+     * MIIEpAIBAAKCAQEA4Ec+irjyKE/rnnQv+XSPoRjtmGM8kvUq63ouvg075gMpvnZq
+     * 0Q62pRXQ0s/ZvqeTDwwwZTeJn3lYzT6FsB+IGFJNMSWEqUslHjYltUFB7b/uGYgI
+     * 4buX/Hy0m56qr2jpyY19DtxTu8D6ADQ1bWMF+7zDxwAUBThqu8hzyw8+90JfPTPf
+     * ezFa4DbSoLZq/UdQOxab8247UWJRW3Ff2oPeryxYrrmr+zCXw8yd2dvl7ylsF2E5
+     * Ao6KZx5jBW1F9AGI0sQTNJCEXeUsJTTpxrJHjAe9rpKII7YtBmx3cPn2Pz26JH9T
+     * CER0e+eqqF2FO4vSRKzsPePImrRkU6tNJMOsaQIDAQABAoIBADd4R3al8XaY9ayW
+     * DfuDobZ1ZOZIvQWXz4q4CHGG8macJ6nsvdSA8Bl6gNBzCebGqW+SUzHlf4tKxvTU
+     * XtpFojJpwJ/EKMB6Tm7fc4oV3sl/q9Lyu0ehTyDqcvz+TDbgGtp3vRN82NTaELsW
+     * LpSkZilx8XX5hfoYjwVsuX7igW9Dq503R2Ekhs2owWGWwwgYqZXshdOEZ3kSZ7O/
+     * IfJzcQppJYYldoQcW2cSwS1L0govMpmtt8E12l6VFavadufK8qO+gFUdBzt4vxFi
+     * xIrSt/R0OgI47k0lL31efmUzzK5kzLOTYAdaL9HgNOw65c6cQIzL8OJeQRQCFoez
+     * 3UdUroECgYEA9UGIS8Nzeyki1BGe9F4t7izUy7dfRVBaFXqlAJ+Zxzot8HJKxGAk
+     * MGMy6omBd2NFRl3G3x4KbxQK/ztzluaomUrF2qloc0cv43dJ0U6z4HXmKdvrNYMz
+     * im82SdCiZUp6Qv2atr+krE1IHTkLsimwZL3DEcwb4bYxidp8QM3s8rECgYEA6hp0
+     * LduIHO23KIyH442GjdekCdFaQ/RF1Td6C1cx3b/KLa8oqOE81cCvzsM0fXSjniNa
+     * PNljPydN4rlPkt9DgzkR2enxz1jyfeLgj/RZZMcg0+whOdx8r8kSlTzeyy81Wi4s
+     * NaUPrXVMs7IxZkJLo7bjESoriYw4xcFe2yOGkzkCgYBRgo8exv2ZYCmQG68dfjN7
+     * pfCvJ+mE6tiVrOYr199O5FoiQInyzBUa880XP84EdLywTzhqLNzA4ANrokGfVFeS
+     * YtRxAL6TGYSj76Bb7PFBV03AebOpXEqD5sQ/MhTW3zLVEt4ZgIXlMeYWuD/X3Z0f
+     * TiYHwzM9B8VdEH0dOJNYcQKBgQDbT7UPUN6O21P/NMgJMYigUShn2izKBIl3WeWH
+     * wkQBDa+GZNWegIPRbBZHiTAfZ6nweAYNg0oq29NnV1toqKhCwrAqibPzH8zsiiL+
+     * OVeVxcbHQitOXXSh6ajzDndZufwtY5wfFWc+hOk6XvFQb0MVODw41Fy9GxQEj0ch
+     * 3IIyYQKBgQDYEUWTr0FfthLb8ZI3ENVNB0hiBadqO0MZSWjA3/HxHvD2GkozfV/T
+     * dBu8lkDkR7i2tsR8OsEgQ1fTsMVbqShr2nP2KSlvX6kUbYl2NX08dR51FIaWpAt0
+     * aFyCzjCQLWOdck/yTV4ulAfuNO3tLjtN9lqpvP623yjQe6aQPxZXaA==
+     * -----END RSA PRIVATE KEY-----
+     *
+     */
+
+    private static final BigInteger RSA_2048_modulus = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xe0, (byte) 0x47, (byte) 0x3e, (byte) 0x8a, (byte) 0xb8, (byte) 0xf2, (byte) 0x28,
+        (byte) 0x4f, (byte) 0xeb, (byte) 0x9e, (byte) 0x74, (byte) 0x2f, (byte) 0xf9, (byte) 0x74, (byte) 0x8f,
+        (byte) 0xa1, (byte) 0x18, (byte) 0xed, (byte) 0x98, (byte) 0x63, (byte) 0x3c, (byte) 0x92, (byte) 0xf5,
+        (byte) 0x2a, (byte) 0xeb, (byte) 0x7a, (byte) 0x2e, (byte) 0xbe, (byte) 0x0d, (byte) 0x3b, (byte) 0xe6,
+        (byte) 0x03, (byte) 0x29, (byte) 0xbe, (byte) 0x76, (byte) 0x6a, (byte) 0xd1, (byte) 0x0e, (byte) 0xb6,
+        (byte) 0xa5, (byte) 0x15, (byte) 0xd0, (byte) 0xd2, (byte) 0xcf, (byte) 0xd9, (byte) 0xbe, (byte) 0xa7,
+        (byte) 0x93, (byte) 0x0f, (byte) 0x0c, (byte) 0x30, (byte) 0x65, (byte) 0x37, (byte) 0x89, (byte) 0x9f,
+        (byte) 0x79, (byte) 0x58, (byte) 0xcd, (byte) 0x3e, (byte) 0x85, (byte) 0xb0, (byte) 0x1f, (byte) 0x88,
+        (byte) 0x18, (byte) 0x52, (byte) 0x4d, (byte) 0x31, (byte) 0x25, (byte) 0x84, (byte) 0xa9, (byte) 0x4b,
+        (byte) 0x25, (byte) 0x1e, (byte) 0x36, (byte) 0x25, (byte) 0xb5, (byte) 0x41, (byte) 0x41, (byte) 0xed,
+        (byte) 0xbf, (byte) 0xee, (byte) 0x19, (byte) 0x88, (byte) 0x08, (byte) 0xe1, (byte) 0xbb, (byte) 0x97,
+        (byte) 0xfc, (byte) 0x7c, (byte) 0xb4, (byte) 0x9b, (byte) 0x9e, (byte) 0xaa, (byte) 0xaf, (byte) 0x68,
+        (byte) 0xe9, (byte) 0xc9, (byte) 0x8d, (byte) 0x7d, (byte) 0x0e, (byte) 0xdc, (byte) 0x53, (byte) 0xbb,
+        (byte) 0xc0, (byte) 0xfa, (byte) 0x00, (byte) 0x34, (byte) 0x35, (byte) 0x6d, (byte) 0x63, (byte) 0x05,
+        (byte) 0xfb, (byte) 0xbc, (byte) 0xc3, (byte) 0xc7, (byte) 0x00, (byte) 0x14, (byte) 0x05, (byte) 0x38,
+        (byte) 0x6a, (byte) 0xbb, (byte) 0xc8, (byte) 0x73, (byte) 0xcb, (byte) 0x0f, (byte) 0x3e, (byte) 0xf7,
+        (byte) 0x42, (byte) 0x5f, (byte) 0x3d, (byte) 0x33, (byte) 0xdf, (byte) 0x7b, (byte) 0x31, (byte) 0x5a,
+        (byte) 0xe0, (byte) 0x36, (byte) 0xd2, (byte) 0xa0, (byte) 0xb6, (byte) 0x6a, (byte) 0xfd, (byte) 0x47,
+        (byte) 0x50, (byte) 0x3b, (byte) 0x16, (byte) 0x9b, (byte) 0xf3, (byte) 0x6e, (byte) 0x3b, (byte) 0x51,
+        (byte) 0x62, (byte) 0x51, (byte) 0x5b, (byte) 0x71, (byte) 0x5f, (byte) 0xda, (byte) 0x83, (byte) 0xde,
+        (byte) 0xaf, (byte) 0x2c, (byte) 0x58, (byte) 0xae, (byte) 0xb9, (byte) 0xab, (byte) 0xfb, (byte) 0x30,
+        (byte) 0x97, (byte) 0xc3, (byte) 0xcc, (byte) 0x9d, (byte) 0xd9, (byte) 0xdb, (byte) 0xe5, (byte) 0xef,
+        (byte) 0x29, (byte) 0x6c, (byte) 0x17, (byte) 0x61, (byte) 0x39, (byte) 0x02, (byte) 0x8e, (byte) 0x8a,
+        (byte) 0x67, (byte) 0x1e, (byte) 0x63, (byte) 0x05, (byte) 0x6d, (byte) 0x45, (byte) 0xf4, (byte) 0x01,
+        (byte) 0x88, (byte) 0xd2, (byte) 0xc4, (byte) 0x13, (byte) 0x34, (byte) 0x90, (byte) 0x84, (byte) 0x5d,
+        (byte) 0xe5, (byte) 0x2c, (byte) 0x25, (byte) 0x34, (byte) 0xe9, (byte) 0xc6, (byte) 0xb2, (byte) 0x47,
+        (byte) 0x8c, (byte) 0x07, (byte) 0xbd, (byte) 0xae, (byte) 0x92, (byte) 0x88, (byte) 0x23, (byte) 0xb6,
+        (byte) 0x2d, (byte) 0x06, (byte) 0x6c, (byte) 0x77, (byte) 0x70, (byte) 0xf9, (byte) 0xf6, (byte) 0x3f,
+        (byte) 0x3d, (byte) 0xba, (byte) 0x24, (byte) 0x7f, (byte) 0x53, (byte) 0x08, (byte) 0x44, (byte) 0x74,
+        (byte) 0x7b, (byte) 0xe7, (byte) 0xaa, (byte) 0xa8, (byte) 0x5d, (byte) 0x85, (byte) 0x3b, (byte) 0x8b,
+        (byte) 0xd2, (byte) 0x44, (byte) 0xac, (byte) 0xec, (byte) 0x3d, (byte) 0xe3, (byte) 0xc8, (byte) 0x9a,
+        (byte) 0xb4, (byte) 0x64, (byte) 0x53, (byte) 0xab, (byte) 0x4d, (byte) 0x24, (byte) 0xc3, (byte) 0xac,
+        (byte) 0x69,
+    });
+
+    private static final BigInteger RSA_2048_privateExponent = new BigInteger(new byte[] {
+        (byte) 0x37, (byte) 0x78, (byte) 0x47, (byte) 0x76, (byte) 0xa5, (byte) 0xf1, (byte) 0x76, (byte) 0x98,
+        (byte) 0xf5, (byte) 0xac, (byte) 0x96, (byte) 0x0d, (byte) 0xfb, (byte) 0x83, (byte) 0xa1, (byte) 0xb6,
+        (byte) 0x75, (byte) 0x64, (byte) 0xe6, (byte) 0x48, (byte) 0xbd, (byte) 0x05, (byte) 0x97, (byte) 0xcf,
+        (byte) 0x8a, (byte) 0xb8, (byte) 0x08, (byte) 0x71, (byte) 0x86, (byte) 0xf2, (byte) 0x66, (byte) 0x9c,
+        (byte) 0x27, (byte) 0xa9, (byte) 0xec, (byte) 0xbd, (byte) 0xd4, (byte) 0x80, (byte) 0xf0, (byte) 0x19,
+        (byte) 0x7a, (byte) 0x80, (byte) 0xd0, (byte) 0x73, (byte) 0x09, (byte) 0xe6, (byte) 0xc6, (byte) 0xa9,
+        (byte) 0x6f, (byte) 0x92, (byte) 0x53, (byte) 0x31, (byte) 0xe5, (byte) 0x7f, (byte) 0x8b, (byte) 0x4a,
+        (byte) 0xc6, (byte) 0xf4, (byte) 0xd4, (byte) 0x5e, (byte) 0xda, (byte) 0x45, (byte) 0xa2, (byte) 0x32,
+        (byte) 0x69, (byte) 0xc0, (byte) 0x9f, (byte) 0xc4, (byte) 0x28, (byte) 0xc0, (byte) 0x7a, (byte) 0x4e,
+        (byte) 0x6e, (byte) 0xdf, (byte) 0x73, (byte) 0x8a, (byte) 0x15, (byte) 0xde, (byte) 0xc9, (byte) 0x7f,
+        (byte) 0xab, (byte) 0xd2, (byte) 0xf2, (byte) 0xbb, (byte) 0x47, (byte) 0xa1, (byte) 0x4f, (byte) 0x20,
+        (byte) 0xea, (byte) 0x72, (byte) 0xfc, (byte) 0xfe, (byte) 0x4c, (byte) 0x36, (byte) 0xe0, (byte) 0x1a,
+        (byte) 0xda, (byte) 0x77, (byte) 0xbd, (byte) 0x13, (byte) 0x7c, (byte) 0xd8, (byte) 0xd4, (byte) 0xda,
+        (byte) 0x10, (byte) 0xbb, (byte) 0x16, (byte) 0x2e, (byte) 0x94, (byte) 0xa4, (byte) 0x66, (byte) 0x29,
+        (byte) 0x71, (byte) 0xf1, (byte) 0x75, (byte) 0xf9, (byte) 0x85, (byte) 0xfa, (byte) 0x18, (byte) 0x8f,
+        (byte) 0x05, (byte) 0x6c, (byte) 0xb9, (byte) 0x7e, (byte) 0xe2, (byte) 0x81, (byte) 0x6f, (byte) 0x43,
+        (byte) 0xab, (byte) 0x9d, (byte) 0x37, (byte) 0x47, (byte) 0x61, (byte) 0x24, (byte) 0x86, (byte) 0xcd,
+        (byte) 0xa8, (byte) 0xc1, (byte) 0x61, (byte) 0x96, (byte) 0xc3, (byte) 0x08, (byte) 0x18, (byte) 0xa9,
+        (byte) 0x95, (byte) 0xec, (byte) 0x85, (byte) 0xd3, (byte) 0x84, (byte) 0x67, (byte) 0x79, (byte) 0x12,
+        (byte) 0x67, (byte) 0xb3, (byte) 0xbf, (byte) 0x21, (byte) 0xf2, (byte) 0x73, (byte) 0x71, (byte) 0x0a,
+        (byte) 0x69, (byte) 0x25, (byte) 0x86, (byte) 0x25, (byte) 0x76, (byte) 0x84, (byte) 0x1c, (byte) 0x5b,
+        (byte) 0x67, (byte) 0x12, (byte) 0xc1, (byte) 0x2d, (byte) 0x4b, (byte) 0xd2, (byte) 0x0a, (byte) 0x2f,
+        (byte) 0x32, (byte) 0x99, (byte) 0xad, (byte) 0xb7, (byte) 0xc1, (byte) 0x35, (byte) 0xda, (byte) 0x5e,
+        (byte) 0x95, (byte) 0x15, (byte) 0xab, (byte) 0xda, (byte) 0x76, (byte) 0xe7, (byte) 0xca, (byte) 0xf2,
+        (byte) 0xa3, (byte) 0xbe, (byte) 0x80, (byte) 0x55, (byte) 0x1d, (byte) 0x07, (byte) 0x3b, (byte) 0x78,
+        (byte) 0xbf, (byte) 0x11, (byte) 0x62, (byte) 0xc4, (byte) 0x8a, (byte) 0xd2, (byte) 0xb7, (byte) 0xf4,
+        (byte) 0x74, (byte) 0x3a, (byte) 0x02, (byte) 0x38, (byte) 0xee, (byte) 0x4d, (byte) 0x25, (byte) 0x2f,
+        (byte) 0x7d, (byte) 0x5e, (byte) 0x7e, (byte) 0x65, (byte) 0x33, (byte) 0xcc, (byte) 0xae, (byte) 0x64,
+        (byte) 0xcc, (byte) 0xb3, (byte) 0x93, (byte) 0x60, (byte) 0x07, (byte) 0x5a, (byte) 0x2f, (byte) 0xd1,
+        (byte) 0xe0, (byte) 0x34, (byte) 0xec, (byte) 0x3a, (byte) 0xe5, (byte) 0xce, (byte) 0x9c, (byte) 0x40,
+        (byte) 0x8c, (byte) 0xcb, (byte) 0xf0, (byte) 0xe2, (byte) 0x5e, (byte) 0x41, (byte) 0x14, (byte) 0x02,
+        (byte) 0x16, (byte) 0x87, (byte) 0xb3, (byte) 0xdd, (byte) 0x47, (byte) 0x54, (byte) 0xae, (byte) 0x81,
+    });
+
+    private static final BigInteger RSA_2048_publicExponent = new BigInteger(new byte[] {
+        (byte) 0x01, (byte) 0x00, (byte) 0x01,
+    });
+
+    private static final BigInteger RSA_2048_primeP = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xf5, (byte) 0x41, (byte) 0x88, (byte) 0x4b, (byte) 0xc3, (byte) 0x73, (byte) 0x7b,
+        (byte) 0x29, (byte) 0x22, (byte) 0xd4, (byte) 0x11, (byte) 0x9e, (byte) 0xf4, (byte) 0x5e, (byte) 0x2d,
+        (byte) 0xee, (byte) 0x2c, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x5f, (byte) 0x45, (byte) 0x50,
+        (byte) 0x5a, (byte) 0x15, (byte) 0x7a, (byte) 0xa5, (byte) 0x00, (byte) 0x9f, (byte) 0x99, (byte) 0xc7,
+        (byte) 0x3a, (byte) 0x2d, (byte) 0xf0, (byte) 0x72, (byte) 0x4a, (byte) 0xc4, (byte) 0x60, (byte) 0x24,
+        (byte) 0x30, (byte) 0x63, (byte) 0x32, (byte) 0xea, (byte) 0x89, (byte) 0x81, (byte) 0x77, (byte) 0x63,
+        (byte) 0x45, (byte) 0x46, (byte) 0x5d, (byte) 0xc6, (byte) 0xdf, (byte) 0x1e, (byte) 0x0a, (byte) 0x6f,
+        (byte) 0x14, (byte) 0x0a, (byte) 0xff, (byte) 0x3b, (byte) 0x73, (byte) 0x96, (byte) 0xe6, (byte) 0xa8,
+        (byte) 0x99, (byte) 0x4a, (byte) 0xc5, (byte) 0xda, (byte) 0xa9, (byte) 0x68, (byte) 0x73, (byte) 0x47,
+        (byte) 0x2f, (byte) 0xe3, (byte) 0x77, (byte) 0x49, (byte) 0xd1, (byte) 0x4e, (byte) 0xb3, (byte) 0xe0,
+        (byte) 0x75, (byte) 0xe6, (byte) 0x29, (byte) 0xdb, (byte) 0xeb, (byte) 0x35, (byte) 0x83, (byte) 0x33,
+        (byte) 0x8a, (byte) 0x6f, (byte) 0x36, (byte) 0x49, (byte) 0xd0, (byte) 0xa2, (byte) 0x65, (byte) 0x4a,
+        (byte) 0x7a, (byte) 0x42, (byte) 0xfd, (byte) 0x9a, (byte) 0xb6, (byte) 0xbf, (byte) 0xa4, (byte) 0xac,
+        (byte) 0x4d, (byte) 0x48, (byte) 0x1d, (byte) 0x39, (byte) 0x0b, (byte) 0xb2, (byte) 0x29, (byte) 0xb0,
+        (byte) 0x64, (byte) 0xbd, (byte) 0xc3, (byte) 0x11, (byte) 0xcc, (byte) 0x1b, (byte) 0xe1, (byte) 0xb6,
+        (byte) 0x31, (byte) 0x89, (byte) 0xda, (byte) 0x7c, (byte) 0x40, (byte) 0xcd, (byte) 0xec, (byte) 0xf2,
+        (byte) 0xb1,
+    });
+
+    private static final BigInteger RSA_2048_primeQ = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xea, (byte) 0x1a, (byte) 0x74, (byte) 0x2d, (byte) 0xdb, (byte) 0x88, (byte) 0x1c,
+        (byte) 0xed, (byte) 0xb7, (byte) 0x28, (byte) 0x8c, (byte) 0x87, (byte) 0xe3, (byte) 0x8d, (byte) 0x86,
+        (byte) 0x8d, (byte) 0xd7, (byte) 0xa4, (byte) 0x09, (byte) 0xd1, (byte) 0x5a, (byte) 0x43, (byte) 0xf4,
+        (byte) 0x45, (byte) 0xd5, (byte) 0x37, (byte) 0x7a, (byte) 0x0b, (byte) 0x57, (byte) 0x31, (byte) 0xdd,
+        (byte) 0xbf, (byte) 0xca, (byte) 0x2d, (byte) 0xaf, (byte) 0x28, (byte) 0xa8, (byte) 0xe1, (byte) 0x3c,
+        (byte) 0xd5, (byte) 0xc0, (byte) 0xaf, (byte) 0xce, (byte) 0xc3, (byte) 0x34, (byte) 0x7d, (byte) 0x74,
+        (byte) 0xa3, (byte) 0x9e, (byte) 0x23, (byte) 0x5a, (byte) 0x3c, (byte) 0xd9, (byte) 0x63, (byte) 0x3f,
+        (byte) 0x27, (byte) 0x4d, (byte) 0xe2, (byte) 0xb9, (byte) 0x4f, (byte) 0x92, (byte) 0xdf, (byte) 0x43,
+        (byte) 0x83, (byte) 0x39, (byte) 0x11, (byte) 0xd9, (byte) 0xe9, (byte) 0xf1, (byte) 0xcf, (byte) 0x58,
+        (byte) 0xf2, (byte) 0x7d, (byte) 0xe2, (byte) 0xe0, (byte) 0x8f, (byte) 0xf4, (byte) 0x59, (byte) 0x64,
+        (byte) 0xc7, (byte) 0x20, (byte) 0xd3, (byte) 0xec, (byte) 0x21, (byte) 0x39, (byte) 0xdc, (byte) 0x7c,
+        (byte) 0xaf, (byte) 0xc9, (byte) 0x12, (byte) 0x95, (byte) 0x3c, (byte) 0xde, (byte) 0xcb, (byte) 0x2f,
+        (byte) 0x35, (byte) 0x5a, (byte) 0x2e, (byte) 0x2c, (byte) 0x35, (byte) 0xa5, (byte) 0x0f, (byte) 0xad,
+        (byte) 0x75, (byte) 0x4c, (byte) 0xb3, (byte) 0xb2, (byte) 0x31, (byte) 0x66, (byte) 0x42, (byte) 0x4b,
+        (byte) 0xa3, (byte) 0xb6, (byte) 0xe3, (byte) 0x11, (byte) 0x2a, (byte) 0x2b, (byte) 0x89, (byte) 0x8c,
+        (byte) 0x38, (byte) 0xc5, (byte) 0xc1, (byte) 0x5e, (byte) 0xdb, (byte) 0x23, (byte) 0x86, (byte) 0x93,
+        (byte) 0x39,
+    });
+
+    /* Test data is: "Android.\n" */
+    private static final byte[] Vector1Data = new byte[] {
+        (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x2e,
+        (byte) 0x0a,
+    };
+
+    private static final byte[] SHA1withRSA_Vector1Signature = {
+        (byte) 0x6d, (byte) 0x5b, (byte) 0xff, (byte) 0x68, (byte) 0xda, (byte) 0x18, (byte) 0x98, (byte) 0x72,
+        (byte) 0x5c, (byte) 0x1f, (byte) 0x46, (byte) 0x51, (byte) 0x77, (byte) 0x15, (byte) 0x11, (byte) 0xcb,
+        (byte) 0xe0, (byte) 0xb9, (byte) 0x3b, (byte) 0x7d, (byte) 0xf5, (byte) 0x96, (byte) 0x98, (byte) 0x24,
+        (byte) 0x85, (byte) 0x9d, (byte) 0x3e, (byte) 0xed, (byte) 0x9b, (byte) 0xb2, (byte) 0x8a, (byte) 0x91,
+        (byte) 0xfb, (byte) 0xf6, (byte) 0x85, (byte) 0x64, (byte) 0x74, (byte) 0x18, (byte) 0xb5, (byte) 0x1c,
+        (byte) 0xb3, (byte) 0x8d, (byte) 0x99, (byte) 0x0d, (byte) 0xdf, (byte) 0xaa, (byte) 0xa6, (byte) 0xa1,
+        (byte) 0xc3, (byte) 0xb6, (byte) 0x25, (byte) 0xb3, (byte) 0x06, (byte) 0xe0, (byte) 0xef, (byte) 0x28,
+        (byte) 0xb0, (byte) 0x4d, (byte) 0x50, (byte) 0xc7, (byte) 0x75, (byte) 0x39, (byte) 0xb9, (byte) 0x2c,
+        (byte) 0x47, (byte) 0xb5, (byte) 0xe2, (byte) 0x96, (byte) 0xf8, (byte) 0xf6, (byte) 0xcb, (byte) 0xa0,
+        (byte) 0x58, (byte) 0xc9, (byte) 0x3e, (byte) 0xd5, (byte) 0xfc, (byte) 0x26, (byte) 0xd9, (byte) 0x55,
+        (byte) 0x73, (byte) 0x39, (byte) 0x75, (byte) 0xb3, (byte) 0xb0, (byte) 0x0a, (byte) 0x5f, (byte) 0x5e,
+        (byte) 0x3b, (byte) 0x4a, (byte) 0x2e, (byte) 0xb1, (byte) 0x0e, (byte) 0x7d, (byte) 0xe5, (byte) 0xcc,
+        (byte) 0x04, (byte) 0x2c, (byte) 0xd1, (byte) 0x0a, (byte) 0x32, (byte) 0xaa, (byte) 0xd9, (byte) 0x8d,
+        (byte) 0x1f, (byte) 0xcb, (byte) 0xe3, (byte) 0x7f, (byte) 0x63, (byte) 0x12, (byte) 0xb1, (byte) 0x98,
+        (byte) 0x46, (byte) 0x46, (byte) 0x07, (byte) 0xd9, (byte) 0x49, (byte) 0xd2, (byte) 0xbf, (byte) 0xb5,
+        (byte) 0xbc, (byte) 0xbb, (byte) 0xfd, (byte) 0x1c, (byte) 0xd7, (byte) 0x11, (byte) 0x94, (byte) 0xaa,
+        (byte) 0x5f, (byte) 0x7b, (byte) 0xb2, (byte) 0x0c, (byte) 0x5d, (byte) 0x94, (byte) 0x53, (byte) 0x5e,
+        (byte) 0x81, (byte) 0x5c, (byte) 0xbb, (byte) 0x1d, (byte) 0x4f, (byte) 0x30, (byte) 0xcd, (byte) 0xf8,
+        (byte) 0xd7, (byte) 0xa5, (byte) 0xfa, (byte) 0x5e, (byte) 0xe0, (byte) 0x19, (byte) 0x3f, (byte) 0xa4,
+        (byte) 0xaa, (byte) 0x56, (byte) 0x4e, (byte) 0xec, (byte) 0xeb, (byte) 0xee, (byte) 0xa2, (byte) 0x6c,
+        (byte) 0xc9, (byte) 0x4f, (byte) 0xc2, (byte) 0xcc, (byte) 0x2a, (byte) 0xbc, (byte) 0x5b, (byte) 0x09,
+        (byte) 0x10, (byte) 0x73, (byte) 0x61, (byte) 0x0c, (byte) 0x04, (byte) 0xb6, (byte) 0xb7, (byte) 0x2c,
+        (byte) 0x37, (byte) 0xd2, (byte) 0xca, (byte) 0x2d, (byte) 0x54, (byte) 0xf2, (byte) 0xf7, (byte) 0x77,
+        (byte) 0xe1, (byte) 0xba, (byte) 0x9f, (byte) 0x29, (byte) 0x07, (byte) 0xa2, (byte) 0x74, (byte) 0xc6,
+        (byte) 0xe9, (byte) 0x1e, (byte) 0xde, (byte) 0xd7, (byte) 0x9c, (byte) 0x4b, (byte) 0xb7, (byte) 0x66,
+        (byte) 0x52, (byte) 0xe8, (byte) 0xac, (byte) 0xf6, (byte) 0x76, (byte) 0xab, (byte) 0x16, (byte) 0x82,
+        (byte) 0x96, (byte) 0x87, (byte) 0x40, (byte) 0x0f, (byte) 0xad, (byte) 0x2d, (byte) 0x46, (byte) 0xa6,
+        (byte) 0x28, (byte) 0x04, (byte) 0x13, (byte) 0xc2, (byte) 0xce, (byte) 0x50, (byte) 0x56, (byte) 0x6d,
+        (byte) 0xbe, (byte) 0x0c, (byte) 0x91, (byte) 0xd0, (byte) 0x8e, (byte) 0x80, (byte) 0x9e, (byte) 0x91,
+        (byte) 0x8f, (byte) 0x62, (byte) 0xb3, (byte) 0x57, (byte) 0xd6, (byte) 0xae, (byte) 0x53, (byte) 0x91,
+        (byte) 0x83, (byte) 0xe9, (byte) 0x38, (byte) 0x77, (byte) 0x8f, (byte) 0x20, (byte) 0xdd, (byte) 0x13,
+        (byte) 0x7d, (byte) 0x15, (byte) 0x44, (byte) 0x7e, (byte) 0xb5, (byte) 0x00, (byte) 0xd6, (byte) 0x45,
+    };
+
+    private static final byte[] Vector2Data = new byte[] {
+        (byte) 0x54, (byte) 0x68, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20,
+        (byte) 0x61, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x65, (byte) 0x64,
+        (byte) 0x20, (byte) 0x6d, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x61, (byte) 0x67, (byte) 0x65,
+        (byte) 0x20, (byte) 0x66, (byte) 0x72, (byte) 0x6f, (byte) 0x6d, (byte) 0x20, (byte) 0x4b, (byte) 0x65,
+        (byte) 0x6e, (byte) 0x6e, (byte) 0x79, (byte) 0x20, (byte) 0x52, (byte) 0x6f, (byte) 0x6f, (byte) 0x74,
+        (byte) 0x2e, (byte) 0x0a,
+    };
+
+    private static final byte[] SHA1withRSA_Vector2Signature = new byte[] {
+        (byte) 0x2e, (byte) 0xa6, (byte) 0x33, (byte) 0xd1, (byte) 0x9d, (byte) 0xfc, (byte) 0x4e, (byte) 0x27,
+        (byte) 0xb3, (byte) 0xa8, (byte) 0x9a, (byte) 0xf2, (byte) 0x48, (byte) 0x62, (byte) 0x15, (byte) 0xa2,
+        (byte) 0xce, (byte) 0x5f, (byte) 0x2b, (byte) 0x0e, (byte) 0xc5, (byte) 0x26, (byte) 0xba, (byte) 0xd9,
+        (byte) 0x0f, (byte) 0x60, (byte) 0xeb, (byte) 0xf0, (byte) 0xd5, (byte) 0x5c, (byte) 0x6b, (byte) 0x23,
+        (byte) 0x11, (byte) 0x95, (byte) 0xa4, (byte) 0xbd, (byte) 0x11, (byte) 0x68, (byte) 0xe7, (byte) 0x3a,
+        (byte) 0x37, (byte) 0x3d, (byte) 0x79, (byte) 0xb8, (byte) 0x4f, (byte) 0xe9, (byte) 0xa1, (byte) 0x88,
+        (byte) 0xfb, (byte) 0xa9, (byte) 0x8b, (byte) 0x34, (byte) 0xa1, (byte) 0xe0, (byte) 0xca, (byte) 0x11,
+        (byte) 0xdd, (byte) 0xd0, (byte) 0x83, (byte) 0x7f, (byte) 0xc1, (byte) 0x0b, (byte) 0x16, (byte) 0x61,
+        (byte) 0xac, (byte) 0x09, (byte) 0xa2, (byte) 0xdd, (byte) 0x40, (byte) 0x5b, (byte) 0x8c, (byte) 0x7a,
+        (byte) 0xb2, (byte) 0xb4, (byte) 0x02, (byte) 0x7c, (byte) 0xd4, (byte) 0x9a, (byte) 0xe6, (byte) 0xa5,
+        (byte) 0x1a, (byte) 0x27, (byte) 0x77, (byte) 0x70, (byte) 0xe3, (byte) 0xe3, (byte) 0x71, (byte) 0xc7,
+        (byte) 0x59, (byte) 0xc7, (byte) 0x9f, (byte) 0xb8, (byte) 0xef, (byte) 0xe7, (byte) 0x15, (byte) 0x02,
+        (byte) 0x0d, (byte) 0x70, (byte) 0xdc, (byte) 0x2c, (byte) 0xe9, (byte) 0xf7, (byte) 0x63, (byte) 0x2a,
+        (byte) 0xb5, (byte) 0xee, (byte) 0x9f, (byte) 0x29, (byte) 0x56, (byte) 0x86, (byte) 0x99, (byte) 0xb3,
+        (byte) 0x0f, (byte) 0xe5, (byte) 0x1f, (byte) 0x76, (byte) 0x22, (byte) 0x3b, (byte) 0x7f, (byte) 0xa9,
+        (byte) 0x9e, (byte) 0xd4, (byte) 0xc4, (byte) 0x83, (byte) 0x5d, (byte) 0x57, (byte) 0xcc, (byte) 0x37,
+        (byte) 0xcb, (byte) 0x9a, (byte) 0x9e, (byte) 0x73, (byte) 0x44, (byte) 0x93, (byte) 0xb4, (byte) 0xf1,
+        (byte) 0x6b, (byte) 0x98, (byte) 0xa0, (byte) 0x57, (byte) 0xbb, (byte) 0x5e, (byte) 0x8f, (byte) 0x89,
+        (byte) 0x5b, (byte) 0x97, (byte) 0x26, (byte) 0xe4, (byte) 0xd0, (byte) 0x51, (byte) 0x0a, (byte) 0x5a,
+        (byte) 0xb7, (byte) 0x12, (byte) 0x1a, (byte) 0x6d, (byte) 0xb0, (byte) 0x79, (byte) 0x30, (byte) 0x51,
+        (byte) 0x83, (byte) 0x2e, (byte) 0xe2, (byte) 0x7a, (byte) 0x67, (byte) 0x66, (byte) 0xd3, (byte) 0x95,
+        (byte) 0xca, (byte) 0xfc, (byte) 0xcb, (byte) 0x92, (byte) 0x79, (byte) 0x32, (byte) 0x26, (byte) 0x86,
+        (byte) 0xe1, (byte) 0x0d, (byte) 0xd8, (byte) 0x19, (byte) 0xfa, (byte) 0x65, (byte) 0x37, (byte) 0xc9,
+        (byte) 0x4c, (byte) 0x2a, (byte) 0xe1, (byte) 0x42, (byte) 0xc7, (byte) 0xd4, (byte) 0xb7, (byte) 0xeb,
+        (byte) 0x1f, (byte) 0xc3, (byte) 0x53, (byte) 0x64, (byte) 0x6f, (byte) 0x2b, (byte) 0x78, (byte) 0x18,
+        (byte) 0x03, (byte) 0xda, (byte) 0x8d, (byte) 0x62, (byte) 0x24, (byte) 0x70, (byte) 0xab, (byte) 0xe6,
+        (byte) 0x16, (byte) 0x13, (byte) 0x24, (byte) 0x6b, (byte) 0x5f, (byte) 0xd3, (byte) 0xec, (byte) 0xc1,
+        (byte) 0x58, (byte) 0x64, (byte) 0xbd, (byte) 0x30, (byte) 0x98, (byte) 0x5e, (byte) 0x33, (byte) 0xce,
+        (byte) 0x87, (byte) 0x64, (byte) 0x14, (byte) 0x07, (byte) 0x85, (byte) 0x43, (byte) 0x3e, (byte) 0x9f,
+        (byte) 0x27, (byte) 0x9f, (byte) 0x63, (byte) 0x66, (byte) 0x9d, (byte) 0x26, (byte) 0x19, (byte) 0xc0,
+        (byte) 0x02, (byte) 0x08, (byte) 0x15, (byte) 0xcb, (byte) 0xb4, (byte) 0xaa, (byte) 0x4a, (byte) 0xc8,
+        (byte) 0xc0, (byte) 0x09, (byte) 0x15, (byte) 0x7d, (byte) 0x8a, (byte) 0x21, (byte) 0xbc, (byte) 0xa3,
+    };
+
+    /*
+     * echo 'Android.' | openssl dgst -sha224 -binary -sign privkey.pem  | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA224withRSA_Vector2Signature = new byte[] {
+        (byte) 0xBD, (byte) 0x3F, (byte) 0xD4, (byte) 0x20, (byte) 0x5B, (byte) 0xC0, (byte) 0x89, (byte) 0x4F,
+        (byte) 0x99, (byte) 0x6C, (byte) 0xF4, (byte) 0xA4, (byte) 0x70, (byte) 0xE3, (byte) 0x5B, (byte) 0x33,
+        (byte) 0xB3, (byte) 0xCA, (byte) 0xFE, (byte) 0x1F, (byte) 0xB9, (byte) 0x3A, (byte) 0xD6, (byte) 0x9B,
+        (byte) 0x1E, (byte) 0xDA, (byte) 0x65, (byte) 0x06, (byte) 0xBD, (byte) 0xC3, (byte) 0x2B, (byte) 0xF8,
+        (byte) 0x0E, (byte) 0xA0, (byte) 0xB5, (byte) 0x33, (byte) 0x7F, (byte) 0x15, (byte) 0xDC, (byte) 0xBB,
+        (byte) 0xDC, (byte) 0x98, (byte) 0x96, (byte) 0xF5, (byte) 0xF8, (byte) 0xE5, (byte) 0x55, (byte) 0x7D,
+        (byte) 0x48, (byte) 0x51, (byte) 0xC5, (byte) 0xAE, (byte) 0x12, (byte) 0xA2, (byte) 0x61, (byte) 0xC7,
+        (byte) 0xA2, (byte) 0x00, (byte) 0x0F, (byte) 0x35, (byte) 0x54, (byte) 0x3C, (byte) 0x7E, (byte) 0x97,
+        (byte) 0x19, (byte) 0x2D, (byte) 0x8F, (byte) 0xFD, (byte) 0x51, (byte) 0x04, (byte) 0x72, (byte) 0x23,
+        (byte) 0x65, (byte) 0x16, (byte) 0x41, (byte) 0x12, (byte) 0x46, (byte) 0xD6, (byte) 0x20, (byte) 0xB6,
+        (byte) 0x4E, (byte) 0xD6, (byte) 0xE8, (byte) 0x60, (byte) 0x91, (byte) 0x05, (byte) 0xCA, (byte) 0x57,
+        (byte) 0x6F, (byte) 0x53, (byte) 0xA4, (byte) 0x05, (byte) 0x2A, (byte) 0x37, (byte) 0xDD, (byte) 0x2E,
+        (byte) 0xA4, (byte) 0xC7, (byte) 0xBF, (byte) 0x9E, (byte) 0xF6, (byte) 0xD5, (byte) 0xD4, (byte) 0x34,
+        (byte) 0xB8, (byte) 0xB3, (byte) 0x8B, (byte) 0x66, (byte) 0x2C, (byte) 0xB6, (byte) 0x5F, (byte) 0xA4,
+        (byte) 0xB7, (byte) 0x77, (byte) 0xF8, (byte) 0x9A, (byte) 0x9C, (byte) 0x44, (byte) 0x9F, (byte) 0xF0,
+        (byte) 0xCA, (byte) 0x53, (byte) 0x56, (byte) 0x2F, (byte) 0x99, (byte) 0x2E, (byte) 0x4B, (byte) 0xA2,
+        (byte) 0x26, (byte) 0x50, (byte) 0x30, (byte) 0x97, (byte) 0x2B, (byte) 0x4B, (byte) 0x0C, (byte) 0x3E,
+        (byte) 0x28, (byte) 0x0B, (byte) 0x88, (byte) 0x87, (byte) 0x9E, (byte) 0xCE, (byte) 0xCB, (byte) 0x57,
+        (byte) 0x72, (byte) 0x6B, (byte) 0xF6, (byte) 0xD6, (byte) 0xAA, (byte) 0x4D, (byte) 0x5F, (byte) 0x19,
+        (byte) 0x7A, (byte) 0xAD, (byte) 0x44, (byte) 0x09, (byte) 0x33, (byte) 0x62, (byte) 0xC8, (byte) 0x56,
+        (byte) 0x82, (byte) 0x84, (byte) 0xBF, (byte) 0x52, (byte) 0xC6, (byte) 0xA2, (byte) 0x2B, (byte) 0xE3,
+        (byte) 0xC2, (byte) 0x7F, (byte) 0xE3, (byte) 0x06, (byte) 0xC3, (byte) 0x30, (byte) 0xB8, (byte) 0xD4,
+        (byte) 0x01, (byte) 0xE6, (byte) 0x3D, (byte) 0xDB, (byte) 0xCA, (byte) 0xE4, (byte) 0xFB, (byte) 0xA8,
+        (byte) 0x7B, (byte) 0x2D, (byte) 0x8F, (byte) 0x39, (byte) 0x7A, (byte) 0x63, (byte) 0x9F, (byte) 0x02,
+        (byte) 0xE8, (byte) 0x91, (byte) 0xD1, (byte) 0xEE, (byte) 0x60, (byte) 0xEE, (byte) 0xCA, (byte) 0xF2,
+        (byte) 0x33, (byte) 0x7D, (byte) 0xF2, (byte) 0x41, (byte) 0x52, (byte) 0x0B, (byte) 0x9B, (byte) 0x1B,
+        (byte) 0x2D, (byte) 0x89, (byte) 0x38, (byte) 0xEC, (byte) 0x24, (byte) 0x60, (byte) 0x40, (byte) 0x40,
+        (byte) 0x6F, (byte) 0xB6, (byte) 0x6F, (byte) 0x86, (byte) 0xB5, (byte) 0x0A, (byte) 0x3D, (byte) 0x98,
+        (byte) 0x77, (byte) 0x3F, (byte) 0x59, (byte) 0x41, (byte) 0x3E, (byte) 0x4D, (byte) 0xE4, (byte) 0x4E,
+        (byte) 0x91, (byte) 0xCD, (byte) 0x8E, (byte) 0x33, (byte) 0x60, (byte) 0x16, (byte) 0x8D, (byte) 0xAB,
+        (byte) 0x04, (byte) 0x14, (byte) 0xE8, (byte) 0x76, (byte) 0xF1, (byte) 0x06, (byte) 0xCD, (byte) 0x4A,
+        (byte) 0x88, (byte) 0xC7, (byte) 0x69, (byte) 0x6B, (byte) 0xC6, (byte) 0xDA, (byte) 0x9E, (byte) 0x09
+    };
+
+    private static final byte[] SHA256withRSA_Vector2Signature = new byte[] {
+        (byte) 0x18, (byte) 0x6e, (byte) 0x31, (byte) 0x1f, (byte) 0x1d, (byte) 0x44, (byte) 0x09, (byte) 0x3e,
+        (byte) 0xa0, (byte) 0xc4, (byte) 0x3d, (byte) 0xb4, (byte) 0x1b, (byte) 0xf2, (byte) 0xd8, (byte) 0xa4,
+        (byte) 0x59, (byte) 0xab, (byte) 0xb5, (byte) 0x37, (byte) 0x28, (byte) 0xb8, (byte) 0x94, (byte) 0x6b,
+        (byte) 0x6f, (byte) 0x13, (byte) 0x54, (byte) 0xff, (byte) 0xac, (byte) 0x15, (byte) 0x84, (byte) 0xd0,
+        (byte) 0xc9, (byte) 0x15, (byte) 0x5b, (byte) 0x69, (byte) 0x05, (byte) 0xf1, (byte) 0x44, (byte) 0xfd,
+        (byte) 0xde, (byte) 0xe8, (byte) 0xb4, (byte) 0x12, (byte) 0x59, (byte) 0x9e, (byte) 0x4c, (byte) 0x0b,
+        (byte) 0xd5, (byte) 0x49, (byte) 0x33, (byte) 0x28, (byte) 0xe0, (byte) 0xcb, (byte) 0x87, (byte) 0x85,
+        (byte) 0xd8, (byte) 0x18, (byte) 0x6f, (byte) 0xfe, (byte) 0xa2, (byte) 0x23, (byte) 0x82, (byte) 0xf0,
+        (byte) 0xe5, (byte) 0x39, (byte) 0x1b, (byte) 0x8c, (byte) 0x93, (byte) 0x11, (byte) 0x49, (byte) 0x72,
+        (byte) 0x2a, (byte) 0x5b, (byte) 0x25, (byte) 0xff, (byte) 0x4e, (byte) 0x88, (byte) 0x70, (byte) 0x9d,
+        (byte) 0x9d, (byte) 0xff, (byte) 0xe2, (byte) 0xc0, (byte) 0x7e, (byte) 0xc8, (byte) 0x03, (byte) 0x40,
+        (byte) 0xbe, (byte) 0x44, (byte) 0x09, (byte) 0xeb, (byte) 0x9e, (byte) 0x8e, (byte) 0x88, (byte) 0xe4,
+        (byte) 0x98, (byte) 0x82, (byte) 0x06, (byte) 0xa4, (byte) 0x9d, (byte) 0x63, (byte) 0x88, (byte) 0x65,
+        (byte) 0xa3, (byte) 0x8e, (byte) 0x0d, (byte) 0x22, (byte) 0xf3, (byte) 0x33, (byte) 0xf2, (byte) 0x40,
+        (byte) 0xe8, (byte) 0x91, (byte) 0x67, (byte) 0x72, (byte) 0x29, (byte) 0x1c, (byte) 0x08, (byte) 0xff,
+        (byte) 0x54, (byte) 0xa0, (byte) 0xcc, (byte) 0xad, (byte) 0x84, (byte) 0x88, (byte) 0x4b, (byte) 0x3b,
+        (byte) 0xef, (byte) 0xf9, (byte) 0x5e, (byte) 0xb3, (byte) 0x41, (byte) 0x6a, (byte) 0xbd, (byte) 0x94,
+        (byte) 0x16, (byte) 0x7d, (byte) 0x9d, (byte) 0x53, (byte) 0x77, (byte) 0xf1, (byte) 0x6a, (byte) 0x95,
+        (byte) 0x57, (byte) 0xad, (byte) 0x65, (byte) 0x9d, (byte) 0x75, (byte) 0x95, (byte) 0xf6, (byte) 0x6a,
+        (byte) 0xd2, (byte) 0x88, (byte) 0xea, (byte) 0x5b, (byte) 0xa2, (byte) 0x94, (byte) 0x8f, (byte) 0x5e,
+        (byte) 0x84, (byte) 0x18, (byte) 0x19, (byte) 0x46, (byte) 0x83, (byte) 0x0b, (byte) 0x6d, (byte) 0x5b,
+        (byte) 0xb9, (byte) 0xdb, (byte) 0xa4, (byte) 0xe5, (byte) 0x17, (byte) 0x02, (byte) 0x9e, (byte) 0x11,
+        (byte) 0xed, (byte) 0xd9, (byte) 0x7b, (byte) 0x83, (byte) 0x87, (byte) 0x89, (byte) 0xf3, (byte) 0xe4,
+        (byte) 0xbf, (byte) 0x0e, (byte) 0xe8, (byte) 0xdc, (byte) 0x55, (byte) 0x9c, (byte) 0xf7, (byte) 0xc9,
+        (byte) 0xc3, (byte) 0xe2, (byte) 0x2c, (byte) 0xf7, (byte) 0x8c, (byte) 0xaa, (byte) 0x17, (byte) 0x1f,
+        (byte) 0xd1, (byte) 0xc7, (byte) 0x74, (byte) 0xc7, (byte) 0x8e, (byte) 0x1c, (byte) 0x5b, (byte) 0xd2,
+        (byte) 0x31, (byte) 0x74, (byte) 0x43, (byte) 0x9a, (byte) 0x52, (byte) 0xbf, (byte) 0x89, (byte) 0xc5,
+        (byte) 0xb4, (byte) 0x80, (byte) 0x6a, (byte) 0x9e, (byte) 0x05, (byte) 0xdb, (byte) 0xbb, (byte) 0x07,
+        (byte) 0x8c, (byte) 0x08, (byte) 0x61, (byte) 0xba, (byte) 0xa4, (byte) 0xbc, (byte) 0x80, (byte) 0x3a,
+        (byte) 0xdd, (byte) 0x3b, (byte) 0x1a, (byte) 0x8c, (byte) 0x21, (byte) 0xd8, (byte) 0xa3, (byte) 0xc0,
+        (byte) 0xc7, (byte) 0xd1, (byte) 0x08, (byte) 0xe1, (byte) 0x34, (byte) 0x99, (byte) 0xc0, (byte) 0xcf,
+        (byte) 0x80, (byte) 0xff, (byte) 0xfa, (byte) 0x07, (byte) 0xef, (byte) 0x5c, (byte) 0x45, (byte) 0xe5,
+    };
+
+    private static final byte[] SHA384withRSA_Vector2Signature = new byte[] {
+        (byte) 0xaf, (byte) 0xf7, (byte) 0x7a, (byte) 0xc2, (byte) 0xbb, (byte) 0xb8, (byte) 0xbd, (byte) 0xe3,
+        (byte) 0x42, (byte) 0xaa, (byte) 0x16, (byte) 0x8a, (byte) 0x52, (byte) 0x6c, (byte) 0x99, (byte) 0x66,
+        (byte) 0x08, (byte) 0xbe, (byte) 0x15, (byte) 0xd9, (byte) 0x7c, (byte) 0x60, (byte) 0x2c, (byte) 0xac,
+        (byte) 0x4d, (byte) 0x4c, (byte) 0xf4, (byte) 0xdf, (byte) 0xbc, (byte) 0x16, (byte) 0x58, (byte) 0x0a,
+        (byte) 0x4e, (byte) 0xde, (byte) 0x8d, (byte) 0xb3, (byte) 0xbd, (byte) 0x03, (byte) 0x4e, (byte) 0x23,
+        (byte) 0x40, (byte) 0xa5, (byte) 0x80, (byte) 0xae, (byte) 0x83, (byte) 0xb4, (byte) 0x0f, (byte) 0x99,
+        (byte) 0x44, (byte) 0xc3, (byte) 0x5e, (byte) 0xdb, (byte) 0x59, (byte) 0x1d, (byte) 0xea, (byte) 0x7b,
+        (byte) 0x4d, (byte) 0xf3, (byte) 0xd2, (byte) 0xad, (byte) 0xbd, (byte) 0x21, (byte) 0x9f, (byte) 0x8e,
+        (byte) 0x87, (byte) 0x8f, (byte) 0x12, (byte) 0x13, (byte) 0x33, (byte) 0xf1, (byte) 0xc0, (byte) 0x9d,
+        (byte) 0xe7, (byte) 0xec, (byte) 0x6e, (byte) 0xad, (byte) 0xea, (byte) 0x5d, (byte) 0x69, (byte) 0xbb,
+        (byte) 0xab, (byte) 0x5b, (byte) 0xd8, (byte) 0x55, (byte) 0x56, (byte) 0xc8, (byte) 0xda, (byte) 0x81,
+        (byte) 0x41, (byte) 0xfb, (byte) 0xd3, (byte) 0x11, (byte) 0x6c, (byte) 0x97, (byte) 0xa7, (byte) 0xc3,
+        (byte) 0xf1, (byte) 0x31, (byte) 0xbf, (byte) 0xbe, (byte) 0x3f, (byte) 0xdb, (byte) 0x35, (byte) 0x85,
+        (byte) 0xb7, (byte) 0xb0, (byte) 0x75, (byte) 0x7f, (byte) 0xaf, (byte) 0xfb, (byte) 0x65, (byte) 0x61,
+        (byte) 0xc7, (byte) 0x0e, (byte) 0x63, (byte) 0xb5, (byte) 0x7d, (byte) 0x95, (byte) 0xe9, (byte) 0x16,
+        (byte) 0x9d, (byte) 0x6a, (byte) 0x00, (byte) 0x9f, (byte) 0x5e, (byte) 0xcd, (byte) 0xff, (byte) 0xa6,
+        (byte) 0xbc, (byte) 0x71, (byte) 0xf2, (byte) 0x2c, (byte) 0xd3, (byte) 0x68, (byte) 0xb9, (byte) 0x3f,
+        (byte) 0xaa, (byte) 0x06, (byte) 0xf1, (byte) 0x9c, (byte) 0x7e, (byte) 0xca, (byte) 0x4a, (byte) 0xfe,
+        (byte) 0xb1, (byte) 0x73, (byte) 0x19, (byte) 0x80, (byte) 0x05, (byte) 0xa6, (byte) 0x85, (byte) 0x14,
+        (byte) 0xda, (byte) 0x7a, (byte) 0x16, (byte) 0x7a, (byte) 0xc2, (byte) 0x46, (byte) 0x57, (byte) 0xa7,
+        (byte) 0xc0, (byte) 0xbf, (byte) 0xcd, (byte) 0xdc, (byte) 0x2f, (byte) 0x64, (byte) 0xf6, (byte) 0x6d,
+        (byte) 0xdc, (byte) 0xcb, (byte) 0x5a, (byte) 0x29, (byte) 0x95, (byte) 0x1c, (byte) 0xfe, (byte) 0xf2,
+        (byte) 0xda, (byte) 0x7e, (byte) 0xcb, (byte) 0x26, (byte) 0x12, (byte) 0xc6, (byte) 0xb0, (byte) 0xba,
+        (byte) 0x84, (byte) 0x9b, (byte) 0x4f, (byte) 0xba, (byte) 0x1b, (byte) 0x78, (byte) 0x25, (byte) 0xb8,
+        (byte) 0x8f, (byte) 0x2e, (byte) 0x51, (byte) 0x5f, (byte) 0x9e, (byte) 0xfc, (byte) 0x40, (byte) 0xbc,
+        (byte) 0x85, (byte) 0xcd, (byte) 0x86, (byte) 0x7f, (byte) 0x88, (byte) 0xc5, (byte) 0xaa, (byte) 0x2b,
+        (byte) 0x78, (byte) 0xb1, (byte) 0x9c, (byte) 0x51, (byte) 0x9a, (byte) 0xe1, (byte) 0xe1, (byte) 0xc0,
+        (byte) 0x40, (byte) 0x47, (byte) 0xcb, (byte) 0xa4, (byte) 0xb7, (byte) 0x6c, (byte) 0x31, (byte) 0xf2,
+        (byte) 0xc8, (byte) 0x9a, (byte) 0xad, (byte) 0x0b, (byte) 0xd3, (byte) 0xf6, (byte) 0x85, (byte) 0x9a,
+        (byte) 0x8f, (byte) 0x4f, (byte) 0xc9, (byte) 0xd8, (byte) 0x33, (byte) 0x7c, (byte) 0x45, (byte) 0x30,
+        (byte) 0xea, (byte) 0x17, (byte) 0xd3, (byte) 0xe3, (byte) 0x90, (byte) 0x2c, (byte) 0xda, (byte) 0xde,
+        (byte) 0x41, (byte) 0x17, (byte) 0x3f, (byte) 0x08, (byte) 0xb9, (byte) 0x34, (byte) 0xc0, (byte) 0xd1,
+    };
+
+    private static final byte[] SHA512withRSA_Vector2Signature = new byte[] {
+        (byte) 0x19, (byte) 0xe2, (byte) 0xe5, (byte) 0xf3, (byte) 0x18, (byte) 0x83, (byte) 0xec, (byte) 0xf0,
+        (byte) 0xab, (byte) 0x50, (byte) 0x05, (byte) 0x4b, (byte) 0x5f, (byte) 0x22, (byte) 0xfc, (byte) 0x82,
+        (byte) 0x6d, (byte) 0xca, (byte) 0xe7, (byte) 0xbe, (byte) 0x23, (byte) 0x94, (byte) 0xfa, (byte) 0xf9,
+        (byte) 0xa4, (byte) 0x8a, (byte) 0x95, (byte) 0x4d, (byte) 0x14, (byte) 0x08, (byte) 0x8b, (byte) 0x5e,
+        (byte) 0x03, (byte) 0x1b, (byte) 0x74, (byte) 0xde, (byte) 0xc1, (byte) 0x45, (byte) 0x9c, (byte) 0xce,
+        (byte) 0x1d, (byte) 0xac, (byte) 0xab, (byte) 0xd3, (byte) 0xa8, (byte) 0xc3, (byte) 0xca, (byte) 0x67,
+        (byte) 0x80, (byte) 0xf6, (byte) 0x03, (byte) 0x46, (byte) 0x65, (byte) 0x77, (byte) 0x59, (byte) 0xbb,
+        (byte) 0xb8, (byte) 0x83, (byte) 0xee, (byte) 0xc2, (byte) 0x3e, (byte) 0x78, (byte) 0xdd, (byte) 0x89,
+        (byte) 0xcd, (byte) 0x9b, (byte) 0x78, (byte) 0x35, (byte) 0xa9, (byte) 0x09, (byte) 0xc8, (byte) 0x77,
+        (byte) 0xdd, (byte) 0xd3, (byte) 0xa0, (byte) 0x64, (byte) 0xb0, (byte) 0x74, (byte) 0x48, (byte) 0x51,
+        (byte) 0x4f, (byte) 0xa0, (byte) 0xae, (byte) 0x33, (byte) 0xb3, (byte) 0x28, (byte) 0xb0, (byte) 0xa8,
+        (byte) 0x78, (byte) 0x8f, (byte) 0xa2, (byte) 0x32, (byte) 0xa6, (byte) 0x0a, (byte) 0xaa, (byte) 0x09,
+        (byte) 0xb5, (byte) 0x8d, (byte) 0x4c, (byte) 0x44, (byte) 0x46, (byte) 0xb4, (byte) 0xd2, (byte) 0x06,
+        (byte) 0x6b, (byte) 0x8c, (byte) 0x51, (byte) 0x6e, (byte) 0x9c, (byte) 0xfa, (byte) 0x1f, (byte) 0x94,
+        (byte) 0x3e, (byte) 0x19, (byte) 0x9c, (byte) 0x63, (byte) 0xfe, (byte) 0xa9, (byte) 0x9a, (byte) 0xe3,
+        (byte) 0x6c, (byte) 0x82, (byte) 0x64, (byte) 0x5f, (byte) 0xca, (byte) 0xc2, (byte) 0x8d, (byte) 0x66,
+        (byte) 0xbe, (byte) 0x12, (byte) 0x6e, (byte) 0xb6, (byte) 0x35, (byte) 0x6d, (byte) 0xaa, (byte) 0xed,
+        (byte) 0x4b, (byte) 0x50, (byte) 0x08, (byte) 0x1c, (byte) 0xbf, (byte) 0x07, (byte) 0x70, (byte) 0x78,
+        (byte) 0xc0, (byte) 0xbb, (byte) 0xc5, (byte) 0x8d, (byte) 0x6c, (byte) 0x8d, (byte) 0x35, (byte) 0xff,
+        (byte) 0x04, (byte) 0x81, (byte) 0xd8, (byte) 0xf4, (byte) 0xd2, (byte) 0x4a, (byte) 0xc3, (byte) 0x05,
+        (byte) 0x23, (byte) 0xcb, (byte) 0xeb, (byte) 0x20, (byte) 0xb1, (byte) 0xd4, (byte) 0x2d, (byte) 0xd8,
+        (byte) 0x7a, (byte) 0xd4, (byte) 0x7e, (byte) 0xf6, (byte) 0xa9, (byte) 0xe8, (byte) 0x72, (byte) 0x69,
+        (byte) 0xfe, (byte) 0xab, (byte) 0x54, (byte) 0x4d, (byte) 0xd1, (byte) 0xf4, (byte) 0x6b, (byte) 0x83,
+        (byte) 0x31, (byte) 0x17, (byte) 0xed, (byte) 0x26, (byte) 0xe9, (byte) 0xd2, (byte) 0x5b, (byte) 0xad,
+        (byte) 0x42, (byte) 0x42, (byte) 0xa5, (byte) 0x8f, (byte) 0x98, (byte) 0x7c, (byte) 0x1b, (byte) 0x5c,
+        (byte) 0x8e, (byte) 0x88, (byte) 0x56, (byte) 0x20, (byte) 0x8e, (byte) 0x48, (byte) 0xf9, (byte) 0x4d,
+        (byte) 0x82, (byte) 0x91, (byte) 0xcb, (byte) 0xc8, (byte) 0x1c, (byte) 0x7c, (byte) 0xa5, (byte) 0x69,
+        (byte) 0x1b, (byte) 0x40, (byte) 0xc2, (byte) 0x4c, (byte) 0x25, (byte) 0x16, (byte) 0x4f, (byte) 0xfa,
+        (byte) 0x09, (byte) 0xeb, (byte) 0xf5, (byte) 0x6c, (byte) 0x55, (byte) 0x3c, (byte) 0x6e, (byte) 0xf7,
+        (byte) 0xc0, (byte) 0xc1, (byte) 0x34, (byte) 0xd1, (byte) 0x53, (byte) 0xa3, (byte) 0x69, (byte) 0x64,
+        (byte) 0xee, (byte) 0xf4, (byte) 0xf9, (byte) 0xc7, (byte) 0x96, (byte) 0x60, (byte) 0x84, (byte) 0x87,
+        (byte) 0xb4, (byte) 0xc7, (byte) 0x3c, (byte) 0x26, (byte) 0xa7, (byte) 0x3a, (byte) 0xbf, (byte) 0x95,
+    };
+
+    private static final byte[] MD5withRSA_Vector2Signature = new byte[] {
+        (byte) 0x04, (byte) 0x17, (byte) 0x83, (byte) 0x10, (byte) 0xe2, (byte) 0x6e, (byte) 0xdf, (byte) 0xa9,
+        (byte) 0xae, (byte) 0xd2, (byte) 0xdc, (byte) 0x5f, (byte) 0x70, (byte) 0x1d, (byte) 0xaf, (byte) 0x54,
+        (byte) 0xc0, (byte) 0x5f, (byte) 0x0b, (byte) 0x2c, (byte) 0xe6, (byte) 0xd0, (byte) 0x00, (byte) 0x18,
+        (byte) 0x4c, (byte) 0xf6, (byte) 0x8f, (byte) 0x18, (byte) 0x10, (byte) 0x74, (byte) 0x90, (byte) 0x99,
+        (byte) 0xa9, (byte) 0x90, (byte) 0x3c, (byte) 0x5a, (byte) 0x38, (byte) 0xd3, (byte) 0x3d, (byte) 0x48,
+        (byte) 0xcf, (byte) 0x31, (byte) 0xaf, (byte) 0x12, (byte) 0x98, (byte) 0xfb, (byte) 0x66, (byte) 0xe8,
+        (byte) 0x58, (byte) 0xec, (byte) 0xca, (byte) 0xe1, (byte) 0x42, (byte) 0xf9, (byte) 0x84, (byte) 0x17,
+        (byte) 0x6f, (byte) 0x4c, (byte) 0x3e, (byte) 0xc4, (byte) 0x40, (byte) 0xc6, (byte) 0x70, (byte) 0xb0,
+        (byte) 0x38, (byte) 0xf3, (byte) 0x47, (byte) 0xeb, (byte) 0x6f, (byte) 0xcb, (byte) 0xea, (byte) 0x21,
+        (byte) 0x41, (byte) 0xf3, (byte) 0xa0, (byte) 0x3e, (byte) 0x42, (byte) 0xad, (byte) 0xa5, (byte) 0xad,
+        (byte) 0x5d, (byte) 0x2c, (byte) 0x1a, (byte) 0x8e, (byte) 0x3e, (byte) 0xb3, (byte) 0xa5, (byte) 0x78,
+        (byte) 0x3d, (byte) 0x56, (byte) 0x09, (byte) 0x93, (byte) 0xc9, (byte) 0x93, (byte) 0xd3, (byte) 0xd2,
+        (byte) 0x9a, (byte) 0xc5, (byte) 0xa5, (byte) 0x2e, (byte) 0xb2, (byte) 0xd8, (byte) 0x37, (byte) 0xc7,
+        (byte) 0x13, (byte) 0x1a, (byte) 0x0b, (byte) 0xda, (byte) 0x50, (byte) 0x28, (byte) 0x6d, (byte) 0x47,
+        (byte) 0x65, (byte) 0x52, (byte) 0xcd, (byte) 0xe7, (byte) 0xec, (byte) 0x57, (byte) 0x00, (byte) 0x41,
+        (byte) 0x34, (byte) 0x28, (byte) 0xb9, (byte) 0x8b, (byte) 0x03, (byte) 0x41, (byte) 0xb6, (byte) 0xd5,
+        (byte) 0xa8, (byte) 0xef, (byte) 0xd3, (byte) 0xdd, (byte) 0x80, (byte) 0xd5, (byte) 0x69, (byte) 0xe4,
+        (byte) 0xf0, (byte) 0x4d, (byte) 0xa4, (byte) 0x7d, (byte) 0x60, (byte) 0x2f, (byte) 0xef, (byte) 0x79,
+        (byte) 0x07, (byte) 0x75, (byte) 0xeb, (byte) 0xf7, (byte) 0x4b, (byte) 0x43, (byte) 0x41, (byte) 0xdb,
+        (byte) 0x33, (byte) 0xad, (byte) 0x9c, (byte) 0x7b, (byte) 0x78, (byte) 0x83, (byte) 0x34, (byte) 0x77,
+        (byte) 0xe4, (byte) 0x80, (byte) 0xbe, (byte) 0xe6, (byte) 0x6f, (byte) 0xdd, (byte) 0xac, (byte) 0xa5,
+        (byte) 0x37, (byte) 0xcf, (byte) 0xb5, (byte) 0x44, (byte) 0x11, (byte) 0x77, (byte) 0x96, (byte) 0x45,
+        (byte) 0xf9, (byte) 0xae, (byte) 0x48, (byte) 0xa6, (byte) 0xbe, (byte) 0x30, (byte) 0x32, (byte) 0xeb,
+        (byte) 0x43, (byte) 0x6f, (byte) 0x66, (byte) 0x39, (byte) 0x57, (byte) 0xf8, (byte) 0xe6, (byte) 0x60,
+        (byte) 0x31, (byte) 0xd0, (byte) 0xfc, (byte) 0xcf, (byte) 0x9f, (byte) 0xe5, (byte) 0x3d, (byte) 0xcf,
+        (byte) 0xbd, (byte) 0x7b, (byte) 0x13, (byte) 0x20, (byte) 0xce, (byte) 0x11, (byte) 0xfd, (byte) 0xe5,
+        (byte) 0xff, (byte) 0x90, (byte) 0x85, (byte) 0xdf, (byte) 0xca, (byte) 0x3d, (byte) 0xd9, (byte) 0x44,
+        (byte) 0x16, (byte) 0xc2, (byte) 0x32, (byte) 0x28, (byte) 0xc7, (byte) 0x01, (byte) 0x6d, (byte) 0xea,
+        (byte) 0xcb, (byte) 0x0d, (byte) 0x85, (byte) 0x08, (byte) 0x6f, (byte) 0xcb, (byte) 0x41, (byte) 0x6a,
+        (byte) 0x3c, (byte) 0x0f, (byte) 0x3d, (byte) 0x38, (byte) 0xb5, (byte) 0x61, (byte) 0xc5, (byte) 0x64,
+        (byte) 0x64, (byte) 0x81, (byte) 0x4c, (byte) 0xcd, (byte) 0xd1, (byte) 0x6a, (byte) 0x87, (byte) 0x28,
+        (byte) 0x02, (byte) 0xaf, (byte) 0x8f, (byte) 0x59, (byte) 0xe5, (byte) 0x67, (byte) 0x25, (byte) 0x00,
+    };
+
+    /*
+     * openssl rsautl -raw -sign -inkey rsa.key | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] NONEwithRSA_Vector1Signature = new byte[] {
+        (byte) 0x35, (byte) 0x43, (byte) 0x38, (byte) 0x44, (byte) 0xAD, (byte) 0x3F,
+        (byte) 0x97, (byte) 0x02, (byte) 0xFB, (byte) 0x59, (byte) 0x1F, (byte) 0x4A,
+        (byte) 0x2B, (byte) 0xB9, (byte) 0x06, (byte) 0xEC, (byte) 0x66, (byte) 0xE6,
+        (byte) 0xD2, (byte) 0xC5, (byte) 0x8B, (byte) 0x7B, (byte) 0xE3, (byte) 0x18,
+        (byte) 0xBF, (byte) 0x07, (byte) 0xD6, (byte) 0x01, (byte) 0xF9, (byte) 0xD9,
+        (byte) 0x89, (byte) 0xC4, (byte) 0xDB, (byte) 0x00, (byte) 0x68, (byte) 0xFF,
+        (byte) 0x9B, (byte) 0x43, (byte) 0x90, (byte) 0xF2, (byte) 0xDB, (byte) 0x83,
+        (byte) 0xF4, (byte) 0x7E, (byte) 0xC6, (byte) 0x81, (byte) 0x01, (byte) 0x3A,
+        (byte) 0x0B, (byte) 0xE5, (byte) 0xED, (byte) 0x08, (byte) 0x73, (byte) 0x3E,
+        (byte) 0xE1, (byte) 0x3F, (byte) 0xDF, (byte) 0x1F, (byte) 0x07, (byte) 0x6D,
+        (byte) 0x22, (byte) 0x8D, (byte) 0xCC, (byte) 0x4E, (byte) 0xE3, (byte) 0x9A,
+        (byte) 0xBC, (byte) 0xCC, (byte) 0x8F, (byte) 0x9E, (byte) 0x9B, (byte) 0x02,
+        (byte) 0x48, (byte) 0x00, (byte) 0xAC, (byte) 0x9F, (byte) 0xA4, (byte) 0x8F,
+        (byte) 0x87, (byte) 0xA1, (byte) 0xA8, (byte) 0xE6, (byte) 0x9D, (byte) 0xCD,
+        (byte) 0x8B, (byte) 0x05, (byte) 0xE9, (byte) 0xD2, (byte) 0x05, (byte) 0x8D,
+        (byte) 0xC9, (byte) 0x95, (byte) 0x16, (byte) 0xD0, (byte) 0xCD, (byte) 0x43,
+        (byte) 0x25, (byte) 0x8A, (byte) 0x11, (byte) 0x46, (byte) 0xD7, (byte) 0x74,
+        (byte) 0x4C, (byte) 0xCF, (byte) 0x58, (byte) 0xF9, (byte) 0xA1, (byte) 0x30,
+        (byte) 0x84, (byte) 0x52, (byte) 0xC9, (byte) 0x01, (byte) 0x5F, (byte) 0x24,
+        (byte) 0x4C, (byte) 0xB1, (byte) 0x9F, (byte) 0x7D, (byte) 0x12, (byte) 0x38,
+        (byte) 0x27, (byte) 0x0F, (byte) 0x5E, (byte) 0xFF, (byte) 0xE0, (byte) 0x55,
+        (byte) 0x8B, (byte) 0xA3, (byte) 0xAD, (byte) 0x60, (byte) 0x35, (byte) 0x83,
+        (byte) 0x58, (byte) 0xAF, (byte) 0x99, (byte) 0xDE, (byte) 0x3F, (byte) 0x5D,
+        (byte) 0x80, (byte) 0x80, (byte) 0xFF, (byte) 0x9B, (byte) 0xDE, (byte) 0x5C,
+        (byte) 0xAB, (byte) 0x97, (byte) 0x43, (byte) 0x64, (byte) 0xD9, (byte) 0x9F,
+        (byte) 0xFB, (byte) 0x67, (byte) 0x65, (byte) 0xA5, (byte) 0x99, (byte) 0xE7,
+        (byte) 0xE6, (byte) 0xEB, (byte) 0x05, (byte) 0x95, (byte) 0xFC, (byte) 0x46,
+        (byte) 0x28, (byte) 0x4B, (byte) 0xD8, (byte) 0x8C, (byte) 0xF5, (byte) 0x0A,
+        (byte) 0xEB, (byte) 0x1F, (byte) 0x30, (byte) 0xEA, (byte) 0xE7, (byte) 0x67,
+        (byte) 0x11, (byte) 0x25, (byte) 0xF0, (byte) 0x44, (byte) 0x75, (byte) 0x74,
+        (byte) 0x94, (byte) 0x06, (byte) 0x78, (byte) 0xD0, (byte) 0x21, (byte) 0xF4,
+        (byte) 0x3F, (byte) 0xC8, (byte) 0xC4, (byte) 0x4A, (byte) 0x57, (byte) 0xBE,
+        (byte) 0x02, (byte) 0x3C, (byte) 0x93, (byte) 0xF6, (byte) 0x95, (byte) 0xFB,
+        (byte) 0xD1, (byte) 0x77, (byte) 0x8B, (byte) 0x43, (byte) 0xF0, (byte) 0xB9,
+        (byte) 0x7D, (byte) 0xE0, (byte) 0x32, (byte) 0xE1, (byte) 0x72, (byte) 0xB5,
+        (byte) 0x62, (byte) 0x3F, (byte) 0x86, (byte) 0xC3, (byte) 0xD4, (byte) 0x5F,
+        (byte) 0x5E, (byte) 0x54, (byte) 0x1B, (byte) 0x5B, (byte) 0xE6, (byte) 0x74,
+        (byte) 0xA1, (byte) 0x0B, (byte) 0xE5, (byte) 0x18, (byte) 0xD2, (byte) 0x4F,
+        (byte) 0x93, (byte) 0xF3, (byte) 0x09, (byte) 0x58, (byte) 0xCE, (byte) 0xF0,
+        (byte) 0xA3, (byte) 0x61, (byte) 0xE4, (byte) 0x6E, (byte) 0x46, (byte) 0x45,
+        (byte) 0x89, (byte) 0x50, (byte) 0xBD, (byte) 0x03, (byte) 0x3F, (byte) 0x38,
+        (byte) 0xDA, (byte) 0x5D, (byte) 0xD0, (byte) 0x1B, (byte) 0x1F, (byte) 0xB1,
+        (byte) 0xEE, (byte) 0x89, (byte) 0x59, (byte) 0xC5,
+    };
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:20 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA1withRSAPSS_Vector2Signature = new byte[] {
+        (byte) 0x66, (byte) 0xE3, (byte) 0xA5, (byte) 0x20, (byte) 0xE9, (byte) 0x5D,
+        (byte) 0xDF, (byte) 0x99, (byte) 0xA6, (byte) 0x04, (byte) 0x77, (byte) 0xF8,
+        (byte) 0x39, (byte) 0x78, (byte) 0x74, (byte) 0xF5, (byte) 0xC2, (byte) 0x4E,
+        (byte) 0x9E, (byte) 0xEB, (byte) 0x24, (byte) 0xDE, (byte) 0xB4, (byte) 0x36,
+        (byte) 0x69, (byte) 0x1F, (byte) 0xAC, (byte) 0x01, (byte) 0xFF, (byte) 0x5A,
+        (byte) 0xE3, (byte) 0x89, (byte) 0x8A, (byte) 0xE9, (byte) 0x92, (byte) 0x32,
+        (byte) 0xA7, (byte) 0xA4, (byte) 0xC0, (byte) 0x25, (byte) 0x00, (byte) 0x14,
+        (byte) 0xFF, (byte) 0x38, (byte) 0x19, (byte) 0x37, (byte) 0x84, (byte) 0x1A,
+        (byte) 0x3D, (byte) 0xCA, (byte) 0xEE, (byte) 0xF3, (byte) 0xC6, (byte) 0x91,
+        (byte) 0xED, (byte) 0x02, (byte) 0xE6, (byte) 0x1D, (byte) 0x73, (byte) 0xDA,
+        (byte) 0xD4, (byte) 0x55, (byte) 0x93, (byte) 0x54, (byte) 0x9A, (byte) 0xE6,
+        (byte) 0x2E, (byte) 0x7D, (byte) 0x5C, (byte) 0x41, (byte) 0xAF, (byte) 0xED,
+        (byte) 0xAD, (byte) 0x8E, (byte) 0x7F, (byte) 0x47, (byte) 0x3B, (byte) 0x23,
+        (byte) 0xC3, (byte) 0xB8, (byte) 0xBB, (byte) 0xCD, (byte) 0x87, (byte) 0xC4,
+        (byte) 0xA3, (byte) 0x32, (byte) 0x16, (byte) 0x57, (byte) 0xCC, (byte) 0xB8,
+        (byte) 0xB6, (byte) 0x96, (byte) 0x84, (byte) 0x1A, (byte) 0xBC, (byte) 0xF8,
+        (byte) 0x09, (byte) 0x53, (byte) 0xB0, (byte) 0x9D, (byte) 0xE1, (byte) 0x6F,
+        (byte) 0xB2, (byte) 0xEB, (byte) 0x83, (byte) 0xDC, (byte) 0x61, (byte) 0x31,
+        (byte) 0xD7, (byte) 0x02, (byte) 0xB4, (byte) 0xD1, (byte) 0xBA, (byte) 0xBD,
+        (byte) 0xF0, (byte) 0x78, (byte) 0xC6, (byte) 0xBE, (byte) 0x1F, (byte) 0xB0,
+        (byte) 0xE1, (byte) 0xCA, (byte) 0x32, (byte) 0x57, (byte) 0x9F, (byte) 0x8C,
+        (byte) 0xD3, (byte) 0xBB, (byte) 0x04, (byte) 0x1B, (byte) 0x30, (byte) 0x74,
+        (byte) 0x5D, (byte) 0xEA, (byte) 0xD3, (byte) 0x6B, (byte) 0x74, (byte) 0x31,
+        (byte) 0x6F, (byte) 0x33, (byte) 0x5A, (byte) 0x70, (byte) 0x96, (byte) 0x8B,
+        (byte) 0xCB, (byte) 0x22, (byte) 0xF3, (byte) 0xAA, (byte) 0x74, (byte) 0x82,
+        (byte) 0xB2, (byte) 0x82, (byte) 0x71, (byte) 0x4D, (byte) 0x42, (byte) 0x13,
+        (byte) 0x3F, (byte) 0xEA, (byte) 0xE3, (byte) 0x39, (byte) 0xC5, (byte) 0x03,
+        (byte) 0x27, (byte) 0xFF, (byte) 0x78, (byte) 0xB2, (byte) 0xA6, (byte) 0x71,
+        (byte) 0x07, (byte) 0x1C, (byte) 0xB3, (byte) 0x97, (byte) 0xFB, (byte) 0xE8,
+        (byte) 0x85, (byte) 0x6D, (byte) 0x14, (byte) 0xDF, (byte) 0xF9, (byte) 0x7D,
+        (byte) 0x0D, (byte) 0x0C, (byte) 0x9F, (byte) 0xC3, (byte) 0xE2, (byte) 0xDB,
+        (byte) 0xE0, (byte) 0xA5, (byte) 0x05, (byte) 0xBC, (byte) 0x47, (byte) 0x36,
+        (byte) 0xEB, (byte) 0x1E, (byte) 0xBA, (byte) 0x60, (byte) 0x12, (byte) 0x19,
+        (byte) 0xA5, (byte) 0x7E, (byte) 0x55, (byte) 0x0C, (byte) 0x9B, (byte) 0xD4,
+        (byte) 0x9A, (byte) 0xE9, (byte) 0x72, (byte) 0x5C, (byte) 0x5B, (byte) 0xF4,
+        (byte) 0xAA, (byte) 0x4A, (byte) 0x12, (byte) 0x8B, (byte) 0xC2, (byte) 0x8E,
+        (byte) 0xC2, (byte) 0x9A, (byte) 0x3E, (byte) 0x0C, (byte) 0x40, (byte) 0xA4,
+        (byte) 0x0A, (byte) 0xFF, (byte) 0xF8, (byte) 0xC1, (byte) 0x85, (byte) 0x59,
+        (byte) 0xDA, (byte) 0xC6, (byte) 0x8C, (byte) 0x83, (byte) 0x2A, (byte) 0x68,
+        (byte) 0x84, (byte) 0x53, (byte) 0x17, (byte) 0x28, (byte) 0x78, (byte) 0x3F,
+        (byte) 0x5A, (byte) 0xA4, (byte) 0x04, (byte) 0xE6, (byte) 0x23, (byte) 0x8D,
+        (byte) 0x2A, (byte) 0x71, (byte) 0xC1, (byte) 0xBC, (byte) 0x1C, (byte) 0xFD,
+        (byte) 0x75, (byte) 0x16, (byte) 0x6E, (byte) 0x85,
+    };
+    private static final PSSParameterSpec SHA1withRSAPSS_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:0 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA1withRSAPSS_NoSalt_Vector2Signature = new byte[] {
+        (byte) 0x31, (byte) 0x61, (byte) 0xA5, (byte) 0x47, (byte) 0x28, (byte) 0x44,
+        (byte) 0x48, (byte) 0x5A, (byte) 0xDA, (byte) 0x78, (byte) 0xA7, (byte) 0x85,
+        (byte) 0xE9, (byte) 0x64, (byte) 0x69, (byte) 0xCF, (byte) 0x14, (byte) 0x07,
+        (byte) 0x3F, (byte) 0xA8, (byte) 0xDB, (byte) 0xFC, (byte) 0xB7, (byte) 0x89,
+        (byte) 0x87, (byte) 0x74, (byte) 0xB9, (byte) 0x81, (byte) 0x37, (byte) 0x62,
+        (byte) 0xD1, (byte) 0x07, (byte) 0x0F, (byte) 0x3D, (byte) 0xDF, (byte) 0xA8,
+        (byte) 0x84, (byte) 0x38, (byte) 0x31, (byte) 0xEB, (byte) 0x17, (byte) 0x3F,
+        (byte) 0xE0, (byte) 0x28, (byte) 0x75, (byte) 0x1F, (byte) 0xE9, (byte) 0x4D,
+        (byte) 0xD3, (byte) 0x62, (byte) 0xFA, (byte) 0xCF, (byte) 0xCC, (byte) 0x2E,
+        (byte) 0xC7, (byte) 0x81, (byte) 0xE1, (byte) 0xEA, (byte) 0xEC, (byte) 0x78,
+        (byte) 0xFE, (byte) 0x19, (byte) 0x59, (byte) 0x54, (byte) 0x1D, (byte) 0x27,
+        (byte) 0xED, (byte) 0x0C, (byte) 0x54, (byte) 0xDF, (byte) 0xE3, (byte) 0x44,
+        (byte) 0x31, (byte) 0x21, (byte) 0x31, (byte) 0xA7, (byte) 0x23, (byte) 0xC4,
+        (byte) 0xE2, (byte) 0x69, (byte) 0x8A, (byte) 0xB3, (byte) 0x1A, (byte) 0x72,
+        (byte) 0x4F, (byte) 0x4E, (byte) 0x82, (byte) 0x86, (byte) 0x2D, (byte) 0x2B,
+        (byte) 0x85, (byte) 0xFE, (byte) 0x4A, (byte) 0x28, (byte) 0x90, (byte) 0xF7,
+        (byte) 0xDF, (byte) 0xD6, (byte) 0xB1, (byte) 0x3E, (byte) 0xC6, (byte) 0xFB,
+        (byte) 0x76, (byte) 0x7B, (byte) 0x3D, (byte) 0x12, (byte) 0x81, (byte) 0x6E,
+        (byte) 0xFD, (byte) 0x00, (byte) 0x7D, (byte) 0xD0, (byte) 0xDC, (byte) 0x25,
+        (byte) 0xD0, (byte) 0x86, (byte) 0x6C, (byte) 0xE8, (byte) 0x0F, (byte) 0x09,
+        (byte) 0x82, (byte) 0x74, (byte) 0x89, (byte) 0x79, (byte) 0x69, (byte) 0x73,
+        (byte) 0x37, (byte) 0x64, (byte) 0xEE, (byte) 0x53, (byte) 0x57, (byte) 0x20,
+        (byte) 0xFA, (byte) 0x0B, (byte) 0x4A, (byte) 0x5A, (byte) 0x4D, (byte) 0x33,
+        (byte) 0xAC, (byte) 0x8B, (byte) 0x04, (byte) 0xA5, (byte) 0x4A, (byte) 0x1A,
+        (byte) 0x9B, (byte) 0x66, (byte) 0xAA, (byte) 0x0B, (byte) 0x3D, (byte) 0x15,
+        (byte) 0xD9, (byte) 0x3E, (byte) 0x2F, (byte) 0xD2, (byte) 0xA1, (byte) 0x28,
+        (byte) 0x13, (byte) 0x59, (byte) 0x98, (byte) 0xC3, (byte) 0x45, (byte) 0x7C,
+        (byte) 0xEE, (byte) 0x60, (byte) 0xD0, (byte) 0xBD, (byte) 0x42, (byte) 0x16,
+        (byte) 0x84, (byte) 0x19, (byte) 0xF6, (byte) 0xD9, (byte) 0xF7, (byte) 0x7D,
+        (byte) 0x77, (byte) 0xAD, (byte) 0x60, (byte) 0xE2, (byte) 0xE3, (byte) 0x22,
+        (byte) 0xB9, (byte) 0xFA, (byte) 0xD5, (byte) 0xFA, (byte) 0x6E, (byte) 0x1F,
+        (byte) 0x69, (byte) 0x3F, (byte) 0xB1, (byte) 0xA7, (byte) 0x1A, (byte) 0x22,
+        (byte) 0xF7, (byte) 0x31, (byte) 0x97, (byte) 0x68, (byte) 0x62, (byte) 0x0F,
+        (byte) 0x39, (byte) 0xB0, (byte) 0xE7, (byte) 0x63, (byte) 0xAE, (byte) 0x65,
+        (byte) 0x69, (byte) 0xD0, (byte) 0xD3, (byte) 0x56, (byte) 0xC9, (byte) 0xA6,
+        (byte) 0xA4, (byte) 0xA5, (byte) 0xA4, (byte) 0x61, (byte) 0xA9, (byte) 0xC4,
+        (byte) 0x45, (byte) 0xCD, (byte) 0x49, (byte) 0x76, (byte) 0xC8, (byte) 0x53,
+        (byte) 0x46, (byte) 0xD0, (byte) 0x63, (byte) 0x35, (byte) 0x89, (byte) 0x04,
+        (byte) 0x22, (byte) 0xD7, (byte) 0xB6, (byte) 0x63, (byte) 0xAF, (byte) 0xC2,
+        (byte) 0x97, (byte) 0x10, (byte) 0xDF, (byte) 0xDE, (byte) 0xE6, (byte) 0x39,
+        (byte) 0x25, (byte) 0x2F, (byte) 0xEA, (byte) 0xD8, (byte) 0x56, (byte) 0x5A,
+        (byte) 0xC1, (byte) 0xB8, (byte) 0xCA, (byte) 0xC1, (byte) 0x8A, (byte) 0xB8,
+        (byte) 0x87, (byte) 0x2F, (byte) 0xCD, (byte) 0x21,
+    };
+    private static final PSSParameterSpec SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 0, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha1 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha1 -pkeyopt rsa_pss_saltlen:234 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA1withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
+        (byte) 0x49, (byte) 0xDB, (byte) 0xAD, (byte) 0x48, (byte) 0x7C, (byte) 0x06,
+        (byte) 0x03, (byte) 0x7C, (byte) 0x58, (byte) 0xE1, (byte) 0x38, (byte) 0x20,
+        (byte) 0x46, (byte) 0x28, (byte) 0x60, (byte) 0x64, (byte) 0x94, (byte) 0x51,
+        (byte) 0xA3, (byte) 0xD1, (byte) 0xC9, (byte) 0x52, (byte) 0xC6, (byte) 0x2A,
+        (byte) 0xB3, (byte) 0xCC, (byte) 0xD6, (byte) 0x19, (byte) 0x50, (byte) 0x99,
+        (byte) 0x60, (byte) 0x58, (byte) 0xA2, (byte) 0x86, (byte) 0xA8, (byte) 0x74,
+        (byte) 0x50, (byte) 0x8C, (byte) 0x0E, (byte) 0x32, (byte) 0x58, (byte) 0x56,
+        (byte) 0x6D, (byte) 0x30, (byte) 0x38, (byte) 0xFB, (byte) 0x26, (byte) 0xC3,
+        (byte) 0xFD, (byte) 0x8E, (byte) 0x36, (byte) 0x73, (byte) 0x82, (byte) 0x9A,
+        (byte) 0xB4, (byte) 0xE5, (byte) 0x22, (byte) 0x96, (byte) 0x55, (byte) 0x3C,
+        (byte) 0x18, (byte) 0xD7, (byte) 0x46, (byte) 0xF1, (byte) 0x7C, (byte) 0xE6,
+        (byte) 0x8E, (byte) 0x0A, (byte) 0x18, (byte) 0xA7, (byte) 0x29, (byte) 0x96,
+        (byte) 0x8D, (byte) 0xFC, (byte) 0x0E, (byte) 0xBE, (byte) 0x91, (byte) 0xA0,
+        (byte) 0xF8, (byte) 0xE2, (byte) 0x70, (byte) 0x5A, (byte) 0xE3, (byte) 0x76,
+        (byte) 0xAC, (byte) 0x18, (byte) 0x10, (byte) 0xB4, (byte) 0xB1, (byte) 0xFF,
+        (byte) 0x58, (byte) 0xBC, (byte) 0x10, (byte) 0xF5, (byte) 0x88, (byte) 0x2F,
+        (byte) 0x0B, (byte) 0x10, (byte) 0x9D, (byte) 0x52, (byte) 0x2D, (byte) 0x42,
+        (byte) 0xDB, (byte) 0xFD, (byte) 0xA7, (byte) 0x23, (byte) 0x3C, (byte) 0x4B,
+        (byte) 0xB3, (byte) 0xD2, (byte) 0x96, (byte) 0x1B, (byte) 0xCE, (byte) 0xB3,
+        (byte) 0xA3, (byte) 0xC3, (byte) 0x42, (byte) 0xA4, (byte) 0x0E, (byte) 0x35,
+        (byte) 0x5C, (byte) 0xC2, (byte) 0x32, (byte) 0xC7, (byte) 0x8C, (byte) 0xFC,
+        (byte) 0x7F, (byte) 0xE0, (byte) 0xF7, (byte) 0x1D, (byte) 0x38, (byte) 0x21,
+        (byte) 0x3C, (byte) 0xDF, (byte) 0x82, (byte) 0x1A, (byte) 0xBD, (byte) 0x83,
+        (byte) 0xE9, (byte) 0x56, (byte) 0xF0, (byte) 0xF1, (byte) 0x54, (byte) 0x76,
+        (byte) 0xE3, (byte) 0xCE, (byte) 0x86, (byte) 0x69, (byte) 0xC2, (byte) 0x61,
+        (byte) 0x6D, (byte) 0x8E, (byte) 0xF5, (byte) 0xA3, (byte) 0x61, (byte) 0xCA,
+        (byte) 0x16, (byte) 0xCB, (byte) 0x7A, (byte) 0xF5, (byte) 0xBF, (byte) 0x36,
+        (byte) 0xCB, (byte) 0x7D, (byte) 0xB1, (byte) 0xE9, (byte) 0x70, (byte) 0x41,
+        (byte) 0xCF, (byte) 0x89, (byte) 0x51, (byte) 0x13, (byte) 0xCC, (byte) 0x95,
+        (byte) 0x50, (byte) 0xC8, (byte) 0xB6, (byte) 0x30, (byte) 0x35, (byte) 0xE3,
+        (byte) 0x13, (byte) 0x08, (byte) 0xF6, (byte) 0xBE, (byte) 0x20, (byte) 0xF1,
+        (byte) 0x48, (byte) 0x4D, (byte) 0x46, (byte) 0x95, (byte) 0xFE, (byte) 0x9E,
+        (byte) 0xD2, (byte) 0xD5, (byte) 0x29, (byte) 0x81, (byte) 0x2E, (byte) 0x0F,
+        (byte) 0x6F, (byte) 0xA7, (byte) 0x02, (byte) 0x15, (byte) 0xCA, (byte) 0x75,
+        (byte) 0x77, (byte) 0x29, (byte) 0x7C, (byte) 0x3A, (byte) 0xE3, (byte) 0x2B,
+        (byte) 0xD7, (byte) 0x3D, (byte) 0x5C, (byte) 0x94, (byte) 0x3B, (byte) 0x2A,
+        (byte) 0x91, (byte) 0xDB, (byte) 0xFA, (byte) 0x69, (byte) 0x47, (byte) 0x1C,
+        (byte) 0x2C, (byte) 0x46, (byte) 0x49, (byte) 0xE6, (byte) 0x37, (byte) 0x5D,
+        (byte) 0x78, (byte) 0x71, (byte) 0x76, (byte) 0xC1, (byte) 0xB6, (byte) 0x2E,
+        (byte) 0x4E, (byte) 0x3C, (byte) 0x83, (byte) 0x6F, (byte) 0x82, (byte) 0xC3,
+        (byte) 0xD8, (byte) 0x50, (byte) 0xD7, (byte) 0x1B, (byte) 0xAF, (byte) 0xF9,
+        (byte) 0xE3, (byte) 0xF1, (byte) 0x47, (byte) 0xC8, (byte) 0x12, (byte) 0x86,
+        (byte) 0x82, (byte) 0x9D, (byte) 0x3F, (byte) 0xCE,
+    };
+    private static final PSSParameterSpec SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 234, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:28 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA224withRSAPSS_Vector2Signature = new byte[] {
+        (byte) 0x86, (byte) 0x41, (byte) 0xCC, (byte) 0x4B, (byte) 0x82, (byte) 0x74,
+        (byte) 0x04, (byte) 0x43, (byte) 0x8C, (byte) 0xAB, (byte) 0xF6, (byte) 0x3B,
+        (byte) 0xFB, (byte) 0x94, (byte) 0xBC, (byte) 0x4C, (byte) 0x0A, (byte) 0xFE,
+        (byte) 0x0F, (byte) 0x4F, (byte) 0x0F, (byte) 0x9F, (byte) 0x84, (byte) 0x35,
+        (byte) 0x57, (byte) 0x8B, (byte) 0x8D, (byte) 0xC3, (byte) 0x58, (byte) 0xA6,
+        (byte) 0x70, (byte) 0xAC, (byte) 0x40, (byte) 0x6D, (byte) 0xBC, (byte) 0xC1,
+        (byte) 0x6A, (byte) 0xFA, (byte) 0x31, (byte) 0x3B, (byte) 0x7A, (byte) 0x23,
+        (byte) 0xCA, (byte) 0x1F, (byte) 0xCD, (byte) 0xA7, (byte) 0xE3, (byte) 0xD6,
+        (byte) 0x7C, (byte) 0x2C, (byte) 0xF3, (byte) 0x6F, (byte) 0xF5, (byte) 0x82,
+        (byte) 0x9E, (byte) 0x18, (byte) 0x70, (byte) 0x90, (byte) 0xE6, (byte) 0xA3,
+        (byte) 0x44, (byte) 0x61, (byte) 0xB6, (byte) 0x46, (byte) 0x9B, (byte) 0x0D,
+        (byte) 0xE5, (byte) 0x3C, (byte) 0xAE, (byte) 0x22, (byte) 0xF4, (byte) 0x87,
+        (byte) 0xB7, (byte) 0x03, (byte) 0xD8, (byte) 0x42, (byte) 0x33, (byte) 0x4E,
+        (byte) 0xCC, (byte) 0x7A, (byte) 0xDF, (byte) 0xD7, (byte) 0x57, (byte) 0xEB,
+        (byte) 0x51, (byte) 0x6C, (byte) 0xB1, (byte) 0x99, (byte) 0x4D, (byte) 0x94,
+        (byte) 0x82, (byte) 0xA7, (byte) 0x69, (byte) 0x85, (byte) 0x8D, (byte) 0x82,
+        (byte) 0x18, (byte) 0xE4, (byte) 0x53, (byte) 0xF5, (byte) 0x9F, (byte) 0x82,
+        (byte) 0x1C, (byte) 0xE1, (byte) 0x25, (byte) 0x1C, (byte) 0x8E, (byte) 0xE7,
+        (byte) 0xC1, (byte) 0xEC, (byte) 0xBE, (byte) 0x3F, (byte) 0xC3, (byte) 0xED,
+        (byte) 0x41, (byte) 0x89, (byte) 0x94, (byte) 0x13, (byte) 0x11, (byte) 0x75,
+        (byte) 0x3F, (byte) 0x38, (byte) 0x52, (byte) 0x58, (byte) 0xAB, (byte) 0x88,
+        (byte) 0x01, (byte) 0x30, (byte) 0xB4, (byte) 0xCD, (byte) 0x45, (byte) 0x3E,
+        (byte) 0x1A, (byte) 0x5F, (byte) 0x36, (byte) 0xF8, (byte) 0x51, (byte) 0x90,
+        (byte) 0x6E, (byte) 0x6F, (byte) 0x31, (byte) 0x9D, (byte) 0x40, (byte) 0x90,
+        (byte) 0x1A, (byte) 0xA8, (byte) 0x10, (byte) 0xEF, (byte) 0x9D, (byte) 0xF8,
+        (byte) 0xB0, (byte) 0x03, (byte) 0x01, (byte) 0xFB, (byte) 0xD8, (byte) 0x3D,
+        (byte) 0x83, (byte) 0x79, (byte) 0x01, (byte) 0xA7, (byte) 0x82, (byte) 0xC2,
+        (byte) 0x46, (byte) 0x35, (byte) 0x68, (byte) 0xD2, (byte) 0x08, (byte) 0x81,
+        (byte) 0x31, (byte) 0x14, (byte) 0xE8, (byte) 0x13, (byte) 0x8C, (byte) 0xD4,
+        (byte) 0xC4, (byte) 0xCB, (byte) 0xB9, (byte) 0x85, (byte) 0x25, (byte) 0x93,
+        (byte) 0x40, (byte) 0x88, (byte) 0x34, (byte) 0x11, (byte) 0xDA, (byte) 0xFF,
+        (byte) 0xEF, (byte) 0x4D, (byte) 0xDC, (byte) 0x31, (byte) 0x74, (byte) 0x7B,
+        (byte) 0x5E, (byte) 0xA7, (byte) 0x51, (byte) 0x15, (byte) 0x13, (byte) 0xB1,
+        (byte) 0x9E, (byte) 0x06, (byte) 0x51, (byte) 0xBA, (byte) 0x11, (byte) 0xDA,
+        (byte) 0x64, (byte) 0x1B, (byte) 0x78, (byte) 0x76, (byte) 0x57, (byte) 0x96,
+        (byte) 0xF3, (byte) 0x1B, (byte) 0x86, (byte) 0xB2, (byte) 0xF3, (byte) 0x66,
+        (byte) 0x64, (byte) 0x2B, (byte) 0x04, (byte) 0x81, (byte) 0x8C, (byte) 0xDC,
+        (byte) 0xE0, (byte) 0xEA, (byte) 0x66, (byte) 0x62, (byte) 0x44, (byte) 0x31,
+        (byte) 0xA2, (byte) 0x19, (byte) 0xF1, (byte) 0x77, (byte) 0x67, (byte) 0x58,
+        (byte) 0x18, (byte) 0x5B, (byte) 0xCB, (byte) 0xBA, (byte) 0x28, (byte) 0x91,
+        (byte) 0x47, (byte) 0x5B, (byte) 0x4F, (byte) 0x17, (byte) 0x23, (byte) 0x2A,
+        (byte) 0xE4, (byte) 0xB0, (byte) 0xAE, (byte) 0x82, (byte) 0x4E, (byte) 0xCA,
+        (byte) 0xA6, (byte) 0x12, (byte) 0xCA, (byte) 0x70,
+    };
+    private static final PSSParameterSpec SHA224withRSAPSS_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 28, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:0 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA224withRSAPSS_NoSalt_Vector2Signature = new byte[] {
+        (byte) 0xD8, (byte) 0x38, (byte) 0x48, (byte) 0xCD, (byte) 0xA4, (byte) 0x09,
+        (byte) 0x36, (byte) 0x35, (byte) 0x47, (byte) 0x55, (byte) 0xDB, (byte) 0x6C,
+        (byte) 0x2D, (byte) 0x83, (byte) 0x17, (byte) 0x10, (byte) 0x3E, (byte) 0xCE,
+        (byte) 0x95, (byte) 0x02, (byte) 0x58, (byte) 0xCE, (byte) 0xA8, (byte) 0x02,
+        (byte) 0x44, (byte) 0xB7, (byte) 0xE4, (byte) 0x32, (byte) 0x3D, (byte) 0x50,
+        (byte) 0xE1, (byte) 0x8C, (byte) 0xF3, (byte) 0x24, (byte) 0x6F, (byte) 0xA4,
+        (byte) 0x2D, (byte) 0xD7, (byte) 0xFB, (byte) 0x70, (byte) 0x97, (byte) 0xBE,
+        (byte) 0xED, (byte) 0x27, (byte) 0x2D, (byte) 0x22, (byte) 0xDC, (byte) 0x62,
+        (byte) 0x97, (byte) 0x66, (byte) 0x39, (byte) 0xE0, (byte) 0x36, (byte) 0x5F,
+        (byte) 0x07, (byte) 0x78, (byte) 0xAF, (byte) 0x5E, (byte) 0xDC, (byte) 0xFD,
+        (byte) 0x21, (byte) 0xA8, (byte) 0xD5, (byte) 0xA7, (byte) 0xD1, (byte) 0xBA,
+        (byte) 0x1C, (byte) 0xDA, (byte) 0xCA, (byte) 0x80, (byte) 0x72, (byte) 0x8A,
+        (byte) 0xDD, (byte) 0x5C, (byte) 0x16, (byte) 0x6A, (byte) 0x47, (byte) 0xFC,
+        (byte) 0x11, (byte) 0x42, (byte) 0x7E, (byte) 0x4E, (byte) 0x3F, (byte) 0x49,
+        (byte) 0xCF, (byte) 0x2F, (byte) 0x54, (byte) 0xD7, (byte) 0x13, (byte) 0x76,
+        (byte) 0x5D, (byte) 0xE9, (byte) 0x2A, (byte) 0x29, (byte) 0xCC, (byte) 0x73,
+        (byte) 0xDB, (byte) 0xE5, (byte) 0xDE, (byte) 0x48, (byte) 0xA2, (byte) 0xE9,
+        (byte) 0xD1, (byte) 0xD0, (byte) 0x35, (byte) 0xFE, (byte) 0xA1, (byte) 0x1C,
+        (byte) 0x13, (byte) 0x04, (byte) 0x75, (byte) 0x77, (byte) 0xF4, (byte) 0x55,
+        (byte) 0x03, (byte) 0xC4, (byte) 0x6D, (byte) 0xAC, (byte) 0x25, (byte) 0x1D,
+        (byte) 0x57, (byte) 0xFF, (byte) 0x0D, (byte) 0xE0, (byte) 0x91, (byte) 0xEA,
+        (byte) 0xF6, (byte) 0x1F, (byte) 0x3F, (byte) 0x69, (byte) 0xD6, (byte) 0x00,
+        (byte) 0xBD, (byte) 0x89, (byte) 0xEA, (byte) 0xD3, (byte) 0x31, (byte) 0x80,
+        (byte) 0x5E, (byte) 0x04, (byte) 0x4C, (byte) 0x59, (byte) 0xDE, (byte) 0xD0,
+        (byte) 0x62, (byte) 0x93, (byte) 0x3B, (byte) 0xC9, (byte) 0x9F, (byte) 0xE7,
+        (byte) 0x69, (byte) 0xC0, (byte) 0xB8, (byte) 0xED, (byte) 0xBF, (byte) 0x0D,
+        (byte) 0x60, (byte) 0x28, (byte) 0x55, (byte) 0x20, (byte) 0x0C, (byte) 0x9F,
+        (byte) 0xA2, (byte) 0x42, (byte) 0x34, (byte) 0x95, (byte) 0xAE, (byte) 0xF8,
+        (byte) 0x67, (byte) 0x7C, (byte) 0xF1, (byte) 0xA0, (byte) 0xC0, (byte) 0x74,
+        (byte) 0xF2, (byte) 0xDF, (byte) 0x75, (byte) 0x5B, (byte) 0x6E, (byte) 0x2F,
+        (byte) 0xFB, (byte) 0x1F, (byte) 0xDD, (byte) 0xC3, (byte) 0xD3, (byte) 0x90,
+        (byte) 0x0A, (byte) 0x33, (byte) 0xF6, (byte) 0x03, (byte) 0x16, (byte) 0xC4,
+        (byte) 0xF8, (byte) 0xED, (byte) 0xB7, (byte) 0x45, (byte) 0x39, (byte) 0x5D,
+        (byte) 0x7C, (byte) 0xF8, (byte) 0x82, (byte) 0xCE, (byte) 0x7D, (byte) 0xFB,
+        (byte) 0x02, (byte) 0x2D, (byte) 0xE0, (byte) 0x96, (byte) 0x35, (byte) 0x60,
+        (byte) 0x5D, (byte) 0xBC, (byte) 0x35, (byte) 0x80, (byte) 0x4C, (byte) 0x39,
+        (byte) 0x7C, (byte) 0xE7, (byte) 0xD4, (byte) 0xB4, (byte) 0x19, (byte) 0xD1,
+        (byte) 0xE5, (byte) 0x8E, (byte) 0x6D, (byte) 0x25, (byte) 0x0C, (byte) 0xB9,
+        (byte) 0x0C, (byte) 0x8D, (byte) 0x45, (byte) 0xE4, (byte) 0x67, (byte) 0x73,
+        (byte) 0xCF, (byte) 0x87, (byte) 0x7C, (byte) 0x78, (byte) 0xAA, (byte) 0xB9,
+        (byte) 0x42, (byte) 0xAE, (byte) 0x7F, (byte) 0xB8, (byte) 0xEC, (byte) 0x4F,
+        (byte) 0xD2, (byte) 0x85, (byte) 0x01, (byte) 0x80, (byte) 0x00, (byte) 0xBD,
+        (byte) 0xF5, (byte) 0xEA, (byte) 0x44, (byte) 0x6D,
+    };
+    private static final PSSParameterSpec SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 0, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha224 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha224 -pkeyopt rsa_pss_saltlen:226 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA224withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
+        (byte) 0x2C, (byte) 0x19, (byte) 0x5E, (byte) 0x63, (byte) 0xC5, (byte) 0x32,
+        (byte) 0xC3, (byte) 0xC7, (byte) 0x52, (byte) 0xE9, (byte) 0x69, (byte) 0x4C,
+        (byte) 0x04, (byte) 0xE5, (byte) 0x4A, (byte) 0xF2, (byte) 0x72, (byte) 0x78,
+        (byte) 0xBF, (byte) 0xC5, (byte) 0x8D, (byte) 0x5A, (byte) 0x71, (byte) 0xEF,
+        (byte) 0xA9, (byte) 0x58, (byte) 0x77, (byte) 0x94, (byte) 0x49, (byte) 0x71,
+        (byte) 0xBF, (byte) 0x45, (byte) 0x3E, (byte) 0xA4, (byte) 0x2E, (byte) 0x33,
+        (byte) 0x9B, (byte) 0x4E, (byte) 0xA4, (byte) 0x95, (byte) 0x07, (byte) 0x9C,
+        (byte) 0xAA, (byte) 0xC4, (byte) 0xA8, (byte) 0x60, (byte) 0xBC, (byte) 0xCD,
+        (byte) 0xC3, (byte) 0x45, (byte) 0xE6, (byte) 0xBC, (byte) 0xAD, (byte) 0xB6,
+        (byte) 0xF3, (byte) 0x0E, (byte) 0xF6, (byte) 0xD5, (byte) 0xCF, (byte) 0x33,
+        (byte) 0xA3, (byte) 0x82, (byte) 0x62, (byte) 0x52, (byte) 0x95, (byte) 0xA8,
+        (byte) 0x0E, (byte) 0xD4, (byte) 0xAC, (byte) 0x1F, (byte) 0x9A, (byte) 0xDC,
+        (byte) 0x00, (byte) 0xD6, (byte) 0x78, (byte) 0xEA, (byte) 0x53, (byte) 0x00,
+        (byte) 0x19, (byte) 0xE3, (byte) 0x81, (byte) 0x7C, (byte) 0x7A, (byte) 0x8E,
+        (byte) 0x30, (byte) 0x57, (byte) 0xB7, (byte) 0x81, (byte) 0xD7, (byte) 0x4D,
+        (byte) 0x1D, (byte) 0xCB, (byte) 0x99, (byte) 0x8D, (byte) 0xE4, (byte) 0xFA,
+        (byte) 0x6E, (byte) 0x4E, (byte) 0xA6, (byte) 0xDA, (byte) 0x13, (byte) 0x92,
+        (byte) 0x31, (byte) 0x7C, (byte) 0x2B, (byte) 0x3A, (byte) 0xA0, (byte) 0xF1,
+        (byte) 0x03, (byte) 0x83, (byte) 0x12, (byte) 0xD1, (byte) 0x23, (byte) 0xED,
+        (byte) 0xC4, (byte) 0x01, (byte) 0x57, (byte) 0x63, (byte) 0xAF, (byte) 0x40,
+        (byte) 0x15, (byte) 0xEC, (byte) 0xB8, (byte) 0x5A, (byte) 0xCE, (byte) 0x3D,
+        (byte) 0x3E, (byte) 0xCD, (byte) 0xD8, (byte) 0xF3, (byte) 0x76, (byte) 0xCA,
+        (byte) 0x23, (byte) 0x20, (byte) 0x68, (byte) 0x17, (byte) 0x5B, (byte) 0x7F,
+        (byte) 0xBC, (byte) 0x22, (byte) 0x67, (byte) 0x2A, (byte) 0x91, (byte) 0x05,
+        (byte) 0xB3, (byte) 0x85, (byte) 0x60, (byte) 0xD8, (byte) 0x76, (byte) 0xD5,
+        (byte) 0x2B, (byte) 0x9C, (byte) 0x80, (byte) 0xB6, (byte) 0xEA, (byte) 0x1E,
+        (byte) 0x05, (byte) 0xC7, (byte) 0x95, (byte) 0x2C, (byte) 0x4F, (byte) 0x14,
+        (byte) 0x5F, (byte) 0xEE, (byte) 0x08, (byte) 0x32, (byte) 0xF7, (byte) 0x12,
+        (byte) 0x2B, (byte) 0xCD, (byte) 0xF3, (byte) 0x83, (byte) 0x7C, (byte) 0xCE,
+        (byte) 0x04, (byte) 0x8A, (byte) 0x36, (byte) 0x3D, (byte) 0xB2, (byte) 0x97,
+        (byte) 0x15, (byte) 0xDB, (byte) 0xD6, (byte) 0xFA, (byte) 0x53, (byte) 0x29,
+        (byte) 0xD1, (byte) 0x43, (byte) 0x55, (byte) 0xDD, (byte) 0xAE, (byte) 0xA7,
+        (byte) 0xB4, (byte) 0x2C, (byte) 0xD9, (byte) 0xA7, (byte) 0x74, (byte) 0xA8,
+        (byte) 0x08, (byte) 0xD6, (byte) 0xC2, (byte) 0x05, (byte) 0xBF, (byte) 0x67,
+        (byte) 0x3B, (byte) 0xBA, (byte) 0x8D, (byte) 0x99, (byte) 0xC1, (byte) 0x14,
+        (byte) 0x1A, (byte) 0x32, (byte) 0xCA, (byte) 0xD5, (byte) 0xCC, (byte) 0xF9,
+        (byte) 0x64, (byte) 0x07, (byte) 0x5B, (byte) 0xB8, (byte) 0xA9, (byte) 0x69,
+        (byte) 0xED, (byte) 0x01, (byte) 0xCD, (byte) 0xD2, (byte) 0x88, (byte) 0x67,
+        (byte) 0xFF, (byte) 0x92, (byte) 0xA3, (byte) 0xC6, (byte) 0x97, (byte) 0x97,
+        (byte) 0xA1, (byte) 0xC5, (byte) 0x15, (byte) 0xC8, (byte) 0xB6, (byte) 0xFE,
+        (byte) 0x4A, (byte) 0x07, (byte) 0x2E, (byte) 0x46, (byte) 0x3F, (byte) 0x27,
+        (byte) 0xB8, (byte) 0xEE, (byte) 0x69, (byte) 0xCB, (byte) 0xDC, (byte) 0x30,
+        (byte) 0x19, (byte) 0x77, (byte) 0xC5, (byte) 0xEF,
+    };
+    private static final PSSParameterSpec SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-224", "MGF1", new MGF1ParameterSpec("SHA-224"), 226, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:32 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA256withRSAPSS_Vector2Signature = new byte[] {
+        (byte) 0x94, (byte) 0x33, (byte) 0xCB, (byte) 0x9E, (byte) 0x2C, (byte) 0x17,
+        (byte) 0x46, (byte) 0xB3, (byte) 0x8F, (byte) 0xB7, (byte) 0x93, (byte) 0x98,
+        (byte) 0xA3, (byte) 0x45, (byte) 0xEA, (byte) 0xD4, (byte) 0x51, (byte) 0x60,
+        (byte) 0x3E, (byte) 0x00, (byte) 0xA3, (byte) 0x93, (byte) 0x05, (byte) 0x0F,
+        (byte) 0xCB, (byte) 0x6E, (byte) 0xFF, (byte) 0xA5, (byte) 0x97, (byte) 0x18,
+        (byte) 0xF6, (byte) 0xED, (byte) 0x6B, (byte) 0x6C, (byte) 0xAD, (byte) 0x9C,
+        (byte) 0x73, (byte) 0x63, (byte) 0x9C, (byte) 0x5B, (byte) 0xA5, (byte) 0xA1,
+        (byte) 0x42, (byte) 0xA3, (byte) 0x0E, (byte) 0x32, (byte) 0xF5, (byte) 0xF0,
+        (byte) 0x55, (byte) 0xEE, (byte) 0x58, (byte) 0xC1, (byte) 0xBD, (byte) 0x99,
+        (byte) 0x0A, (byte) 0x2B, (byte) 0xFD, (byte) 0xBD, (byte) 0x1E, (byte) 0x23,
+        (byte) 0xEF, (byte) 0x99, (byte) 0x7D, (byte) 0xC1, (byte) 0xE2, (byte) 0xD5,
+        (byte) 0x71, (byte) 0x6C, (byte) 0x96, (byte) 0x70, (byte) 0xC3, (byte) 0x75,
+        (byte) 0x48, (byte) 0x83, (byte) 0x85, (byte) 0x5E, (byte) 0xC6, (byte) 0x3A,
+        (byte) 0xFF, (byte) 0xE5, (byte) 0xF1, (byte) 0x6B, (byte) 0x85, (byte) 0x7B,
+        (byte) 0x61, (byte) 0xA6, (byte) 0xB1, (byte) 0xCF, (byte) 0x60, (byte) 0x09,
+        (byte) 0x32, (byte) 0xAF, (byte) 0xEF, (byte) 0x95, (byte) 0xA4, (byte) 0x1B,
+        (byte) 0xD6, (byte) 0xFA, (byte) 0xD0, (byte) 0xD7, (byte) 0x17, (byte) 0xCA,
+        (byte) 0xB0, (byte) 0x19, (byte) 0x21, (byte) 0x7F, (byte) 0x5E, (byte) 0x9B,
+        (byte) 0xBB, (byte) 0xB8, (byte) 0xE0, (byte) 0xB1, (byte) 0x95, (byte) 0xB3,
+        (byte) 0xDA, (byte) 0x0B, (byte) 0xB8, (byte) 0xFA, (byte) 0x15, (byte) 0x75,
+        (byte) 0x73, (byte) 0x88, (byte) 0xC8, (byte) 0x45, (byte) 0x33, (byte) 0xD1,
+        (byte) 0x5C, (byte) 0xB7, (byte) 0xFB, (byte) 0x38, (byte) 0x05, (byte) 0xA0,
+        (byte) 0x85, (byte) 0x99, (byte) 0x2C, (byte) 0xB1, (byte) 0xC2, (byte) 0xFE,
+        (byte) 0xAC, (byte) 0x5D, (byte) 0x2C, (byte) 0x1B, (byte) 0xD3, (byte) 0x42,
+        (byte) 0x81, (byte) 0xC8, (byte) 0x1C, (byte) 0xB7, (byte) 0x53, (byte) 0x7E,
+        (byte) 0xC5, (byte) 0x9F, (byte) 0x84, (byte) 0x97, (byte) 0x6F, (byte) 0x00,
+        (byte) 0xC3, (byte) 0x5E, (byte) 0x8B, (byte) 0x67, (byte) 0x3D, (byte) 0x9A,
+        (byte) 0xD0, (byte) 0xE2, (byte) 0x9B, (byte) 0x2D, (byte) 0xC6, (byte) 0xD8,
+        (byte) 0xEF, (byte) 0x19, (byte) 0x14, (byte) 0x49, (byte) 0x88, (byte) 0x52,
+        (byte) 0xF7, (byte) 0x93, (byte) 0xEB, (byte) 0xDB, (byte) 0xB6, (byte) 0x55,
+        (byte) 0x05, (byte) 0xB6, (byte) 0xE7, (byte) 0x70, (byte) 0xE4, (byte) 0x5A,
+        (byte) 0x9E, (byte) 0x80, (byte) 0x78, (byte) 0x48, (byte) 0xA8, (byte) 0xE5,
+        (byte) 0x59, (byte) 0x8D, (byte) 0x1C, (byte) 0x5D, (byte) 0x95, (byte) 0x38,
+        (byte) 0x25, (byte) 0xFC, (byte) 0x38, (byte) 0xC3, (byte) 0xFF, (byte) 0xE2,
+        (byte) 0x6F, (byte) 0xE4, (byte) 0xFC, (byte) 0x64, (byte) 0x8B, (byte) 0xCA,
+        (byte) 0x91, (byte) 0x5F, (byte) 0x0B, (byte) 0x4E, (byte) 0x9A, (byte) 0xB5,
+        (byte) 0x22, (byte) 0x5D, (byte) 0xC5, (byte) 0x5A, (byte) 0x77, (byte) 0xED,
+        (byte) 0x23, (byte) 0xE0, (byte) 0x13, (byte) 0x8F, (byte) 0xAC, (byte) 0x13,
+        (byte) 0xE5, (byte) 0x81, (byte) 0xEE, (byte) 0xD1, (byte) 0xAD, (byte) 0x8A,
+        (byte) 0x0F, (byte) 0x2B, (byte) 0x4C, (byte) 0xB2, (byte) 0x13, (byte) 0x54,
+        (byte) 0x44, (byte) 0x8E, (byte) 0x53, (byte) 0xE2, (byte) 0x33, (byte) 0x14,
+        (byte) 0x7F, (byte) 0x9B, (byte) 0xA9, (byte) 0xD3, (byte) 0xBB, (byte) 0xFC,
+        (byte) 0xAC, (byte) 0xC9, (byte) 0x31, (byte) 0xB6,
+    };
+    private static final PSSParameterSpec SHA256withRSAPSS_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:0 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA256withRSAPSS_NoSalt_Vector2Signature = new byte[] {
+        (byte) 0x4C, (byte) 0xB7, (byte) 0x33, (byte) 0x78, (byte) 0x0A, (byte) 0xA7,
+        (byte) 0xEB, (byte) 0x35, (byte) 0x5E, (byte) 0x99, (byte) 0x8F, (byte) 0xE9,
+        (byte) 0x2A, (byte) 0x3D, (byte) 0x8C, (byte) 0x9B, (byte) 0x19, (byte) 0xC7,
+        (byte) 0xC8, (byte) 0xB8, (byte) 0x10, (byte) 0xC5, (byte) 0x6D, (byte) 0xA4,
+        (byte) 0x44, (byte) 0x3E, (byte) 0xAB, (byte) 0x90, (byte) 0x82, (byte) 0x70,
+        (byte) 0xFA, (byte) 0x7B, (byte) 0xE6, (byte) 0x06, (byte) 0x36, (byte) 0x06,
+        (byte) 0x93, (byte) 0x54, (byte) 0x50, (byte) 0xCD, (byte) 0x5F, (byte) 0xAA,
+        (byte) 0x01, (byte) 0x42, (byte) 0xAD, (byte) 0xB9, (byte) 0x02, (byte) 0x6E,
+        (byte) 0xAE, (byte) 0x60, (byte) 0x00, (byte) 0x60, (byte) 0x55, (byte) 0x1B,
+        (byte) 0xBB, (byte) 0x9E, (byte) 0x03, (byte) 0xB7, (byte) 0x86, (byte) 0x3D,
+        (byte) 0xCC, (byte) 0xFA, (byte) 0x6E, (byte) 0x20, (byte) 0x07, (byte) 0x61,
+        (byte) 0x8F, (byte) 0x53, (byte) 0xC6, (byte) 0x2B, (byte) 0xEF, (byte) 0x8F,
+        (byte) 0x0F, (byte) 0x8B, (byte) 0x80, (byte) 0x22, (byte) 0xDC, (byte) 0x9E,
+        (byte) 0x20, (byte) 0x4A, (byte) 0x57, (byte) 0xA1, (byte) 0x15, (byte) 0xE0,
+        (byte) 0x01, (byte) 0x95, (byte) 0xDB, (byte) 0x46, (byte) 0x85, (byte) 0x6D,
+        (byte) 0x27, (byte) 0x9F, (byte) 0x44, (byte) 0x3B, (byte) 0xB1, (byte) 0x35,
+        (byte) 0x04, (byte) 0x9D, (byte) 0xF8, (byte) 0xC6, (byte) 0xD7, (byte) 0xD7,
+        (byte) 0xEF, (byte) 0x9A, (byte) 0x53, (byte) 0x5A, (byte) 0x73, (byte) 0xB3,
+        (byte) 0xD0, (byte) 0x32, (byte) 0x39, (byte) 0xE1, (byte) 0x28, (byte) 0x3A,
+        (byte) 0x9D, (byte) 0x69, (byte) 0x4E, (byte) 0x57, (byte) 0xC1, (byte) 0xDF,
+        (byte) 0xFE, (byte) 0x5F, (byte) 0xA8, (byte) 0xFF, (byte) 0xE8, (byte) 0x75,
+        (byte) 0x85, (byte) 0x33, (byte) 0x90, (byte) 0x83, (byte) 0x3D, (byte) 0x8F,
+        (byte) 0x15, (byte) 0x47, (byte) 0x16, (byte) 0xF2, (byte) 0x32, (byte) 0xF9,
+        (byte) 0x46, (byte) 0x96, (byte) 0xCC, (byte) 0x2E, (byte) 0x8F, (byte) 0x27,
+        (byte) 0x3F, (byte) 0xCF, (byte) 0x91, (byte) 0xA6, (byte) 0x9E, (byte) 0xBF,
+        (byte) 0x42, (byte) 0x2F, (byte) 0xD6, (byte) 0x52, (byte) 0xD7, (byte) 0x3B,
+        (byte) 0xCD, (byte) 0xFE, (byte) 0x0B, (byte) 0x4A, (byte) 0x3B, (byte) 0x19,
+        (byte) 0x57, (byte) 0x47, (byte) 0x65, (byte) 0x33, (byte) 0xD9, (byte) 0xF7,
+        (byte) 0xE4, (byte) 0xC3, (byte) 0x05, (byte) 0x49, (byte) 0x3C, (byte) 0xC0,
+        (byte) 0xDF, (byte) 0xC1, (byte) 0x54, (byte) 0x18, (byte) 0x8D, (byte) 0xDA,
+        (byte) 0xE4, (byte) 0x59, (byte) 0xE9, (byte) 0x3B, (byte) 0xD6, (byte) 0x89,
+        (byte) 0x07, (byte) 0x99, (byte) 0xB0, (byte) 0xF4, (byte) 0x09, (byte) 0x0A,
+        (byte) 0x2C, (byte) 0xBA, (byte) 0x0B, (byte) 0xE4, (byte) 0x79, (byte) 0xB1,
+        (byte) 0xDB, (byte) 0xAD, (byte) 0xAB, (byte) 0x5D, (byte) 0xA2, (byte) 0x1E,
+        (byte) 0x76, (byte) 0x7F, (byte) 0x74, (byte) 0x62, (byte) 0x49, (byte) 0x07,
+        (byte) 0x7A, (byte) 0x5B, (byte) 0xD7, (byte) 0x0F, (byte) 0xA4, (byte) 0x2C,
+        (byte) 0x36, (byte) 0x13, (byte) 0x42, (byte) 0xBA, (byte) 0xCF, (byte) 0x0A,
+        (byte) 0xFC, (byte) 0xC3, (byte) 0x31, (byte) 0x5E, (byte) 0x06, (byte) 0x84,
+        (byte) 0x8A, (byte) 0x8A, (byte) 0x84, (byte) 0x0D, (byte) 0x48, (byte) 0xBD,
+        (byte) 0x67, (byte) 0xCF, (byte) 0x04, (byte) 0xB4, (byte) 0xFB, (byte) 0xBB,
+        (byte) 0x04, (byte) 0x91, (byte) 0xB1, (byte) 0x0A, (byte) 0xA4, (byte) 0x70,
+        (byte) 0x58, (byte) 0x1A, (byte) 0x9B, (byte) 0x02, (byte) 0x86, (byte) 0xBD,
+        (byte) 0xAE, (byte) 0x77, (byte) 0x97, (byte) 0x1C,
+    };
+    private static final PSSParameterSpec SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 0, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha256 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha256 -pkeyopt rsa_pss_saltlen:222 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA256withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
+        (byte) 0x3B, (byte) 0x43, (byte) 0xA8, (byte) 0xB5, (byte) 0x34, (byte) 0xD8,
+        (byte) 0xF9, (byte) 0xAD, (byte) 0xDD, (byte) 0x1F, (byte) 0x7A, (byte) 0x73,
+        (byte) 0xBF, (byte) 0xFA, (byte) 0xED, (byte) 0x10, (byte) 0xF3, (byte) 0x16,
+        (byte) 0xCC, (byte) 0xE5, (byte) 0x09, (byte) 0x0F, (byte) 0x68, (byte) 0x02,
+        (byte) 0xE7, (byte) 0x55, (byte) 0x0D, (byte) 0xCF, (byte) 0x1B, (byte) 0x83,
+        (byte) 0xCD, (byte) 0xA2, (byte) 0xD6, (byte) 0x02, (byte) 0xDD, (byte) 0x72,
+        (byte) 0xA6, (byte) 0x5F, (byte) 0x05, (byte) 0x8A, (byte) 0x1E, (byte) 0xA1,
+        (byte) 0x4F, (byte) 0x92, (byte) 0xD9, (byte) 0x09, (byte) 0x19, (byte) 0x6E,
+        (byte) 0x80, (byte) 0xA0, (byte) 0x47, (byte) 0x98, (byte) 0x5C, (byte) 0xF7,
+        (byte) 0x34, (byte) 0x52, (byte) 0x7D, (byte) 0x85, (byte) 0xCF, (byte) 0x9F,
+        (byte) 0xEB, (byte) 0xAF, (byte) 0xB4, (byte) 0x53, (byte) 0xF0, (byte) 0x5D,
+        (byte) 0x28, (byte) 0x87, (byte) 0xAC, (byte) 0xA7, (byte) 0xB4, (byte) 0xCF,
+        (byte) 0xDD, (byte) 0x8B, (byte) 0xA4, (byte) 0xC9, (byte) 0xCA, (byte) 0xAA,
+        (byte) 0xF4, (byte) 0xA8, (byte) 0x25, (byte) 0x26, (byte) 0x34, (byte) 0x11,
+        (byte) 0x14, (byte) 0x24, (byte) 0x1C, (byte) 0x1C, (byte) 0x50, (byte) 0xC8,
+        (byte) 0xFF, (byte) 0x7E, (byte) 0xFF, (byte) 0x6F, (byte) 0x4F, (byte) 0x14,
+        (byte) 0xB3, (byte) 0x57, (byte) 0x48, (byte) 0x0A, (byte) 0x5A, (byte) 0x95,
+        (byte) 0x5D, (byte) 0xEB, (byte) 0x71, (byte) 0x4E, (byte) 0x86, (byte) 0xFC,
+        (byte) 0x38, (byte) 0x1B, (byte) 0x93, (byte) 0x45, (byte) 0x09, (byte) 0x15,
+        (byte) 0xD3, (byte) 0x06, (byte) 0x6B, (byte) 0x9D, (byte) 0x05, (byte) 0x5C,
+        (byte) 0x4A, (byte) 0xB3, (byte) 0x93, (byte) 0xD1, (byte) 0x01, (byte) 0x54,
+        (byte) 0xCC, (byte) 0xED, (byte) 0xBF, (byte) 0x0E, (byte) 0x7E, (byte) 0x33,
+        (byte) 0x32, (byte) 0xA6, (byte) 0xA5, (byte) 0xF7, (byte) 0x3D, (byte) 0x2E,
+        (byte) 0xCB, (byte) 0x76, (byte) 0xA7, (byte) 0x22, (byte) 0x64, (byte) 0xB8,
+        (byte) 0x19, (byte) 0x53, (byte) 0xFE, (byte) 0x8C, (byte) 0xC8, (byte) 0x1E,
+        (byte) 0x6C, (byte) 0xEE, (byte) 0x08, (byte) 0x07, (byte) 0x7E, (byte) 0x93,
+        (byte) 0x43, (byte) 0x1B, (byte) 0xCF, (byte) 0x37, (byte) 0xE4, (byte) 0xAB,
+        (byte) 0xE7, (byte) 0xD7, (byte) 0x83, (byte) 0x8E, (byte) 0x19, (byte) 0xAE,
+        (byte) 0x05, (byte) 0x51, (byte) 0x91, (byte) 0x10, (byte) 0x7B, (byte) 0x70,
+        (byte) 0xFC, (byte) 0x73, (byte) 0x12, (byte) 0x96, (byte) 0xFA, (byte) 0xD0,
+        (byte) 0xCA, (byte) 0xA3, (byte) 0x59, (byte) 0xA7, (byte) 0xDD, (byte) 0xC3,
+        (byte) 0x1D, (byte) 0x9C, (byte) 0x7B, (byte) 0x50, (byte) 0xBB, (byte) 0x57,
+        (byte) 0xB8, (byte) 0x86, (byte) 0xF2, (byte) 0xCA, (byte) 0xC4, (byte) 0x86,
+        (byte) 0x7A, (byte) 0x96, (byte) 0x90, (byte) 0x02, (byte) 0xDF, (byte) 0xA0,
+        (byte) 0x88, (byte) 0x0E, (byte) 0x89, (byte) 0x45, (byte) 0x27, (byte) 0x52,
+        (byte) 0xDA, (byte) 0x86, (byte) 0x42, (byte) 0x4B, (byte) 0x90, (byte) 0xC3,
+        (byte) 0xC1, (byte) 0x41, (byte) 0x60, (byte) 0x5C, (byte) 0x29, (byte) 0x15,
+        (byte) 0xE5, (byte) 0x5C, (byte) 0x43, (byte) 0x9B, (byte) 0x40, (byte) 0xE5,
+        (byte) 0x04, (byte) 0x1B, (byte) 0x4A, (byte) 0x93, (byte) 0xDD, (byte) 0x55,
+        (byte) 0xC4, (byte) 0xFC, (byte) 0xFE, (byte) 0x0C, (byte) 0x65, (byte) 0x96,
+        (byte) 0x98, (byte) 0xDE, (byte) 0xC5, (byte) 0x05, (byte) 0xC5, (byte) 0x3E,
+        (byte) 0xB0, (byte) 0x25, (byte) 0x4E, (byte) 0x65, (byte) 0x24, (byte) 0x8D,
+        (byte) 0x4E, (byte) 0x9D, (byte) 0x94, (byte) 0x01,
+    };
+    private static final PSSParameterSpec SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 222, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:48 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA384withRSAPSS_Vector2Signature = new byte[] {
+        (byte) 0x20, (byte) 0xCB, (byte) 0x97, (byte) 0x9C, (byte) 0x2E, (byte) 0x51,
+        (byte) 0x59, (byte) 0x56, (byte) 0x9F, (byte) 0x04, (byte) 0x47, (byte) 0x7C,
+        (byte) 0x5C, (byte) 0x57, (byte) 0x59, (byte) 0xBC, (byte) 0x43, (byte) 0xD9,
+        (byte) 0x4B, (byte) 0xEC, (byte) 0xAC, (byte) 0xB9, (byte) 0x88, (byte) 0xA2,
+        (byte) 0x30, (byte) 0x8B, (byte) 0xEE, (byte) 0x2F, (byte) 0xC1, (byte) 0x73,
+        (byte) 0xF1, (byte) 0x13, (byte) 0xB2, (byte) 0x5E, (byte) 0x1A, (byte) 0xC8,
+        (byte) 0xD2, (byte) 0xAA, (byte) 0x27, (byte) 0x16, (byte) 0xA1, (byte) 0x14,
+        (byte) 0xAB, (byte) 0x45, (byte) 0x8A, (byte) 0x7E, (byte) 0x22, (byte) 0x22,
+        (byte) 0x2A, (byte) 0x2E, (byte) 0xDA, (byte) 0x6A, (byte) 0x7E, (byte) 0x3F,
+        (byte) 0x66, (byte) 0x99, (byte) 0x55, (byte) 0xAF, (byte) 0x2B, (byte) 0x94,
+        (byte) 0xD8, (byte) 0x6B, (byte) 0xC2, (byte) 0x60, (byte) 0xB5, (byte) 0x55,
+        (byte) 0xA9, (byte) 0x26, (byte) 0x29, (byte) 0xFC, (byte) 0x17, (byte) 0x56,
+        (byte) 0x05, (byte) 0xB7, (byte) 0x48, (byte) 0x2F, (byte) 0xAB, (byte) 0x68,
+        (byte) 0xCF, (byte) 0x37, (byte) 0x62, (byte) 0x79, (byte) 0x4F, (byte) 0x32,
+        (byte) 0x04, (byte) 0xF6, (byte) 0xEA, (byte) 0xBE, (byte) 0x79, (byte) 0x84,
+        (byte) 0x73, (byte) 0xEE, (byte) 0x1C, (byte) 0xEE, (byte) 0x9F, (byte) 0x72,
+        (byte) 0x7A, (byte) 0xC6, (byte) 0x64, (byte) 0xB4, (byte) 0x4F, (byte) 0xDE,
+        (byte) 0x0B, (byte) 0x38, (byte) 0x47, (byte) 0x62, (byte) 0xA9, (byte) 0xFD,
+        (byte) 0x1B, (byte) 0x75, (byte) 0xEC, (byte) 0xFE, (byte) 0x2D, (byte) 0x04,
+        (byte) 0x2D, (byte) 0x0A, (byte) 0xCE, (byte) 0x13, (byte) 0xFA, (byte) 0xDA,
+        (byte) 0x3F, (byte) 0x4C, (byte) 0x11, (byte) 0xEA, (byte) 0x02, (byte) 0x00,
+        (byte) 0x0A, (byte) 0x93, (byte) 0x12, (byte) 0xDC, (byte) 0x60, (byte) 0xE7,
+        (byte) 0x52, (byte) 0x90, (byte) 0x8A, (byte) 0xA3, (byte) 0xAE, (byte) 0xC5,
+        (byte) 0x9A, (byte) 0xD7, (byte) 0xD5, (byte) 0x0D, (byte) 0xBC, (byte) 0x7A,
+        (byte) 0xDB, (byte) 0xF4, (byte) 0x10, (byte) 0xE0, (byte) 0xDB, (byte) 0xC0,
+        (byte) 0x97, (byte) 0xF1, (byte) 0x84, (byte) 0xCF, (byte) 0x66, (byte) 0xB2,
+        (byte) 0x04, (byte) 0x58, (byte) 0x81, (byte) 0xB5, (byte) 0x9B, (byte) 0x4A,
+        (byte) 0xF9, (byte) 0xD7, (byte) 0xCA, (byte) 0x51, (byte) 0x09, (byte) 0x67,
+        (byte) 0x48, (byte) 0x7B, (byte) 0xE5, (byte) 0xE9, (byte) 0x07, (byte) 0x4E,
+        (byte) 0x6A, (byte) 0xC1, (byte) 0xA6, (byte) 0x68, (byte) 0x90, (byte) 0x17,
+        (byte) 0xAB, (byte) 0x0E, (byte) 0xFB, (byte) 0x3E, (byte) 0x39, (byte) 0x74,
+        (byte) 0x85, (byte) 0x04, (byte) 0x42, (byte) 0x0A, (byte) 0x9E, (byte) 0x02,
+        (byte) 0xA9, (byte) 0x50, (byte) 0xFF, (byte) 0x23, (byte) 0x2D, (byte) 0x30,
+        (byte) 0xDD, (byte) 0x17, (byte) 0xC0, (byte) 0x82, (byte) 0xF7, (byte) 0xBB,
+        (byte) 0x3B, (byte) 0x03, (byte) 0xBD, (byte) 0xB1, (byte) 0x96, (byte) 0xCD,
+        (byte) 0x71, (byte) 0x3F, (byte) 0x67, (byte) 0x59, (byte) 0x5E, (byte) 0x45,
+        (byte) 0xE0, (byte) 0x1C, (byte) 0x80, (byte) 0x52, (byte) 0xD7, (byte) 0xF0,
+        (byte) 0xC1, (byte) 0xE6, (byte) 0xCF, (byte) 0x59, (byte) 0x13, (byte) 0x25,
+        (byte) 0x6F, (byte) 0x9F, (byte) 0xBB, (byte) 0xB9, (byte) 0x7F, (byte) 0x7E,
+        (byte) 0x7D, (byte) 0x93, (byte) 0xD9, (byte) 0x3F, (byte) 0x95, (byte) 0xB7,
+        (byte) 0x9A, (byte) 0xDB, (byte) 0xE2, (byte) 0x2C, (byte) 0x53, (byte) 0x83,
+        (byte) 0x9A, (byte) 0x06, (byte) 0x6D, (byte) 0x22, (byte) 0x81, (byte) 0xB5,
+        (byte) 0x63, (byte) 0xAE, (byte) 0x4A, (byte) 0xEE,
+    };
+    private static final PSSParameterSpec SHA384withRSAPSS_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 48, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:0 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA384withRSAPSS_NoSalt_Vector2Signature = new byte[] {
+        (byte) 0x41, (byte) 0x0C, (byte) 0x3A, (byte) 0xEC, (byte) 0xF6, (byte) 0xD9,
+        (byte) 0x8F, (byte) 0xA3, (byte) 0x61, (byte) 0xBB, (byte) 0x03, (byte) 0xED,
+        (byte) 0xD9, (byte) 0x69, (byte) 0x7D, (byte) 0xE1, (byte) 0xE1, (byte) 0x4E,
+        (byte) 0x5E, (byte) 0x71, (byte) 0x4E, (byte) 0x88, (byte) 0x9C, (byte) 0x79,
+        (byte) 0xD3, (byte) 0x71, (byte) 0x28, (byte) 0x07, (byte) 0x28, (byte) 0x19,
+        (byte) 0x96, (byte) 0x55, (byte) 0x30, (byte) 0x81, (byte) 0x29, (byte) 0x5C,
+        (byte) 0x4A, (byte) 0x18, (byte) 0x69, (byte) 0x36, (byte) 0x74, (byte) 0xAC,
+        (byte) 0x99, (byte) 0xB1, (byte) 0xBC, (byte) 0xA0, (byte) 0xFC, (byte) 0x17,
+        (byte) 0xA4, (byte) 0xD1, (byte) 0xAE, (byte) 0x84, (byte) 0xA6, (byte) 0x09,
+        (byte) 0x6B, (byte) 0xB3, (byte) 0x02, (byte) 0xB2, (byte) 0x81, (byte) 0x04,
+        (byte) 0x59, (byte) 0x8C, (byte) 0xCF, (byte) 0xAD, (byte) 0xFB, (byte) 0x76,
+        (byte) 0x6F, (byte) 0xE2, (byte) 0x5E, (byte) 0x09, (byte) 0xE5, (byte) 0xBC,
+        (byte) 0x54, (byte) 0xBD, (byte) 0x08, (byte) 0xA8, (byte) 0x18, (byte) 0x60,
+        (byte) 0xAF, (byte) 0x09, (byte) 0x67, (byte) 0x15, (byte) 0x03, (byte) 0xA8,
+        (byte) 0x8B, (byte) 0x3F, (byte) 0x31, (byte) 0xB7, (byte) 0x76, (byte) 0xFD,
+        (byte) 0xF6, (byte) 0x82, (byte) 0xC7, (byte) 0x89, (byte) 0xC2, (byte) 0x47,
+        (byte) 0x80, (byte) 0x06, (byte) 0x4F, (byte) 0x8C, (byte) 0x9C, (byte) 0xD7,
+        (byte) 0x4F, (byte) 0x63, (byte) 0x1E, (byte) 0xF0, (byte) 0x34, (byte) 0xD7,
+        (byte) 0x91, (byte) 0xD2, (byte) 0x96, (byte) 0x62, (byte) 0xFD, (byte) 0x68,
+        (byte) 0xE3, (byte) 0xE0, (byte) 0xFB, (byte) 0x7D, (byte) 0x0A, (byte) 0xD7,
+        (byte) 0x52, (byte) 0xFE, (byte) 0xD1, (byte) 0x95, (byte) 0x9E, (byte) 0xD2,
+        (byte) 0x84, (byte) 0xBE, (byte) 0x3D, (byte) 0x1F, (byte) 0x8C, (byte) 0xC4,
+        (byte) 0xD6, (byte) 0xE3, (byte) 0xCF, (byte) 0xE8, (byte) 0xB3, (byte) 0x82,
+        (byte) 0x2E, (byte) 0xFA, (byte) 0x39, (byte) 0xA3, (byte) 0x20, (byte) 0x3C,
+        (byte) 0xBE, (byte) 0x6A, (byte) 0xFA, (byte) 0x04, (byte) 0xD2, (byte) 0x74,
+        (byte) 0x41, (byte) 0xDC, (byte) 0xE8, (byte) 0x0E, (byte) 0xE7, (byte) 0xF2,
+        (byte) 0x36, (byte) 0xD4, (byte) 0x2E, (byte) 0x6A, (byte) 0xCF, (byte) 0xDF,
+        (byte) 0x8B, (byte) 0x4B, (byte) 0x77, (byte) 0xE8, (byte) 0x0A, (byte) 0x64,
+        (byte) 0x86, (byte) 0x2C, (byte) 0xCA, (byte) 0x92, (byte) 0x01, (byte) 0xB2,
+        (byte) 0x8A, (byte) 0xB8, (byte) 0xB2, (byte) 0x6C, (byte) 0x0B, (byte) 0x18,
+        (byte) 0x90, (byte) 0x31, (byte) 0x93, (byte) 0x29, (byte) 0xBA, (byte) 0xB1,
+        (byte) 0x88, (byte) 0x94, (byte) 0x44, (byte) 0x0B, (byte) 0x38, (byte) 0x64,
+        (byte) 0xC1, (byte) 0xDE, (byte) 0x0B, (byte) 0xD8, (byte) 0xE4, (byte) 0xBA,
+        (byte) 0x0A, (byte) 0x41, (byte) 0x24, (byte) 0x35, (byte) 0xAA, (byte) 0xE3,
+        (byte) 0x59, (byte) 0x8E, (byte) 0x57, (byte) 0x51, (byte) 0x43, (byte) 0xE1,
+        (byte) 0x9C, (byte) 0xF6, (byte) 0xF8, (byte) 0x16, (byte) 0x68, (byte) 0x83,
+        (byte) 0x08, (byte) 0x8C, (byte) 0x2D, (byte) 0x40, (byte) 0xD2, (byte) 0xEF,
+        (byte) 0xD6, (byte) 0xAE, (byte) 0x98, (byte) 0x77, (byte) 0xE8, (byte) 0xF2,
+        (byte) 0xC7, (byte) 0x19, (byte) 0x61, (byte) 0xD6, (byte) 0x43, (byte) 0xCD,
+        (byte) 0x76, (byte) 0x2E, (byte) 0x7A, (byte) 0xCB, (byte) 0x1A, (byte) 0x5D,
+        (byte) 0x73, (byte) 0x45, (byte) 0xF2, (byte) 0x7C, (byte) 0xD0, (byte) 0x88,
+        (byte) 0x83, (byte) 0x51, (byte) 0xF3, (byte) 0x19, (byte) 0x0F, (byte) 0xD5,
+        (byte) 0x40, (byte) 0x3F, (byte) 0xD9, (byte) 0xBF,
+    };
+    private static final PSSParameterSpec SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 0, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha384 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha384 -pkeyopt rsa_pss_saltlen:206 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA384withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
+        (byte) 0xDE, (byte) 0xF7, (byte) 0xC3, (byte) 0x21, (byte) 0x79, (byte) 0x0F,
+        (byte) 0x55, (byte) 0xD1, (byte) 0x56, (byte) 0x9A, (byte) 0xB0, (byte) 0x08,
+        (byte) 0xA1, (byte) 0x27, (byte) 0xC9, (byte) 0x5E, (byte) 0x64, (byte) 0xF4,
+        (byte) 0xC7, (byte) 0x83, (byte) 0x94, (byte) 0xCA, (byte) 0xBD, (byte) 0x50,
+        (byte) 0xD6, (byte) 0xC5, (byte) 0x56, (byte) 0x94, (byte) 0xBD, (byte) 0x0B,
+        (byte) 0x55, (byte) 0xE6, (byte) 0x04, (byte) 0xAD, (byte) 0xAF, (byte) 0xAF,
+        (byte) 0x4F, (byte) 0x2D, (byte) 0x91, (byte) 0x7F, (byte) 0xF1, (byte) 0x60,
+        (byte) 0x0C, (byte) 0xEE, (byte) 0xE8, (byte) 0x44, (byte) 0xFC, (byte) 0x69,
+        (byte) 0x80, (byte) 0x43, (byte) 0xBC, (byte) 0xAB, (byte) 0x83, (byte) 0x35,
+        (byte) 0xB0, (byte) 0xC6, (byte) 0xCB, (byte) 0xE6, (byte) 0x92, (byte) 0x29,
+        (byte) 0x09, (byte) 0xCF, (byte) 0xDB, (byte) 0xAD, (byte) 0x16, (byte) 0x93,
+        (byte) 0xC7, (byte) 0xBE, (byte) 0x81, (byte) 0x68, (byte) 0x0F, (byte) 0x7B,
+        (byte) 0xC1, (byte) 0xC2, (byte) 0x8C, (byte) 0xBA, (byte) 0x59, (byte) 0x80,
+        (byte) 0xAE, (byte) 0xFB, (byte) 0x60, (byte) 0x22, (byte) 0x28, (byte) 0x36,
+        (byte) 0xBE, (byte) 0x37, (byte) 0x72, (byte) 0x86, (byte) 0x02, (byte) 0x4B,
+        (byte) 0xF9, (byte) 0x14, (byte) 0x5A, (byte) 0x6B, (byte) 0x32, (byte) 0x44,
+        (byte) 0x72, (byte) 0x33, (byte) 0x2E, (byte) 0x7F, (byte) 0xA1, (byte) 0xFD,
+        (byte) 0x07, (byte) 0xF2, (byte) 0xD9, (byte) 0x9D, (byte) 0x03, (byte) 0x77,
+        (byte) 0x17, (byte) 0xFB, (byte) 0x0E, (byte) 0xFF, (byte) 0xF7, (byte) 0x37,
+        (byte) 0x68, (byte) 0xF6, (byte) 0x8F, (byte) 0x9B, (byte) 0x2C, (byte) 0xEB,
+        (byte) 0xAF, (byte) 0x6C, (byte) 0x50, (byte) 0x9F, (byte) 0x34, (byte) 0xB2,
+        (byte) 0x52, (byte) 0x3B, (byte) 0x94, (byte) 0x6F, (byte) 0x60, (byte) 0x16,
+        (byte) 0x52, (byte) 0x0A, (byte) 0xBF, (byte) 0x95, (byte) 0x41, (byte) 0x44,
+        (byte) 0x83, (byte) 0x91, (byte) 0x85, (byte) 0xA1, (byte) 0xF7, (byte) 0xF9,
+        (byte) 0x17, (byte) 0x4A, (byte) 0xF7, (byte) 0xF1, (byte) 0xE8, (byte) 0x9C,
+        (byte) 0x75, (byte) 0x86, (byte) 0x12, (byte) 0x44, (byte) 0x19, (byte) 0x5C,
+        (byte) 0x65, (byte) 0x31, (byte) 0x89, (byte) 0x2A, (byte) 0xFC, (byte) 0xBE,
+        (byte) 0xE8, (byte) 0xEC, (byte) 0xC9, (byte) 0xD7, (byte) 0x41, (byte) 0xDA,
+        (byte) 0xD9, (byte) 0xC9, (byte) 0x8B, (byte) 0x90, (byte) 0x60, (byte) 0xCC,
+        (byte) 0xB2, (byte) 0x7A, (byte) 0xBA, (byte) 0xA0, (byte) 0xEE, (byte) 0xBE,
+        (byte) 0x9C, (byte) 0xE7, (byte) 0xF2, (byte) 0x27, (byte) 0x92, (byte) 0x9C,
+        (byte) 0x3C, (byte) 0x0F, (byte) 0x5C, (byte) 0xEE, (byte) 0x38, (byte) 0x48,
+        (byte) 0xCF, (byte) 0xFF, (byte) 0x33, (byte) 0x35, (byte) 0x80, (byte) 0x99,
+        (byte) 0x5D, (byte) 0xA7, (byte) 0x5A, (byte) 0x7A, (byte) 0xEA, (byte) 0x96,
+        (byte) 0x74, (byte) 0x28, (byte) 0x36, (byte) 0x7B, (byte) 0xE1, (byte) 0x33,
+        (byte) 0x7C, (byte) 0x78, (byte) 0xEC, (byte) 0x05, (byte) 0x72, (byte) 0x0E,
+        (byte) 0x5D, (byte) 0x16, (byte) 0x5C, (byte) 0x77, (byte) 0x58, (byte) 0xA7,
+        (byte) 0x31, (byte) 0x3F, (byte) 0xBA, (byte) 0x91, (byte) 0xA7, (byte) 0x16,
+        (byte) 0xFC, (byte) 0x31, (byte) 0xCA, (byte) 0x30, (byte) 0xE0, (byte) 0xF4,
+        (byte) 0x5D, (byte) 0x07, (byte) 0x4A, (byte) 0x9C, (byte) 0x1D, (byte) 0x2B,
+        (byte) 0x4E, (byte) 0xB8, (byte) 0x7C, (byte) 0x67, (byte) 0xCB, (byte) 0x34,
+        (byte) 0x69, (byte) 0x85, (byte) 0x4E, (byte) 0x99, (byte) 0x41, (byte) 0x8A,
+        (byte) 0x35, (byte) 0x85, (byte) 0xF2, (byte) 0x1A,
+    };
+    private static final PSSParameterSpec SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 206, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:64 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA512withRSAPSS_Vector2Signature = new byte[] {
+        (byte) 0x9F, (byte) 0xED, (byte) 0xF8, (byte) 0xEE, (byte) 0x30, (byte) 0x5F,
+        (byte) 0x30, (byte) 0x63, (byte) 0x1D, (byte) 0x86, (byte) 0xD3, (byte) 0xAD,
+        (byte) 0x1D, (byte) 0xD8, (byte) 0xD2, (byte) 0x67, (byte) 0xE2, (byte) 0x43,
+        (byte) 0x64, (byte) 0x71, (byte) 0x98, (byte) 0x82, (byte) 0x00, (byte) 0x84,
+        (byte) 0x2C, (byte) 0x88, (byte) 0x1A, (byte) 0x28, (byte) 0xCD, (byte) 0xA2,
+        (byte) 0x34, (byte) 0x17, (byte) 0x0F, (byte) 0x34, (byte) 0x8A, (byte) 0x10,
+        (byte) 0x79, (byte) 0x6C, (byte) 0xCB, (byte) 0xDA, (byte) 0x2F, (byte) 0xDF,
+        (byte) 0x4D, (byte) 0x98, (byte) 0x01, (byte) 0xE8, (byte) 0xB3, (byte) 0xF5,
+        (byte) 0xCD, (byte) 0x60, (byte) 0xEA, (byte) 0xDE, (byte) 0xA5, (byte) 0x0C,
+        (byte) 0x09, (byte) 0xA1, (byte) 0x4A, (byte) 0xC4, (byte) 0x6B, (byte) 0x09,
+        (byte) 0xB3, (byte) 0x37, (byte) 0x1F, (byte) 0x8A, (byte) 0x64, (byte) 0x81,
+        (byte) 0x2E, (byte) 0x22, (byte) 0x75, (byte) 0x24, (byte) 0x3B, (byte) 0xC0,
+        (byte) 0x0E, (byte) 0x1F, (byte) 0x37, (byte) 0xC9, (byte) 0x1E, (byte) 0x6F,
+        (byte) 0xAF, (byte) 0x3E, (byte) 0x9B, (byte) 0x3F, (byte) 0xA3, (byte) 0xC3,
+        (byte) 0x0B, (byte) 0xB9, (byte) 0x83, (byte) 0x60, (byte) 0x02, (byte) 0xC6,
+        (byte) 0x29, (byte) 0x83, (byte) 0x09, (byte) 0x16, (byte) 0xD9, (byte) 0x3D,
+        (byte) 0x84, (byte) 0x02, (byte) 0x81, (byte) 0x20, (byte) 0xE9, (byte) 0x01,
+        (byte) 0x5B, (byte) 0x85, (byte) 0xC8, (byte) 0x81, (byte) 0x25, (byte) 0x6B,
+        (byte) 0xCB, (byte) 0x78, (byte) 0x48, (byte) 0x65, (byte) 0x3A, (byte) 0xD6,
+        (byte) 0x95, (byte) 0x9B, (byte) 0x62, (byte) 0x2D, (byte) 0x84, (byte) 0x54,
+        (byte) 0x12, (byte) 0x94, (byte) 0xB7, (byte) 0xF0, (byte) 0x1C, (byte) 0xB6,
+        (byte) 0x59, (byte) 0xCD, (byte) 0xC3, (byte) 0x86, (byte) 0xE6, (byte) 0x63,
+        (byte) 0xD7, (byte) 0x99, (byte) 0x9A, (byte) 0xC4, (byte) 0xBF, (byte) 0x8E,
+        (byte) 0xDD, (byte) 0x46, (byte) 0x10, (byte) 0xBE, (byte) 0xAB, (byte) 0x78,
+        (byte) 0xC6, (byte) 0x30, (byte) 0x47, (byte) 0x23, (byte) 0xB6, (byte) 0x2C,
+        (byte) 0x02, (byte) 0x5E, (byte) 0x1F, (byte) 0x07, (byte) 0x96, (byte) 0x54,
+        (byte) 0xEE, (byte) 0x28, (byte) 0xC7, (byte) 0xEC, (byte) 0x57, (byte) 0xDB,
+        (byte) 0x9E, (byte) 0xEF, (byte) 0xE4, (byte) 0x11, (byte) 0xF8, (byte) 0x04,
+        (byte) 0xA9, (byte) 0x26, (byte) 0xC2, (byte) 0x61, (byte) 0xF1, (byte) 0x84,
+        (byte) 0xEB, (byte) 0x94, (byte) 0xBD, (byte) 0x48, (byte) 0xCA, (byte) 0xD1,
+        (byte) 0x84, (byte) 0xCE, (byte) 0x82, (byte) 0x2E, (byte) 0xF6, (byte) 0x4E,
+        (byte) 0x17, (byte) 0x6F, (byte) 0x78, (byte) 0xB9, (byte) 0x0B, (byte) 0xA9,
+        (byte) 0x7D, (byte) 0xBC, (byte) 0xE5, (byte) 0xF8, (byte) 0x7D, (byte) 0xA8,
+        (byte) 0x76, (byte) 0x7A, (byte) 0x8B, (byte) 0xB5, (byte) 0x05, (byte) 0x42,
+        (byte) 0x37, (byte) 0xDA, (byte) 0x15, (byte) 0xE2, (byte) 0xC4, (byte) 0x70,
+        (byte) 0x6E, (byte) 0x95, (byte) 0x60, (byte) 0x47, (byte) 0xF9, (byte) 0x0F,
+        (byte) 0xF4, (byte) 0xA2, (byte) 0x73, (byte) 0xF1, (byte) 0x73, (byte) 0xBD,
+        (byte) 0x0B, (byte) 0x9B, (byte) 0x44, (byte) 0xB6, (byte) 0xA9, (byte) 0xAF,
+        (byte) 0x50, (byte) 0x2D, (byte) 0x5C, (byte) 0xA3, (byte) 0x72, (byte) 0x6F,
+        (byte) 0x85, (byte) 0xE8, (byte) 0x0C, (byte) 0xF9, (byte) 0xE1, (byte) 0xE8,
+        (byte) 0xF7, (byte) 0xC0, (byte) 0x85, (byte) 0x14, (byte) 0x53, (byte) 0x95,
+        (byte) 0xF9, (byte) 0x9E, (byte) 0x65, (byte) 0x05, (byte) 0xF0, (byte) 0x22,
+        (byte) 0x7F, (byte) 0x4F, (byte) 0x40, (byte) 0x45,
+    };
+    private static final PSSParameterSpec SHA512withRSAPSS_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:64 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA512withRSAPSS_NoSalt_Vector2Signature = new byte[] {
+        (byte) 0x49, (byte) 0xA3, (byte) 0xBC, (byte) 0x2E, (byte) 0x67, (byte) 0x96,
+        (byte) 0xA5, (byte) 0x3E, (byte) 0x39, (byte) 0x46, (byte) 0xD6, (byte) 0xA1,
+        (byte) 0xA0, (byte) 0x4F, (byte) 0x3A, (byte) 0x03, (byte) 0x8F, (byte) 0x62,
+        (byte) 0xF2, (byte) 0xD8, (byte) 0x90, (byte) 0xAD, (byte) 0xE2, (byte) 0x3B,
+        (byte) 0x4F, (byte) 0x98, (byte) 0x88, (byte) 0x51, (byte) 0x41, (byte) 0x09,
+        (byte) 0x23, (byte) 0xEB, (byte) 0xF4, (byte) 0x5D, (byte) 0x6A, (byte) 0x22,
+        (byte) 0x12, (byte) 0x12, (byte) 0xDC, (byte) 0x27, (byte) 0xE9, (byte) 0xF7,
+        (byte) 0x64, (byte) 0xA3, (byte) 0xDE, (byte) 0x3A, (byte) 0xB0, (byte) 0xD6,
+        (byte) 0xF2, (byte) 0xC6, (byte) 0xBC, (byte) 0x0B, (byte) 0xA2, (byte) 0xA1,
+        (byte) 0xAA, (byte) 0xB0, (byte) 0x51, (byte) 0xDA, (byte) 0x4F, (byte) 0x28,
+        (byte) 0xA8, (byte) 0xEB, (byte) 0x34, (byte) 0x60, (byte) 0x37, (byte) 0xF7,
+        (byte) 0x50, (byte) 0x7D, (byte) 0xB8, (byte) 0xE7, (byte) 0x24, (byte) 0x8E,
+        (byte) 0xAC, (byte) 0x03, (byte) 0x31, (byte) 0xB8, (byte) 0xE0, (byte) 0xDB,
+        (byte) 0x97, (byte) 0xE9, (byte) 0x1B, (byte) 0x7E, (byte) 0x27, (byte) 0x99,
+        (byte) 0x93, (byte) 0x4D, (byte) 0x46, (byte) 0xB3, (byte) 0xFE, (byte) 0xD6,
+        (byte) 0x23, (byte) 0xB3, (byte) 0xAB, (byte) 0x3E, (byte) 0x33, (byte) 0xA1,
+        (byte) 0x10, (byte) 0x4E, (byte) 0x34, (byte) 0x27, (byte) 0x58, (byte) 0x25,
+        (byte) 0xB7, (byte) 0xBA, (byte) 0xEE, (byte) 0xBE, (byte) 0xE0, (byte) 0x6E,
+        (byte) 0x54, (byte) 0xF7, (byte) 0x73, (byte) 0x7B, (byte) 0x5A, (byte) 0x9C,
+        (byte) 0x74, (byte) 0xEA, (byte) 0xC7, (byte) 0x7E, (byte) 0xC6, (byte) 0xF7,
+        (byte) 0xD5, (byte) 0x32, (byte) 0x0E, (byte) 0x28, (byte) 0x99, (byte) 0xD8,
+        (byte) 0xEF, (byte) 0x97, (byte) 0x62, (byte) 0x8A, (byte) 0xE3, (byte) 0x16,
+        (byte) 0xAD, (byte) 0xE2, (byte) 0xF4, (byte) 0x11, (byte) 0x91, (byte) 0x17,
+        (byte) 0xF3, (byte) 0x32, (byte) 0x90, (byte) 0xCB, (byte) 0x3C, (byte) 0x89,
+        (byte) 0xF4, (byte) 0x20, (byte) 0xF1, (byte) 0x2D, (byte) 0x74, (byte) 0x22,
+        (byte) 0x50, (byte) 0x64, (byte) 0xC2, (byte) 0xF4, (byte) 0xC4, (byte) 0x0D,
+        (byte) 0x18, (byte) 0x6A, (byte) 0x02, (byte) 0x52, (byte) 0x14, (byte) 0x85,
+        (byte) 0x67, (byte) 0xA4, (byte) 0x08, (byte) 0xE5, (byte) 0xBF, (byte) 0x65,
+        (byte) 0x15, (byte) 0xB3, (byte) 0x5A, (byte) 0x88, (byte) 0xEB, (byte) 0xD4,
+        (byte) 0x75, (byte) 0xF9, (byte) 0x52, (byte) 0x73, (byte) 0xA0, (byte) 0x5E,
+        (byte) 0xBA, (byte) 0x37, (byte) 0x6A, (byte) 0x61, (byte) 0x2B, (byte) 0x16,
+        (byte) 0x8A, (byte) 0xA8, (byte) 0x00, (byte) 0xBB, (byte) 0x4D, (byte) 0xFA,
+        (byte) 0x04, (byte) 0xB8, (byte) 0xAB, (byte) 0x4D, (byte) 0xA4, (byte) 0xFC,
+        (byte) 0x9D, (byte) 0xCF, (byte) 0x63, (byte) 0x83, (byte) 0x34, (byte) 0xAE,
+        (byte) 0xAE, (byte) 0xA6, (byte) 0x77, (byte) 0x73, (byte) 0xA2, (byte) 0xB5,
+        (byte) 0x77, (byte) 0xAC, (byte) 0x00, (byte) 0x03, (byte) 0x06, (byte) 0xD4,
+        (byte) 0xDF, (byte) 0x81, (byte) 0x61, (byte) 0xCE, (byte) 0x8E, (byte) 0xC1,
+        (byte) 0xD5, (byte) 0x99, (byte) 0xD5, (byte) 0x2F, (byte) 0xE8, (byte) 0x27,
+        (byte) 0xFA, (byte) 0x84, (byte) 0x7E, (byte) 0x57, (byte) 0xF1, (byte) 0xC9,
+        (byte) 0xEB, (byte) 0x4F, (byte) 0xF9, (byte) 0x92, (byte) 0xC6, (byte) 0xD0,
+        (byte) 0x25, (byte) 0x8A, (byte) 0x16, (byte) 0xD0, (byte) 0xEC, (byte) 0xE5,
+        (byte) 0x33, (byte) 0xA6, (byte) 0xF9, (byte) 0xD5, (byte) 0x0C, (byte) 0x7B,
+        (byte) 0xEC, (byte) 0xC6, (byte) 0x58, (byte) 0x45,
+    };
+    private static final PSSParameterSpec SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 0, 1);
+
+    /*
+     * echo "This is a signed message from Kenny Root." | openssl sha512 -binary -out digest.bin \
+     *     && openssl pkeyutl -sign -in digest.bin -inkey privkey.pem \
+     *         -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:190 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] SHA512withRSAPSS_MaxSalt_Vector2Signature = new byte[] {
+        (byte) 0x90, (byte) 0x92, (byte) 0x45, (byte) 0xA1, (byte) 0x1E, (byte) 0x0F,
+        (byte) 0x5F, (byte) 0xF6, (byte) 0x8F, (byte) 0xA0, (byte) 0xBE, (byte) 0x34,
+        (byte) 0x29, (byte) 0x62, (byte) 0xBE, (byte) 0x41, (byte) 0x80, (byte) 0xF0,
+        (byte) 0xB8, (byte) 0x9F, (byte) 0x29, (byte) 0x63, (byte) 0x89, (byte) 0x26,
+        (byte) 0xC2, (byte) 0x22, (byte) 0x1F, (byte) 0x60, (byte) 0xB6, (byte) 0xFC,
+        (byte) 0x5A, (byte) 0x3E, (byte) 0x99, (byte) 0xB8, (byte) 0xC6, (byte) 0x3B,
+        (byte) 0x67, (byte) 0x33, (byte) 0x97, (byte) 0x19, (byte) 0xC6, (byte) 0xFF,
+        (byte) 0x0C, (byte) 0xA9, (byte) 0x04, (byte) 0x5A, (byte) 0xF0, (byte) 0x02,
+        (byte) 0x9A, (byte) 0x19, (byte) 0x0F, (byte) 0xEA, (byte) 0x77, (byte) 0x0D,
+        (byte) 0x56, (byte) 0x38, (byte) 0x0A, (byte) 0xED, (byte) 0x4E, (byte) 0xB7,
+        (byte) 0x57, (byte) 0xBD, (byte) 0xC9, (byte) 0xA3, (byte) 0xE8, (byte) 0xC0,
+        (byte) 0x7D, (byte) 0xF6, (byte) 0xA3, (byte) 0x4B, (byte) 0x61, (byte) 0x45,
+        (byte) 0x06, (byte) 0x5E, (byte) 0x56, (byte) 0xF5, (byte) 0xEF, (byte) 0x76,
+        (byte) 0x6B, (byte) 0xB7, (byte) 0xD4, (byte) 0xBB, (byte) 0xA4, (byte) 0x3C,
+        (byte) 0x52, (byte) 0xF8, (byte) 0x06, (byte) 0x67, (byte) 0xF7, (byte) 0xC3,
+        (byte) 0x8C, (byte) 0x5E, (byte) 0xDF, (byte) 0xFE, (byte) 0x30, (byte) 0x2E,
+        (byte) 0xF8, (byte) 0x59, (byte) 0x3C, (byte) 0x3B, (byte) 0xEA, (byte) 0xA0,
+        (byte) 0x5D, (byte) 0x8F, (byte) 0x18, (byte) 0x73, (byte) 0x1A, (byte) 0x2D,
+        (byte) 0xB1, (byte) 0x55, (byte) 0x07, (byte) 0xC8, (byte) 0x33, (byte) 0xED,
+        (byte) 0x8A, (byte) 0x5E, (byte) 0xC3, (byte) 0xAE, (byte) 0x51, (byte) 0x31,
+        (byte) 0xC4, (byte) 0xFA, (byte) 0xE8, (byte) 0xE9, (byte) 0xBE, (byte) 0x2E,
+        (byte) 0x28, (byte) 0xAA, (byte) 0xED, (byte) 0xA8, (byte) 0x4B, (byte) 0xA3,
+        (byte) 0x13, (byte) 0xB9, (byte) 0x82, (byte) 0x57, (byte) 0xD1, (byte) 0x72,
+        (byte) 0x0D, (byte) 0xA7, (byte) 0xF8, (byte) 0x67, (byte) 0xB8, (byte) 0x55,
+        (byte) 0xF3, (byte) 0x06, (byte) 0xAE, (byte) 0xA7, (byte) 0x69, (byte) 0x66,
+        (byte) 0x0B, (byte) 0x80, (byte) 0x56, (byte) 0x65, (byte) 0xC7, (byte) 0xE9,
+        (byte) 0x60, (byte) 0xDC, (byte) 0x2D, (byte) 0x4B, (byte) 0x26, (byte) 0xA9,
+        (byte) 0xED, (byte) 0x54, (byte) 0x79, (byte) 0x9E, (byte) 0x55, (byte) 0x1D,
+        (byte) 0xEE, (byte) 0x78, (byte) 0x49, (byte) 0xA1, (byte) 0x1F, (byte) 0x9B,
+        (byte) 0x37, (byte) 0xC0, (byte) 0xBA, (byte) 0xE6, (byte) 0x4B, (byte) 0x3B,
+        (byte) 0xAF, (byte) 0x12, (byte) 0x99, (byte) 0x32, (byte) 0x14, (byte) 0x8C,
+        (byte) 0x4D, (byte) 0xEB, (byte) 0x08, (byte) 0xA4, (byte) 0xE3, (byte) 0xC6,
+        (byte) 0x37, (byte) 0x8B, (byte) 0x6E, (byte) 0x7C, (byte) 0xEC, (byte) 0xA3,
+        (byte) 0x78, (byte) 0xED, (byte) 0x4E, (byte) 0x36, (byte) 0xBC, (byte) 0xA2,
+        (byte) 0x7D, (byte) 0x11, (byte) 0x0E, (byte) 0xD0, (byte) 0x53, (byte) 0x14,
+        (byte) 0x93, (byte) 0x16, (byte) 0x54, (byte) 0x45, (byte) 0x79, (byte) 0x7A,
+        (byte) 0x1A, (byte) 0xA1, (byte) 0xEC, (byte) 0xF3, (byte) 0x12, (byte) 0x3F,
+        (byte) 0xFE, (byte) 0x68, (byte) 0xFF, (byte) 0x5A, (byte) 0x3F, (byte) 0xE7,
+        (byte) 0x13, (byte) 0x37, (byte) 0xEB, (byte) 0x60, (byte) 0x0A, (byte) 0x8E,
+        (byte) 0x4F, (byte) 0x54, (byte) 0x46, (byte) 0x19, (byte) 0x82, (byte) 0xBF,
+        (byte) 0xB7, (byte) 0xD2, (byte) 0x19, (byte) 0x71, (byte) 0x78, (byte) 0x38,
+        (byte) 0x4C, (byte) 0xE3, (byte) 0xC4, (byte) 0xEA, (byte) 0x8F, (byte) 0x9B,
+        (byte) 0xE5, (byte) 0xBA, (byte) 0x06, (byte) 0xFC,
+    };
+    private static final PSSParameterSpec SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec =
+            new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 190, 1);
+
+    @Test
+    public void testGetCommonInstances_Success() throws Exception {
+        assertNotNull(Signature.getInstance("SHA1withRSA"));
+        assertNotNull(Signature.getInstance("SHA256withRSA"));
+        assertNotNull(Signature.getInstance("SHA384withRSA"));
+        assertNotNull(Signature.getInstance("SHA512withRSA"));
+        assertNotNull(Signature.getInstance("NONEwithRSA"));
+        assertNotNull(Signature.getInstance("MD5withRSA"));
+        assertNotNull(Signature.getInstance("SHA1withDSA"));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+
+        assertTrue("Signature must match expected signature",
+                sig.verify(SHA1withRSA_Vector1Signature));
+    }
+
+    @Test
+    public void testVerify_SHA256withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must match expected signature",
+                sig.verify(SHA256withRSA_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA384withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must match expected signature",
+                sig.verify(SHA384withRSA_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA512withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must match expected signature",
+                sig.verify(SHA512withRSA_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_MD5withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("MD5withRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must match expected signature",
+                sig.verify(MD5withRSA_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initVerify(pubKey);
+        assertPSSAlgorithmParametersEquals(
+                SHA1withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA1withRSAPSS_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA1withRSAPSS_NoSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA1withRSAPSS_MaxSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA224withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initVerify(pubKey);
+        assertPSSAlgorithmParametersEquals(
+                SHA224withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA224withRSAPSS_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA224withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA224withRSAPSS_NoSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA224withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA224withRSAPSS_MaxSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA256withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initVerify(pubKey);
+        assertPSSAlgorithmParametersEquals(
+                SHA256withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA256withRSAPSS_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA256withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA256withRSAPSS_NoSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA256withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA256withRSAPSS_MaxSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA384withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initVerify(pubKey);
+        assertPSSAlgorithmParametersEquals(
+                SHA384withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA384withRSAPSS_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA384withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA384withRSAPSS_NoSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA384withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA384withRSAPSS_MaxSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA512withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initVerify(pubKey);
+        assertPSSAlgorithmParametersEquals(
+                SHA512withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA512withRSAPSS_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA512withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA512withRSAPSS_NoSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA512withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        assertTrue("Signature must verify",
+                sig.verify(SHA512withRSAPSS_MaxSalt_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSA_Key_InitSignThenInitVerify_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(privKeySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+
+        // Start a signing operation
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        // Switch to verify
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+
+        assertTrue("Signature must match expected signature",
+                sig.verify(SHA1withRSA_Vector1Signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSA_Key_TwoMessages_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+        sig.initVerify(pubKey);
+
+        sig.update(Vector1Data);
+        assertTrue("First signature must match expected signature",
+                sig.verify(SHA1withRSA_Vector1Signature));
+
+        sig.update(Vector2Data);
+        assertTrue("Second signature must match expected signature",
+                sig.verify(SHA1withRSA_Vector2Signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withRSA_Key_WrongExpectedSignature_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+
+        assertFalse("Signature should fail to verify", sig.verify(SHA1withRSA_Vector2Signature));
+    }
+
+    @Test
+    public void testSign_SHA1withRSA_CrtKeyWithPublicExponent_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent, RSA_2048_privateExponent, null, null, null, null, null);
+
+        // The RI fails on this key which is totally unreasonable.
+        final PrivateKey privKey;
+        try {
+            privKey = kf.generatePrivate(keySpec);
+        } catch (NullPointerException e) {
+            if (StandardNames.IS_RI) {
+                return;
+            } else {
+                fail("Private key should be created");
+                return;
+            }
+        }
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector1Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA1withRSA_Vector1Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA1withRSA_CrtKey_NoPrivateExponent_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent, null, RSA_2048_primeP, RSA_2048_primeQ, null, null, null);
+
+        // Failing on this key early is okay.
+        final PrivateKey privKey;
+        try {
+            privKey = kf.generatePrivate(keySpec);
+        } catch (NullPointerException e) {
+            return;
+        } catch (InvalidKeySpecException e) {
+            return;
+        }
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+
+        try {
+            sig.initSign(privKey);
+            fail("Should throw error when private exponent is not available");
+        } catch (InvalidKeyException expected) {
+        }
+    }
+
+    @Test
+    public void testSign_SHA1withRSA_CrtKey_NoModulus_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(null, RSA_2048_publicExponent,
+                RSA_2048_privateExponent, RSA_2048_primeP, RSA_2048_primeQ, null, null, null);
+
+        // Failing on this key early is okay.
+        final PrivateKey privKey;
+        try {
+            privKey = kf.generatePrivate(keySpec);
+        } catch (NullPointerException e) {
+            return;
+        } catch (InvalidKeySpecException e) {
+            return;
+        }
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+
+        try {
+            sig.initSign(privKey);
+            fail("Should throw error when modulus is not available");
+        } catch (InvalidKeyException expected) {
+        }
+    }
+
+    @Test
+    public void testSign_SHA1withRSA_Key_EmptyKey_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(null, null);
+
+        // Failing on this key early is okay.
+        final PrivateKey privKey;
+        try {
+            privKey = kf.generatePrivate(keySpec);
+        } catch (NullPointerException e) {
+            return;
+        } catch (InvalidKeySpecException e) {
+            return;
+        }
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+
+        try {
+            sig.initSign(privKey);
+            fail("Should throw error when key is empty");
+        } catch (InvalidKeyException expected) {
+        }
+    }
+
+    @Test
+    public void testSign_SHA1withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector1Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA1withRSA_Vector1Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA224withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+
+        final PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA224withRSA_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA256withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+
+        final PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA256withRSA_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA384withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA384withRSA_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA512withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA512withRSA_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_MD5withRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("MD5withRSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, MD5withRSA_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA1withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA1withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA1withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA1withRSAPSS_NoSalt_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA1withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA1withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig = Signature.getInstance("SHA1withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA1withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA224withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA224withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA224withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA224withRSAPSS_NoSalt_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA224withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA224withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig = Signature.getInstance("SHA224withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA224withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA256withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA256withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA256withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA256withRSAPSS_NoSalt_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA256withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA256withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig = Signature.getInstance("SHA256withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA256withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA384withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA384withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA384withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA384withRSAPSS_NoSalt_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA384withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA384withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig = Signature.getInstance("SHA384withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA384withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA512withRSAPSS_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA512withRSAPSS_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA512withRSAPSS_NoSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, SHA512withRSAPSS_NoSalt_Vector2Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA512withRSAPSS_NoSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_SHA512withRSAPSS_MaxSalt_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initSign(privKey);
+        sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertPSSAlgorithmParametersEquals(
+                SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec, sig.getParameters());
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig = Signature.getInstance("SHA512withRSA/PSS");
+        sig.initVerify(pubKey);
+        sig.setParameter(SHA512withRSAPSS_MaxSalt_Vector2Signature_ParameterSpec);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testSign_NONEwithRSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initSign(privKey);
+        sig.update(Vector1Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature should match expected",
+                Arrays.equals(signature, NONEwithRSA_Vector1Signature));
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testVerify_NONEwithRSA_Key_WrongSignature_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+        assertFalse("Invalid signature must not verify",
+                sig.verify("Invalid".getBytes("UTF-8")));
+    }
+
+    @Test
+    public void testSign_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initSign(privKey);
+
+        final int oneTooBig = RSA_2048_modulus.bitLength() - 10;
+        for (int i = 0; i < oneTooBig; i++) {
+            sig.update((byte) i);
+        }
+
+        try {
+            sig.sign();
+            fail("Should throw exception when data is too large");
+        } catch (SignatureException expected) {
+        }
+    }
+
+    @Test
+    public void testSign_NONEwithRSA_Key_DataTooLarge_SingleByte_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
+                RSA_2048_privateExponent);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initSign(privKey);
+
+        // This should make it two bytes too big.
+        final int oneTooBig = RSA_2048_modulus.bitLength() - 10;
+        for (int i = 0; i < oneTooBig; i++) {
+            sig.update((byte) i);
+        }
+
+        try {
+            sig.sign();
+            fail("Should throw exception when data is too large");
+        } catch (SignatureException expected) {
+        }
+    }
+
+    @Test
+    public void testVerify_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initVerify(pubKey);
+
+        // This should make it one bytes too big.
+        final int oneTooBig = RSA_2048_modulus.bitLength() + 1;
+        final byte[] vector = new byte[oneTooBig];
+        for (int i = 0; i < oneTooBig; i++) {
+            vector[i] = Vector1Data[i % Vector1Data.length];
+        }
+        sig.update(vector);
+
+        assertFalse("Should not verify when signature is too large",
+                sig.verify(NONEwithRSA_Vector1Signature));
+    }
+
+    @Test
+    public void testVerify_NONEwithRSA_Key_DataTooLarge_SingleByte_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initVerify(pubKey);
+
+        // This should make it twice as big as it should be.
+        final int tooBig = RSA_2048_modulus.bitLength() * 2;
+        for (int i = 0; i < tooBig; i++) {
+            sig.update(Vector1Data[i % Vector1Data.length]);
+        }
+
+        assertFalse("Should not verify when signature is too large",
+                sig.verify(NONEwithRSA_Vector1Signature));
+    }
+
+    @Test
+    public void testVerify_NONEwithRSA_Key_SignatureTooSmall_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+
+        assertFalse("Invalid signature should not verify",
+                sig.verify("Invalid sig".getBytes("UTF-8")));
+    }
+
+    @Test
+    public void testVerify_NONEwithRSA_Key_SignatureTooLarge_Failure() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+
+        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                RSA_2048_publicExponent);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("NONEwithRSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector1Data);
+
+        byte[] invalidSignature = new byte[NONEwithRSA_Vector1Signature.length * 2];
+        System.arraycopy(NONEwithRSA_Vector1Signature, 0, invalidSignature, 0,
+                NONEwithRSA_Vector1Signature.length);
+        System.arraycopy(NONEwithRSA_Vector1Signature, 0, invalidSignature,
+                NONEwithRSA_Vector1Signature.length, NONEwithRSA_Vector1Signature.length);
+
+        try {
+            sig.verify(invalidSignature);
+            fail("Should throw exception when signature is too large");
+        } catch (SignatureException expected) {
+        }
+    }
+
+    @Test
+    public void testSign_NONEwithECDSA_Key_Success() throws Exception {
+        KeyPair keys = keyPair("NONEwithECDSA");
+        Signature sig = Signature.getInstance("NONEwithECDSA");
+
+        sig.initSign(keys.getPrivate());
+        sig.update(Vector1Data);
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+        assertTrue("Signature must not be empty", signature.length > 0);
+
+        sig.initVerify(keys.getPublic());
+        sig.update(Vector1Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testVerify_NONEwithECDSA_Key_Success() throws Exception {
+        PublicKey pub = getNamedCurveEcPublicKey();
+        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
+        Signature sig = Signature.getInstance("NONEwithECDSA");
+
+        // NAMED_CURVE_SIGNATURE was signed using SHA1withECDSA, so NONEwithECDSA should
+        // verify the digest
+        sig.initVerify(pub);
+        sig.update(sha1.digest(NAMED_CURVE_VECTOR));
+        assertTrue(sig.verify(NAMED_CURVE_SIGNATURE));
+    }
+
+    @Test
+    public void testVerify_NONEwithECDSA_Key_WrongData_Failure() throws Exception {
+        PublicKey pub = getNamedCurveEcPublicKey();
+        Signature sig = Signature.getInstance("NONEwithECDSA");
+
+        sig.initVerify(pub);
+        sig.update(NAMED_CURVE_VECTOR);
+        assertFalse(sig.verify(NAMED_CURVE_SIGNATURE));
+    }
+
+    // Suppress ErrorProne's warning about the try block that doesn't call fail() but
+    // expects an exception, it's intentional
+    @SuppressWarnings("MissingFail")
+    @Test
+    public void testVerify_NONEwithECDSA_Key_SingleByte_Failure() throws Exception {
+        PublicKey pub = getNamedCurveEcPublicKey();
+        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
+        Signature sig = Signature.getInstance("NONEwithECDSA");
+
+        byte[] corrupted = new byte[NAMED_CURVE_SIGNATURE.length];
+        corrupted[0] = (byte) (corrupted[0] ^ 1);
+
+        sig.initVerify(pub);
+        sig.update(sha1.digest(NAMED_CURVE_VECTOR));
+        try {
+            assertFalse(sig.verify(corrupted));
+        } catch (SignatureException expected) {
+            // It's valid to either return false or throw an exception, accept either
+        }
+    }
+
+    // Tests that an opaque key will be accepted by the ECDSA signature and will delegate to a
+    // functioning alternative provider
+    @Test
+    public void test_NONEwithECDSA_OpaqueKey() throws Exception {
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
+        keyGen.initialize(256);
+        KeyPair kp = keyGen.generateKeyPair();
+
+        // Insert this at #2 so that Conscrypt is still the first provider and CryptoUpcalls
+        // has to drop to manual provider selection rather than relying on Signature's internals
+        Security.insertProviderAt(new OpaqueProvider(), 2);
+        try {
+            Signature sig =
+                    Signature.getInstance("NONEwithECDSA", TestUtils.getConscryptProvider());
+            sig.initSign(OpaqueProvider.wrapKeyMarked(kp.getPrivate()));
+            sig.update(new byte[] {1, 2, 3, 4, 5, 6, 7, 8});
+            byte[] data = sig.sign();
+
+            sig.initVerify(kp.getPublic());
+            sig.update(new byte[] {1, 2, 3, 4, 5, 6, 7, 8});
+            assertTrue(sig.verify(data));
+        } finally {
+            Security.removeProvider(OpaqueProvider.NAME);
+        }
+    }
+
+    // Tests that an opaque key will be accepted by the ECDSA signature and that a broken
+    // alternative provider that throws UnsupportedOperationException will be skipped and
+    // a functioning provider that follows will work.
+    @Test
+    public void test_NONEwithECDSA_OpaqueKey_BrokenProvider() throws Exception {
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
+        keyGen.initialize(256);
+        KeyPair kp = keyGen.generateKeyPair();
+
+        // Insert these at #2 so that Conscrypt is still the first provider and CryptoUpcalls
+        // has to drop to manual provider selection rather than relying on Signature's internals
+        Security.insertProviderAt(new OpaqueProvider(), 2);
+        Security.insertProviderAt(new BrokenProvider(), 2);
+        try {
+            Signature sig =
+                    Signature.getInstance("NONEwithECDSA", TestUtils.getConscryptProvider());
+            sig.initSign(OpaqueProvider.wrapKeyMarked(kp.getPrivate()));
+            sig.update(new byte[] {1, 2, 3, 4, 5, 6, 7, 8});
+            byte[] data = sig.sign();
+
+            sig.initVerify(kp.getPublic());
+            sig.update(new byte[] {1, 2, 3, 4, 5, 6, 7, 8});
+            assertTrue(sig.verify(data));
+        } finally {
+            Security.removeProvider(OpaqueProvider.NAME);
+            Security.removeProvider(BrokenProvider.NAME);
+        }
+    }
+
+    /*
+     * These tests were generated with this DSA private key:
+     *
+     * -----BEGIN DSA PRIVATE KEY-----
+     * MIIBugIBAAKBgQCeYcKJ73epThNnZB8JAf4kE1Pgt5CoTnb+iYJ/esU8TgwgVTCV
+     * QoXhQH0njwcN6NyZ77MHlDTWfP+cvmnT60Q3UO9J+OJb2NEQhJfq46UcwE5pynA9
+     * eLkW5f5hXYpasyxhtgE70AF8Mo3h82kOi1jGzwCU+EkqS+raAP9L0L5AIwIVAL/u
+     * qg8SNFBy+GAT2PFBARClL1dfAoGAd9R6EsyBfn7rOvvmhm1aEB2tqU+5A10hGuQw
+     * lXWOzV7RvQpF7uf3a2UCYNAurz28B90rjjPAk4DZK6dxV3a8jrng1/QjjUEal08s
+     * G9VLZuj60lANF6s0MT2kiNiOqKduFwO3D2h8ZHuSuGPkmmcYgSfUCxNI031O9qiP
+     * VhctCFECgYAz7i1DhjRGUkCdYQd5tVaI42lhXOV71MTYPbuFOIxTL/hny7Z0PZWR
+     * A1blmYE6vrArDEhzpmRvDJZSIMzMfJjUIGu1KO73zpo9siK0xY0/sw5r3QC9txP2
+     * 2Mv3BUIl5TLrs9outQJ0VMwldY2fElgCLWcSVkH44qZwWir1cq+cIwIUEGPDardb
+     * pNvWlWgTDD6a6ZTby+M=
+     * -----END DSA PRIVATE KEY-----
+     *
+     */
+
+    private static final BigInteger DSA_priv = new BigInteger(new byte[] {
+        (byte) 0x10, (byte) 0x63, (byte) 0xc3, (byte) 0x6a, (byte) 0xb7, (byte) 0x5b, (byte) 0xa4, (byte) 0xdb,
+        (byte) 0xd6, (byte) 0x95, (byte) 0x68, (byte) 0x13, (byte) 0x0c, (byte) 0x3e, (byte) 0x9a, (byte) 0xe9,
+        (byte) 0x94, (byte) 0xdb, (byte) 0xcb, (byte) 0xe3,
+    });
+
+    private static final BigInteger DSA_pub = new BigInteger(new byte[] {
+        (byte) 0x33, (byte) 0xee, (byte) 0x2d, (byte) 0x43, (byte) 0x86, (byte) 0x34, (byte) 0x46, (byte) 0x52,
+        (byte) 0x40, (byte) 0x9d, (byte) 0x61, (byte) 0x07, (byte) 0x79, (byte) 0xb5, (byte) 0x56, (byte) 0x88,
+        (byte) 0xe3, (byte) 0x69, (byte) 0x61, (byte) 0x5c, (byte) 0xe5, (byte) 0x7b, (byte) 0xd4, (byte) 0xc4,
+        (byte) 0xd8, (byte) 0x3d, (byte) 0xbb, (byte) 0x85, (byte) 0x38, (byte) 0x8c, (byte) 0x53, (byte) 0x2f,
+        (byte) 0xf8, (byte) 0x67, (byte) 0xcb, (byte) 0xb6, (byte) 0x74, (byte) 0x3d, (byte) 0x95, (byte) 0x91,
+        (byte) 0x03, (byte) 0x56, (byte) 0xe5, (byte) 0x99, (byte) 0x81, (byte) 0x3a, (byte) 0xbe, (byte) 0xb0,
+        (byte) 0x2b, (byte) 0x0c, (byte) 0x48, (byte) 0x73, (byte) 0xa6, (byte) 0x64, (byte) 0x6f, (byte) 0x0c,
+        (byte) 0x96, (byte) 0x52, (byte) 0x20, (byte) 0xcc, (byte) 0xcc, (byte) 0x7c, (byte) 0x98, (byte) 0xd4,
+        (byte) 0x20, (byte) 0x6b, (byte) 0xb5, (byte) 0x28, (byte) 0xee, (byte) 0xf7, (byte) 0xce, (byte) 0x9a,
+        (byte) 0x3d, (byte) 0xb2, (byte) 0x22, (byte) 0xb4, (byte) 0xc5, (byte) 0x8d, (byte) 0x3f, (byte) 0xb3,
+        (byte) 0x0e, (byte) 0x6b, (byte) 0xdd, (byte) 0x00, (byte) 0xbd, (byte) 0xb7, (byte) 0x13, (byte) 0xf6,
+        (byte) 0xd8, (byte) 0xcb, (byte) 0xf7, (byte) 0x05, (byte) 0x42, (byte) 0x25, (byte) 0xe5, (byte) 0x32,
+        (byte) 0xeb, (byte) 0xb3, (byte) 0xda, (byte) 0x2e, (byte) 0xb5, (byte) 0x02, (byte) 0x74, (byte) 0x54,
+        (byte) 0xcc, (byte) 0x25, (byte) 0x75, (byte) 0x8d, (byte) 0x9f, (byte) 0x12, (byte) 0x58, (byte) 0x02,
+        (byte) 0x2d, (byte) 0x67, (byte) 0x12, (byte) 0x56, (byte) 0x41, (byte) 0xf8, (byte) 0xe2, (byte) 0xa6,
+        (byte) 0x70, (byte) 0x5a, (byte) 0x2a, (byte) 0xf5, (byte) 0x72, (byte) 0xaf, (byte) 0x9c, (byte) 0x23,
+    });
+
+    private static final BigInteger DSA_P = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0x9e, (byte) 0x61, (byte) 0xc2, (byte) 0x89, (byte) 0xef, (byte) 0x77, (byte) 0xa9,
+        (byte) 0x4e, (byte) 0x13, (byte) 0x67, (byte) 0x64, (byte) 0x1f, (byte) 0x09, (byte) 0x01, (byte) 0xfe,
+        (byte) 0x24, (byte) 0x13, (byte) 0x53, (byte) 0xe0, (byte) 0xb7, (byte) 0x90, (byte) 0xa8, (byte) 0x4e,
+        (byte) 0x76, (byte) 0xfe, (byte) 0x89, (byte) 0x82, (byte) 0x7f, (byte) 0x7a, (byte) 0xc5, (byte) 0x3c,
+        (byte) 0x4e, (byte) 0x0c, (byte) 0x20, (byte) 0x55, (byte) 0x30, (byte) 0x95, (byte) 0x42, (byte) 0x85,
+        (byte) 0xe1, (byte) 0x40, (byte) 0x7d, (byte) 0x27, (byte) 0x8f, (byte) 0x07, (byte) 0x0d, (byte) 0xe8,
+        (byte) 0xdc, (byte) 0x99, (byte) 0xef, (byte) 0xb3, (byte) 0x07, (byte) 0x94, (byte) 0x34, (byte) 0xd6,
+        (byte) 0x7c, (byte) 0xff, (byte) 0x9c, (byte) 0xbe, (byte) 0x69, (byte) 0xd3, (byte) 0xeb, (byte) 0x44,
+        (byte) 0x37, (byte) 0x50, (byte) 0xef, (byte) 0x49, (byte) 0xf8, (byte) 0xe2, (byte) 0x5b, (byte) 0xd8,
+        (byte) 0xd1, (byte) 0x10, (byte) 0x84, (byte) 0x97, (byte) 0xea, (byte) 0xe3, (byte) 0xa5, (byte) 0x1c,
+        (byte) 0xc0, (byte) 0x4e, (byte) 0x69, (byte) 0xca, (byte) 0x70, (byte) 0x3d, (byte) 0x78, (byte) 0xb9,
+        (byte) 0x16, (byte) 0xe5, (byte) 0xfe, (byte) 0x61, (byte) 0x5d, (byte) 0x8a, (byte) 0x5a, (byte) 0xb3,
+        (byte) 0x2c, (byte) 0x61, (byte) 0xb6, (byte) 0x01, (byte) 0x3b, (byte) 0xd0, (byte) 0x01, (byte) 0x7c,
+        (byte) 0x32, (byte) 0x8d, (byte) 0xe1, (byte) 0xf3, (byte) 0x69, (byte) 0x0e, (byte) 0x8b, (byte) 0x58,
+        (byte) 0xc6, (byte) 0xcf, (byte) 0x00, (byte) 0x94, (byte) 0xf8, (byte) 0x49, (byte) 0x2a, (byte) 0x4b,
+        (byte) 0xea, (byte) 0xda, (byte) 0x00, (byte) 0xff, (byte) 0x4b, (byte) 0xd0, (byte) 0xbe, (byte) 0x40,
+        (byte) 0x23,
+    });
+
+    private static final BigInteger DSA_Q = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xbf, (byte) 0xee, (byte) 0xaa, (byte) 0x0f, (byte) 0x12, (byte) 0x34, (byte) 0x50,
+        (byte) 0x72, (byte) 0xf8, (byte) 0x60, (byte) 0x13, (byte) 0xd8, (byte) 0xf1, (byte) 0x41, (byte) 0x01,
+        (byte) 0x10, (byte) 0xa5, (byte) 0x2f, (byte) 0x57, (byte) 0x5f,
+    });
+
+    private static final BigInteger DSA_G = new BigInteger(new byte[] {
+        (byte) 0x77, (byte) 0xd4, (byte) 0x7a, (byte) 0x12, (byte) 0xcc, (byte) 0x81, (byte) 0x7e, (byte) 0x7e,
+        (byte) 0xeb, (byte) 0x3a, (byte) 0xfb, (byte) 0xe6, (byte) 0x86, (byte) 0x6d, (byte) 0x5a, (byte) 0x10,
+        (byte) 0x1d, (byte) 0xad, (byte) 0xa9, (byte) 0x4f, (byte) 0xb9, (byte) 0x03, (byte) 0x5d, (byte) 0x21,
+        (byte) 0x1a, (byte) 0xe4, (byte) 0x30, (byte) 0x95, (byte) 0x75, (byte) 0x8e, (byte) 0xcd, (byte) 0x5e,
+        (byte) 0xd1, (byte) 0xbd, (byte) 0x0a, (byte) 0x45, (byte) 0xee, (byte) 0xe7, (byte) 0xf7, (byte) 0x6b,
+        (byte) 0x65, (byte) 0x02, (byte) 0x60, (byte) 0xd0, (byte) 0x2e, (byte) 0xaf, (byte) 0x3d, (byte) 0xbc,
+        (byte) 0x07, (byte) 0xdd, (byte) 0x2b, (byte) 0x8e, (byte) 0x33, (byte) 0xc0, (byte) 0x93, (byte) 0x80,
+        (byte) 0xd9, (byte) 0x2b, (byte) 0xa7, (byte) 0x71, (byte) 0x57, (byte) 0x76, (byte) 0xbc, (byte) 0x8e,
+        (byte) 0xb9, (byte) 0xe0, (byte) 0xd7, (byte) 0xf4, (byte) 0x23, (byte) 0x8d, (byte) 0x41, (byte) 0x1a,
+        (byte) 0x97, (byte) 0x4f, (byte) 0x2c, (byte) 0x1b, (byte) 0xd5, (byte) 0x4b, (byte) 0x66, (byte) 0xe8,
+        (byte) 0xfa, (byte) 0xd2, (byte) 0x50, (byte) 0x0d, (byte) 0x17, (byte) 0xab, (byte) 0x34, (byte) 0x31,
+        (byte) 0x3d, (byte) 0xa4, (byte) 0x88, (byte) 0xd8, (byte) 0x8e, (byte) 0xa8, (byte) 0xa7, (byte) 0x6e,
+        (byte) 0x17, (byte) 0x03, (byte) 0xb7, (byte) 0x0f, (byte) 0x68, (byte) 0x7c, (byte) 0x64, (byte) 0x7b,
+        (byte) 0x92, (byte) 0xb8, (byte) 0x63, (byte) 0xe4, (byte) 0x9a, (byte) 0x67, (byte) 0x18, (byte) 0x81,
+        (byte) 0x27, (byte) 0xd4, (byte) 0x0b, (byte) 0x13, (byte) 0x48, (byte) 0xd3, (byte) 0x7d, (byte) 0x4e,
+        (byte) 0xf6, (byte) 0xa8, (byte) 0x8f, (byte) 0x56, (byte) 0x17, (byte) 0x2d, (byte) 0x08, (byte) 0x51,
+    });
+
+    /**
+     * A possible signature using SHA1withDSA of Vector2Data. Note that DSS is
+     * randomized, so this won't be the exact signature you'll get out of
+     * another signing operation unless you use a fixed RNG.
+     */
+    public static final byte[] SHA1withDSA_Vector2Signature = new byte[] {
+        (byte) 0x30, (byte) 0x2d, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x88, (byte) 0xef, (byte) 0xac,
+        (byte) 0x2b, (byte) 0x8b, (byte) 0xe2, (byte) 0x61, (byte) 0xc6, (byte) 0x2b, (byte) 0xea, (byte) 0xd5,
+        (byte) 0x96, (byte) 0xbc, (byte) 0xb0, (byte) 0xa1, (byte) 0x30, (byte) 0x0c, (byte) 0x1f, (byte) 0xed,
+        (byte) 0x11, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0xc4, (byte) 0xfc, (byte) 0x82, (byte) 0x6f,
+        (byte) 0x17, (byte) 0xdc, (byte) 0x87, (byte) 0x82, (byte) 0x75, (byte) 0x23, (byte) 0xd4, (byte) 0x58,
+        (byte) 0xdc, (byte) 0x73, (byte) 0x3d, (byte) 0xf3, (byte) 0x51, (byte) 0xc0, (byte) 0x57,
+    };
+
+    /**
+     * A possible signature using SHA224withDSA of Vector2Data. Note that DSS is
+     * randomized, so this won't be the exact signature you'll get out of
+     * another signing operation unless you use a fixed RNG.
+     */
+    public static final byte[] SHA224withDSA_Vector2Signature = new byte[] {
+        (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xAD, (byte) 0xE5, (byte) 0x6D,
+        (byte) 0xF5, (byte) 0x11, (byte) 0x8D, (byte) 0x2E, (byte) 0x62, (byte) 0x5D, (byte) 0x98, (byte) 0x8A,
+        (byte) 0xC4, (byte) 0x88, (byte) 0x7E, (byte) 0xE6, (byte) 0xA3, (byte) 0x44, (byte) 0x99, (byte) 0xEF,
+        (byte) 0x49, (byte) 0x02, (byte) 0x14, (byte) 0x15, (byte) 0x3E, (byte) 0x32, (byte) 0xD6, (byte) 0xF9,
+        (byte) 0x79, (byte) 0x2C, (byte) 0x60, (byte) 0x6E, (byte) 0xF9, (byte) 0xA9, (byte) 0x78, (byte) 0xE7,
+        (byte) 0x4B, (byte) 0x87, (byte) 0x08, (byte) 0x96, (byte) 0x60, (byte) 0xDE, (byte) 0xB5
+    };
+
+    /**
+     * A possible signature using SHA256withDSA of Vector2Data. Note that DSS is
+     * randomized, so this won't be the exact signature you'll get out of
+     * another signing operation unless you use a fixed RNG.
+     */
+    public static final byte[] SHA256withDSA_Vector2Signature = new byte[] {
+        (byte) 0x30, (byte) 0x2D, (byte) 0x02, (byte) 0x14, (byte) 0x0A, (byte) 0xB1, (byte) 0x74, (byte) 0x45,
+        (byte) 0xE1, (byte) 0x63, (byte) 0x43, (byte) 0x68, (byte) 0x65, (byte) 0xBC, (byte) 0xCA, (byte) 0x45,
+        (byte) 0x27, (byte) 0x11, (byte) 0x4D, (byte) 0x52, (byte) 0xFB, (byte) 0x22, (byte) 0x93, (byte) 0xDD,
+        (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x98, (byte) 0x32, (byte) 0x1A, (byte) 0x16, (byte) 0x77,
+        (byte) 0x49, (byte) 0xA7, (byte) 0x78, (byte) 0xFD, (byte) 0xE0, (byte) 0xF7, (byte) 0x71, (byte) 0xD4,
+        (byte) 0x80, (byte) 0x50, (byte) 0xA7, (byte) 0xDD, (byte) 0x94, (byte) 0xD1, (byte) 0x6C
+    };
+
+    @Test
+    public void testSign_SHA1withDSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("DSA");
+        DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA1withDSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+
+        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testVerify_SHA1withDSA_Key_Success() throws Exception {
+        KeyFactory kf = KeyFactory.getInstance("DSA");
+        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("SHA1withDSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(SHA1withDSA_Vector2Signature));
+    }
+
+    @Test
+    public void testSign_SHA224withDSA_Key_Success() throws Exception {
+        TestUtils.assumeSHA2WithDSAAvailable();
+        KeyFactory kf = KeyFactory.getInstance("DSA");
+        DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA224withDSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+
+        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testVerify_SHA224withDSA_Key_Success() throws Exception {
+        TestUtils.assumeSHA2WithDSAAvailable();
+        KeyFactory kf = KeyFactory.getInstance("DSA");
+        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("SHA224withDSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(SHA224withDSA_Vector2Signature));
+    }
+
+    @Test
+    public void testSign_SHA256withDSA_Key_Success() throws Exception {
+        TestUtils.assumeSHA2WithDSAAvailable();
+        KeyFactory kf = KeyFactory.getInstance("DSA");
+        DSAPrivateKeySpec keySpec = new DSAPrivateKeySpec(DSA_priv, DSA_P, DSA_Q, DSA_G);
+        PrivateKey privKey = kf.generatePrivate(keySpec);
+
+        Signature sig = Signature.getInstance("SHA256withDSA");
+        sig.initSign(privKey);
+        sig.update(Vector2Data);
+
+        byte[] signature = sig.sign();
+        assertNotNull("Signature must not be null", signature);
+
+        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(signature));
+    }
+
+    @Test
+    public void testVerify_SHA256withDSA_Key_Success() throws Exception {
+        TestUtils.assumeSHA2WithDSAAvailable();
+        KeyFactory kf = KeyFactory.getInstance("DSA");
+        DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(DSA_pub, DSA_P, DSA_Q, DSA_G);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        Signature sig = Signature.getInstance("SHA256withDSA");
+        sig.initVerify(pubKey);
+        sig.update(Vector2Data);
+        assertTrue("Signature must verify correctly", sig.verify(SHA256withDSA_Vector2Signature));
+    }
+
+    private final int THREAD_COUNT = 10;
+
+    private void testSignature_MultipleThreads_Misuse(final Signature s, final PrivateKey p)
+            throws Exception {
+        ExecutorService es = Executors.newFixedThreadPool(THREAD_COUNT);
+
+        final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
+        final byte[] message = new byte[64];
+        List<Future<Void>> futures = new ArrayList<Future<Void>>();
+
+        for (int i = 0; i < THREAD_COUNT; i++) {
+            futures.add(es.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    // Try to make sure all the threads are ready first.
+                    latch.countDown();
+                    latch.await();
+
+                    for (int j = 0; j < 100; j++) {
+                        s.initSign(p);
+                        s.update(message);
+                        s.sign();
+                    }
+
+                    return null;
+                }
+            }));
+        }
+        es.shutdown();
+        assertTrue("Test should not timeout", es.awaitTermination(1, TimeUnit.MINUTES));
+
+        for (Future<Void> f : futures) {
+            try {
+                f.get();
+            } catch (ExecutionException expected) {
+                // We expect concurrent execution to cause instances to eventually throw, though
+                // if they happen to get lucky and execute completely, that's fine.
+            }
+        }
+    }
+
+    private static final byte[] NAMED_CURVE_VECTOR = "Satoshi Nakamoto".getBytes(
+            Charset.defaultCharset());
+    // $ echo -n "Satoshi Nakamoto" > signed
+    // $ openssl dgst -ecdsa-with-SHA1 -sign key.pem -out sig signed
+    private static final byte[] NAMED_CURVE_SIGNATURE = TestUtils.decodeHex("304402205b41ece6dcc1c5bfcfdae74658d99c08c5e783f3926c11ecc1a8bea5d95cdf27022061a7d5fc687287e2e02dd7c6723e2e27fe0555f789590a37e96b1bb0355b4df0");
+
+    private static PublicKey getNamedCurveEcPublicKey() throws Exception {
+        // These are the parameters for the BitCoin curve (secp256k1). See
+        // https://en.bitcoin.it/wiki/Secp256k1.
+        final BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
+        final BigInteger a = BigInteger.valueOf(0);
+        final BigInteger b = BigInteger.valueOf(7);
+        final BigInteger x = new BigInteger("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
+        final BigInteger y = new BigInteger("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16);
+        final BigInteger order = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
+        final int cofactor = 1;
+
+        final ECParameterSpec spec = new ECParameterSpec(new EllipticCurve(new ECFieldFp(p), a, b), new ECPoint(x, y), order, cofactor);
+
+        // $ openssl ecparam -name secp256k1 -genkey > key.pem
+        // $ openssl ec -text -noout < key.pem
+        final BigInteger Px = new BigInteger("2d45572747a625db5fd23b30f97044a682f2d42d31959295043c1fa0034c8ed3", 16);
+        final BigInteger Py = new BigInteger("4d330f52e4bba00145a331041c8bbcf300c4fbfdf3d63d8de7608155b2793808", 16);
+
+        final KeyFactory factory = KeyFactory.getInstance("EC");
+        ECPublicKeySpec keySpec = new ECPublicKeySpec(new ECPoint(Px, Py), spec);
+        return factory.generatePublic(keySpec);
+    }
+
+    @Test
+    public void testArbitraryCurve() throws Exception {
+        final PublicKey pub = getNamedCurveEcPublicKey();
+
+        Signature ecdsaVerify = Signature.getInstance("SHA1withECDSA");
+        ecdsaVerify.initVerify(pub);
+        ecdsaVerify.update(NAMED_CURVE_VECTOR);
+        boolean result = ecdsaVerify.verify(NAMED_CURVE_SIGNATURE);
+        assertEquals(true, result);
+
+        ecdsaVerify = Signature.getInstance("SHA1withECDSA");
+        ecdsaVerify.initVerify(pub);
+        ecdsaVerify.update("Not Satoshi Nakamoto".getBytes("UTF-8"));
+        result = ecdsaVerify.verify(NAMED_CURVE_SIGNATURE);
+        assertEquals(false, result);
+    }
+
+    private static void assertPSSAlgorithmParametersEquals(
+            PSSParameterSpec expectedSpec, AlgorithmParameters actual)
+                    throws InvalidParameterSpecException {
+        assertNotNull(actual);
+        assertEqualsIgnoreCase("PSS", actual.getAlgorithm());
+        PSSParameterSpec actualSpec = actual.getParameterSpec(PSSParameterSpec.class);
+        assertPSSParameterSpecEquals(expectedSpec, actualSpec);
+    }
+
+    private static void assertPSSParameterSpecEquals(
+            PSSParameterSpec expected, PSSParameterSpec actual) {
+        assertEqualsIgnoreCase(expected.getDigestAlgorithm(), actual.getDigestAlgorithm());
+        assertEqualsIgnoreCase(expected.getMGFAlgorithm(), actual.getMGFAlgorithm());
+        if (!"MGF1".equalsIgnoreCase(expected.getMGFAlgorithm())) {
+            fail("Unsupported MGF algorithm: " + expected.getMGFAlgorithm());
+        }
+        MGF1ParameterSpec expectedMgfParams = (MGF1ParameterSpec) expected.getMGFParameters();
+        MGF1ParameterSpec actualMgfParams = (MGF1ParameterSpec) actual.getMGFParameters();
+        assertEqualsIgnoreCase(
+                expectedMgfParams.getDigestAlgorithm(), actualMgfParams.getDigestAlgorithm());
+        assertEquals(expected.getSaltLength(), actual.getSaltLength());
+        assertEquals(expected.getTrailerField(), actual.getTrailerField());
+    }
+
+    private static void assertEqualsIgnoreCase(String expected, String actual) {
+        if (expected == null) {
+            if (actual == null) {
+                return;
+            }
+            fail("Expected null, actual: <" + actual + ">");
+        } else if (actual == null) {
+            fail("Expected: <" + expected + ">, actual: null");
+        } else {
+            if (!expected.equalsIgnoreCase(actual)) {
+                fail("Expected: <" + expected + ">, actual: <" + actual + ">");
+            }
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/cert/CertificateFactoryTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/cert/CertificateFactoryTest.java
new file mode 100644
index 0000000..54dcee2
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/cert/CertificateFactoryTest.java
@@ -0,0 +1,717 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.java.security.cert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import dalvik.system.VMRuntime;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.cert.CertPath;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TimeZone;
+import javax.security.auth.x500.X500Principal;
+import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.x509.X509V3CertificateGenerator;
+import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class CertificateFactoryTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private static final String VALID_CERTIFICATE_PEM =
+            "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\n"
+            + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\n"
+            + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\n"
+            + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n"
+            + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\n"
+            + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\n"
+            + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\n"
+            + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\n"
+            + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\n"
+            + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\n"
+            + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\n"
+            + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\n"
+            + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\n"
+            + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\n"
+            + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\n"
+            + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\n"
+            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\n"
+            + "-----END CERTIFICATE-----\n";
+
+    private static final String VALID_CERTIFICATE_PEM_CRLF =
+            "-----BEGIN CERTIFICATE-----\r\n"
+            + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\r\n"
+            + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg\r\n"
+            + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x\r\n"
+            + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh\r\n"
+            + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw\r\n"
+            + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC\r\n"
+            + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN\r\n"
+            + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L\r\n"
+            + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM\r\n"
+            + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl\r\n"
+            + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF\r\n"
+            + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw\r\n"
+            + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0\r\n"
+            + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF\r\n"
+            + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5\r\n"
+            + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6\r\n"
+            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==\r\n"
+            + "-----END CERTIFICATE-----\r\n";
+
+    private static final byte[] VALID_CERTIFICATE_PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
+            .getBytes(Charset.defaultCharset());
+
+    private static final byte[] VALID_CERTIFICATE_PEM_DATA =
+             ("MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM"
+            + "MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg"
+            + "THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x"
+            + "MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh"
+            + "MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw"
+            + "FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC"
+            + "gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN"
+            + "gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L"
+            + "05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM"
+            + "BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl"
+            + "LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF"
+            + "BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw"
+            + "Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0"
+            + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF"
+            + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5"
+            + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6"
+            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==")
+                     .getBytes(Charset.defaultCharset());
+
+    private static final byte[] VALID_CERTIFICATE_PEM_FOOTER = "\n-----END CERTIFICATE-----\n"
+            .getBytes(Charset.defaultCharset());
+
+    private static final String INVALID_CERTIFICATE_PEM =
+            "-----BEGIN CERTIFICATE-----\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
+            + "AAAAAAAA\n"
+            + "-----END CERTIFICATE-----";
+
+    private static final String VALID_CERTIFICATE_DER_BASE64 =
+            "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQG"
+            + "EwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhh"
+            + "d3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0xMTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVT"
+            + "MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApH"
+            + "b29nbGUgSW5jMRcwFQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw"
+            + "gYkCgYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jNgtXj9xVo"
+            + "RaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L05vuuWciKh0R73mkszeK"
+            + "9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAMBgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0w"
+            + "K6ApoCeGJWh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYI"
+            + "KwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzAB"
+            + "hhZodHRwOi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0ZS5j"
+            + "b20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUFAAOBgQCfQ89bxFAp"
+            + "sb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5u2ONgJd8IyAPkU0Wueru9G2Jysa9"
+            + "zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqA"
+            + "ibAxWEEHXw==";
+
+    @Test
+    public void test_generateCertificate() throws Exception {
+        ServiceTester.test("CertificateFactory")
+                .withAlgorithm("X509")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        CertificateFactory cf = CertificateFactory.getInstance("X509", p);
+                        test_generateCertificate(cf);
+                        test_generateCertificate_InputStream_Offset_Correct(cf);
+                        test_generateCertificate_InputStream_Empty(cf);
+                        test_generateCertificate_InputStream_InvalidStart_Failure(cf);
+                        test_generateCertificate_AnyLineLength_Success(cf);
+                        test_generateCertificate_PartialInput(cf);
+                    }
+                });
+    }
+
+    private void test_generateCertificate(CertificateFactory cf) throws Exception {
+        {
+            byte[] valid = VALID_CERTIFICATE_PEM.getBytes(Charset.defaultCharset());
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
+            assertNotNull(c);
+        }
+
+        {
+            byte[] valid = VALID_CERTIFICATE_PEM_CRLF.getBytes(Charset.defaultCharset());
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
+            assertNotNull(c);
+        }
+
+        {
+            byte[] valid = TestUtils.decodeBase64(VALID_CERTIFICATE_DER_BASE64);
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
+            assertNotNull(c);
+        }
+
+        try {
+            byte[] invalid = INVALID_CERTIFICATE_PEM.getBytes(Charset.defaultCharset());
+            cf.generateCertificate(new ByteArrayInputStream(invalid));
+            fail();
+        } catch (CertificateException expected) {
+        }
+
+        try {
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(new byte[0]));
+            // Bouncy Castle returns null on empty inputs rather than throwing an exception,
+            // which technically doesn't satisfy the method contract, but we'll accept it
+            assertTrue((c == null) && cf.getProvider().getName().equals("BC"));
+        } catch (CertificateException expected) {
+        }
+
+        try {
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(new byte[] { 0x00 }));
+            // Bouncy Castle returns null on short inputs rather than throwing an exception,
+            // which technically doesn't satisfy the method contract, but we'll accept it
+            assertTrue((c == null) && cf.getProvider().getName().equals("BC"));
+        } catch (CertificateException expected) {
+        }
+    }
+
+    /*
+     * Checks all possible line lengths for PEM input data.
+     */
+    private void test_generateCertificate_AnyLineLength_Success(CertificateFactory cf)
+            throws Exception {
+        // RI barfs on this
+        if (StandardNames.IS_RI) {
+            return;
+        }
+
+        int lineLength = 1;
+        int maxLineLength = VALID_CERTIFICATE_PEM_DATA.length;
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        baos.write(VALID_CERTIFICATE_PEM_HEADER);
+        int offset = 0;
+        while (lineLength < (maxLineLength - 4)) {
+            int end = offset + lineLength;
+            if (end > VALID_CERTIFICATE_PEM_DATA.length) {
+                end = VALID_CERTIFICATE_PEM_DATA.length;
+            }
+            baos.write(Arrays.copyOfRange(VALID_CERTIFICATE_PEM_DATA, offset, end));
+            baos.write('\n');
+            offset += lineLength;
+            if (offset >= maxLineLength) {
+                baos.write(VALID_CERTIFICATE_PEM_FOOTER);
+                try {
+                    Certificate c =
+                            cf.generateCertificate(new ByteArrayInputStream(baos.toByteArray()));
+                    assertNotNull(c);
+                } catch (Exception e) {
+                    throw new Exception("Fail at line length " + lineLength, e);
+                }
+                baos.reset();
+                baos.write(VALID_CERTIFICATE_PEM_HEADER);
+                offset = 0;
+            } else {
+                lineLength++;
+            }
+        }
+
+    }
+
+    private void test_generateCertificate_InputStream_Empty(CertificateFactory cf) throws Exception {
+        try {
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(new byte[0]));
+            if (!"BC".equals(cf.getProvider().getName())) {
+                fail("should throw CertificateException: " + cf.getProvider().getName());
+            }
+            assertNull(c);
+        } catch (CertificateException e) {
+            if ("BC".equals(cf.getProvider().getName())) {
+                fail("should return null: " + cf.getProvider().getName());
+            }
+        }
+    }
+
+    private void test_generateCertificate_InputStream_InvalidStart_Failure(CertificateFactory cf)
+            throws Exception {
+        try {
+            Certificate c = cf.generateCertificate(new ByteArrayInputStream(
+                    "-----BEGIN CERTIFICATE-----".getBytes(Charset.defaultCharset())));
+            if (!"BC".equals(cf.getProvider().getName())) {
+                fail("should throw CertificateException: " + cf.getProvider().getName());
+            }
+            assertNull(c);
+        } catch (CertificateException expected) {
+            if ("BC".equals(cf.getProvider().getName())) {
+                fail("should return null: " + cf.getProvider().getName());
+            }
+        }
+    }
+
+    private void test_generateCertificate_InputStream_Offset_Correct(CertificateFactory cf)
+            throws Exception {
+        byte[] valid = VALID_CERTIFICATE_PEM.getBytes(Charset.defaultCharset());
+
+        byte[] doubleCertificateData = new byte[valid.length * 2];
+        System.arraycopy(valid, 0, doubleCertificateData, 0, valid.length);
+        System.arraycopy(valid, 0, doubleCertificateData, valid.length, valid.length);
+        MeasuredInputStream certStream = new MeasuredInputStream(new ByteArrayInputStream(
+                doubleCertificateData));
+        Certificate certificate = cf.generateCertificate(certStream);
+        assertNotNull(certificate);
+        assertEquals(valid.length, certStream.getCount());
+    }
+
+    /**
+     * Proxy that counts the number of bytes read from an InputStream.
+     */
+    private static class MeasuredInputStream extends InputStream {
+        private long mCount = 0;
+
+        private long mMarked = 0;
+
+        private InputStream mStream;
+
+        public MeasuredInputStream(InputStream is) {
+            mStream = is;
+        }
+
+        public long getCount() {
+            return mCount;
+        }
+
+        @Override
+        public int read() throws IOException {
+            int nextByte = mStream.read();
+            mCount++;
+            return nextByte;
+        }
+
+        @Override
+        public int read(byte[] buffer) throws IOException {
+            int count = mStream.read(buffer);
+            mCount += count;
+            return count;
+        }
+
+        @Override
+        public int read(byte[] buffer, int offset, int length) throws IOException {
+            int count = mStream.read(buffer, offset, length);
+            mCount += count;
+            return count;
+        }
+
+        @Override
+        public long skip(long byteCount) throws IOException {
+            long count = mStream.skip(byteCount);
+            mCount += count;
+            return count;
+        }
+
+        @Override
+        public int available() throws IOException {
+            return mStream.available();
+        }
+
+        @Override
+        public void close() throws IOException {
+            mStream.close();
+        }
+
+        @Override
+        public void mark(int readlimit) {
+            mMarked = mCount;
+            mStream.mark(readlimit);
+        }
+
+        @Override
+        public boolean markSupported() {
+            return mStream.markSupported();
+        }
+
+        @Override
+        public synchronized void reset() throws IOException {
+            mCount = mMarked;
+            mStream.reset();
+        }
+    }
+
+    /**
+     * An InputStream that only returns two bytes at a time, no matter how many were requested.
+     */
+    private static class SlowInputStream extends FilterInputStream {
+        protected SlowInputStream(InputStream inputStream) {
+            super(inputStream);
+        }
+
+        @Override
+        public int read(byte[] buffer) throws IOException {
+            if (buffer.length < 2) {
+                return super.read(buffer);
+            }
+            return super.read(buffer, 0, 2);
+        }
+
+        @Override
+        public int read(byte[] buffer, int offset, int len) throws IOException {
+            if (len < 2) {
+                return super.read(buffer, offset, len);
+            }
+            return super.read(buffer, offset, 2);
+        }
+    }
+
+    // Test that certificates are decoded properly even if the InputStream is unhelpful and only
+    // returns partial inputs on basically every request.
+    private void test_generateCertificate_PartialInput(CertificateFactory cf) throws Exception {
+        byte[] valid = VALID_CERTIFICATE_PEM.getBytes(Charset.defaultCharset());
+        Certificate c =
+                cf.generateCertificate(new SlowInputStream(new ByteArrayInputStream(valid)));
+        assertNotNull(c);
+
+        valid = TestUtils.decodeBase64(VALID_CERTIFICATE_DER_BASE64);
+        c = cf.generateCertificate(new SlowInputStream(new ByteArrayInputStream(valid)));
+        assertNotNull(c);
+    }
+
+    /* CertPath tests */
+    @Test
+    public void testGenerateCertPath() throws Exception {
+        KeyHolder ca = generateCertificate(true, null);
+        KeyHolder cert1 = generateCertificate(true, ca);
+        KeyHolder cert2 = generateCertificate(false, cert1);
+        KeyHolder cert3 = generateCertificate(false, cert2);
+
+        List<X509Certificate> certs = new ArrayList<X509Certificate>();
+        certs.add(cert3.certificate);
+        certs.add(cert2.certificate);
+        certs.add(cert1.certificate);
+
+        List<X509Certificate> duplicatedCerts = new ArrayList<X509Certificate>(certs);
+        duplicatedCerts.add(cert2.certificate);
+
+        Provider[] providers = Security.getProviders("CertificateFactory.X509");
+        for (Provider p : providers) {
+            final CertificateFactory cf = CertificateFactory.getInstance("X.509", p);
+
+            if (Conscrypt.isConscrypt(p)) {
+                // It's not specified whether duplicated certs should work, but we want Conscrypt
+                // to accept them
+                {
+                    final CertPath duplicatedPath = cf.generateCertPath(duplicatedCerts);
+                    // This shouldn't cause an exception
+                    duplicatedPath.getEncoded();
+                }
+            }
+
+            testCertPathEncoding(cf, certs, null);
+
+            /* Make sure all encoding entries are the same. */
+            final Iterator<String> it1 = cf.getCertPathEncodings();
+            final Iterator<String> it2 = cf.generateCertPath(certs).getEncodings();
+            for (;;) {
+                assertEquals(p.getName(), it1.hasNext(), it2.hasNext());
+                if (!it1.hasNext()) {
+                    break;
+                }
+
+                String encoding = it1.next();
+                assertEquals(p.getName(), encoding, it2.next());
+
+                try {
+                    it1.remove();
+                    fail("Should not be able to remove from iterator");
+                } catch (UnsupportedOperationException expected) {
+                }
+
+                try {
+                    it2.remove();
+                    fail("Should not be able to remove from iterator");
+                } catch (UnsupportedOperationException expected) {
+                }
+
+                /* Now test using this encoding. */
+                testCertPathEncoding(cf, certs, encoding);
+            }
+        }
+    }
+
+    private void testCertPathEncoding(CertificateFactory cf, List<X509Certificate> expectedCerts,
+            String encoding) throws Exception {
+        final String providerName = cf.getProvider().getName() + "[" + encoding + "]";
+
+        final CertPath pathFromList = cf.generateCertPath(expectedCerts);
+
+        // Create a copy we can modify and discard.
+        final byte[] encodedCopy;
+        if (encoding == null) {
+            encodedCopy = pathFromList.getEncoded();
+            assertNotNull(providerName, encodedCopy);
+
+            // check idempotence
+            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()),
+                    Arrays.toString(encodedCopy));
+        } else {
+            encodedCopy = pathFromList.getEncoded(encoding);
+            assertNotNull(providerName, encodedCopy);
+
+            // check idempotence
+            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)),
+                    Arrays.toString(encodedCopy));
+        }
+
+        // Try to modify byte array.
+        encodedCopy[0] ^= (byte) 0xFF;
+
+        // Get a real copy we will use if the test proceeds.
+        final byte[] encoded;
+        if (encoding == null) {
+            encoded = pathFromList.getEncoded();
+            assertNotNull(providerName, encodedCopy);
+
+            // check idempotence
+            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded()),
+                    Arrays.toString(encoded));
+        } else {
+            encoded = pathFromList.getEncoded(encoding);
+            assertNotNull(providerName, encodedCopy);
+
+            // check idempotence
+            assertEquals(providerName, Arrays.toString(pathFromList.getEncoded(encoding)),
+                    Arrays.toString(encoded));
+        }
+        assertFalse(providerName, Arrays.toString(encoded).equals(Arrays.toString(encodedCopy)));
+
+        encodedCopy[0] ^= (byte) 0xFF;
+        assertEquals(providerName, Arrays.toString(encoded), Arrays.toString(encodedCopy));
+
+        final CertPath actualPath;
+        if (encoding == null) {
+            actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded));
+        } else {
+            actualPath = cf.generateCertPath(new ByteArrayInputStream(encoded), encoding);
+        }
+
+        // PKCS7 certificate bags are not guaranteed to be in order.
+        final List<? extends Certificate> actualCerts;
+        if (!"PKCS7".equals(encoding)) {
+            actualCerts = actualPath.getCertificates();
+            assertEquals(providerName, expectedCerts, actualCerts);
+        } else {
+            actualCerts = pathFromList.getCertificates();
+        }
+
+        try {
+            actualCerts.remove(0);
+            fail("List of certificate should be immutable");
+        } catch (UnsupportedOperationException expected) {
+        }
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(actualPath);
+        oos.close();
+
+        byte[] serialized = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        Object output = ois.readObject();
+        assertTrue(providerName, output instanceof CertPath);
+
+        assertEquals(providerName, actualPath, (CertPath) output);
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class KeyHolder {
+        public X509Certificate certificate;
+
+        public PrivateKey privateKey;
+    }
+
+    @SuppressWarnings("deprecation")
+    private static KeyHolder generateCertificate(boolean isCa, KeyHolder issuer) throws Exception {
+        Date startDate = new Date();
+
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.setTimeZone(TimeZone.getTimeZone("UTC"));
+        cal.set(2100, 0, 1, 0, 0, 0); // Jan 1, 2100 UTC
+        Date expiryDate = cal.getTime();
+
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        KeyPair keyPair = kpg.generateKeyPair();
+
+        BigInteger serial;
+        X500Principal issuerPrincipal;
+        X500Principal subjectPrincipal;
+        PrivateKey caKey;
+        if (issuer != null) {
+            serial = issuer.certificate.getSerialNumber().add(BigInteger.ONE);
+            subjectPrincipal = new X500Principal("CN=Test Certificate Serial #" + serial.toString());
+            issuerPrincipal = issuer.certificate.getSubjectX500Principal();
+            caKey = issuer.privateKey;
+        } else {
+            serial = BigInteger.ONE;
+            subjectPrincipal = new X500Principal("CN=Test CA, O=Tests, C=US");
+            issuerPrincipal = subjectPrincipal;
+            caKey = keyPair.getPrivate();
+        }
+
+        BasicConstraints basicConstraints;
+        if (isCa) {
+            basicConstraints = new BasicConstraints(10 - serial.intValue());
+        } else {
+            basicConstraints = new BasicConstraints(false);
+        }
+
+        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
+
+        PublicKey pubKey = keyPair.getPublic();
+        certGen.setSerialNumber(serial);
+        certGen.setIssuerDN(issuerPrincipal);
+        certGen.setNotBefore(startDate);
+        certGen.setNotAfter(expiryDate);
+        certGen.setSubjectDN(subjectPrincipal);
+        certGen.setPublicKey(pubKey);
+        certGen.setSignatureAlgorithm("SHA1withRSA");
+
+        if (issuer != null) {
+            certGen.addExtension(Extension.authorityKeyIdentifier, false,
+                    new AuthorityKeyIdentifierStructure(issuer.certificate));
+        } else {
+            certGen.addExtension(Extension.authorityKeyIdentifier, false,
+                    new AuthorityKeyIdentifier(generatePublicKeyDigest(pubKey)));
+        }
+
+        certGen.addExtension(Extension.subjectKeyIdentifier, false,
+                new SubjectKeyIdentifier(generatePublicKeyDigest(pubKey)));
+        certGen.addExtension(Extension.basicConstraints, true, basicConstraints);
+
+        X509Certificate cert = certGen.generate(caKey);
+
+        KeyHolder holder = new KeyHolder();
+        holder.certificate = cert;
+        holder.privateKey = keyPair.getPrivate();
+
+        return holder;
+    }
+
+    /**
+     * Generates a type 1 key identifier according to RFC 3280 4.2.1.2.
+     */
+    private static byte[] generatePublicKeyDigest(PublicKey pubKey) {
+        SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
+        MessageDigest sha1digest;
+        try {
+            sha1digest = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("SHA-1 not available");
+        }
+        return sha1digest.digest(spki.getPublicKeyData().getBytes());
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java
new file mode 100644
index 0000000..6456e70
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java
@@ -0,0 +1,214 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2018 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 com.android.org.conscrypt.java.security.cert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import dalvik.system.VMRuntime;
+import java.io.ByteArrayInputStream;
+import java.nio.charset.Charset;
+import java.security.InvalidKeyException;
+import java.security.Provider;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class X509CertificateTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private static final String VALID_CERT = "-----BEGIN CERTIFICATE-----\n"
+            + "MIIFMjCCAxqgAwIBAgIJAL0mG5fOeJ7xMA0GCSqGSIb3DQEBCwUAMC0xCzAJBgNV\n"
+            + "BAYTAkdCMQ8wDQYDVQQHDAZMb25kb24xDTALBgNVBAoMBFRlc3QwIBcNMTgwOTE3\n"
+            + "MTIxNzU3WhgPMjExODA4MjQxMjE3NTdaMC0xCzAJBgNVBAYTAkdCMQ8wDQYDVQQH\n"
+            + "DAZMb25kb24xDTALBgNVBAoMBFRlc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n"
+            + "ggIKAoICAQDCMhBrRAGGw+n2GdctBr/cEK4FZA6ajiHjihgpCHoSBdyL4R2jGKLS\n"
+            + "g0WgaMXa1HpkKN7LcIySosEBPlmcRkr1RqbEvQStOSvoFCXYvtx3alM6HTbXMcDR\n"
+            + "mqoKoABP6LXsPSoMWIgqMtP2X9EOppzHVIK1yFYFfbIlvYUV2Ka+MuMe0Vh5wvD1\n"
+            + "4GanPb+cWSKgdRSVQovCCMY3yWtZKVEaxRpCsk/mYYIFWz0tcgMjIKwDx1XXgiAV\n"
+            + "nU6NK43xbaw3XhtnaD/pv9lhTTbNrlcln9LjTD097BaK4R+1AEPHnpfxA9Ui3upn\n"
+            + "kbsNUdGdOB0ksZi/vd7lh833YgquQUIAhYrbfvq/HFCpVV1gljzlS3sqULYpLE//\n"
+            + "i3OsuL2mE+CYIJGpIi2GeJJWXciNMTJDOqTn+fRDtVb4RPp4Y70DJirp7XzaBi3q\n"
+            + "H0edANCzPSRCDbZsOhzIXhXshldiXVRX666DDlbMQgLTEnNKrkwv6DmU8o15XQsb\n"
+            + "8k1Os2YwXmkEOxUQ7AJZXVTZSf6UK9Znmdq1ZrHjybMfRUkHVxJcnKvrxfryralv\n"
+            + "gzfvu+D6HuxrCo3Ojqa+nDgIbxKEBtdrcsMhq1jWPFhjwo1fSadAkKOfdCAuXJRD\n"
+            + "THg3b4Sf+W7Cpc570YHrIpBf7WFl2XsPcEM0mJZ5+yATASCubNozQwIDAQABo1Mw\n"
+            + "UTAdBgNVHQ4EFgQUES0hupZSqY21JOba10QyZuxm91EwHwYDVR0jBBgwFoAUES0h\n"
+            + "upZSqY21JOba10QyZuxm91EwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF\n"
+            + "AAOCAgEABTN5S30ng/RMpBweDm2N561PdpaCdiRXtAFCRVWR2mkDYC/Xj9Vqe6be\n"
+            + "PyM7L/5OKYVjzF1yJu67z/dx+ja5o+41g17jdqla7hyPx+9B4uRyDh+1KJTa+duj\n"
+            + "mw/aA1LCr6O6W4WizDOsChJ6FaB2Y1+GlFnKWb5nUdhVJqXQE1WOX9dZnw8Y4Npd\n"
+            + "VmAsjWot0BZorJrt3fwfcv3QfA896twkbo7Llv/8qzg4sXZXZ4ZtgAOqnPngiSn+\n"
+            + "JT/vYCXZ406VvAFpFqMcVz2dO/VGuL8lGIMHRKNyafrsV81EzH1W/XmRWOgvgj6r\n"
+            + "yQI63ln/AMY72HQ97xLkE1xKunGz6bK5Ug5+O43Uftc4Mb6MUgzo+ZqEQ3Ob+cAV\n"
+            + "cvjmtwDaPO/O39O5Xq0tLTlkn2/cKf4OQ6S++GDxzyRVHh5JXgP4j9+jfZY57Woy\n"
+            + "R1bE7N50JjY4cDermBJKdlBIjL7UPhqmLyaG7V0hBitFlgGBUCcJtJOV0xYd5aF3\n"
+            + "pxNkvMXhBmh95fjxJ0cJjpO7tN1RAwtMMNgsl7OUbuVRQCHOPW5DgP5qY21jDeRn\n"
+            + "BY82382l+9QzykmJLI5MZnmj4BA9uIDCwMtoTTvP++SsvhUAbuvh7MOOUQL0EY4m\n"
+            + "KStYq7X9PKseN+PvmfeoffIKc5R/Ha39oi7cGMVHCr8aiEhsf94=\n"
+            + "-----END CERTIFICATE-----";
+
+    /*
+     This certificate is a modified version of the above self-signed cert. The cert has
+     been modified to change the certificate data's signature algorithm
+     declaration from sha256withRSAEncryption to sha512withRSAEncryption.  This causes
+     the signature block's algorithm (which is unmodified) to not match the cert info.
+     */
+    private static final String MISMATCHED_ALGORITHM_CERT =
+            "-----BEGIN CERTIFICATE-----\n"
+            + "MIIFMjCCAxqgAwIBAgIJAL0mG5fOeJ7xMA0GCSqGSIb3DQEBDQUAMC0xCzAJBgNV\n"
+            + "BAYTAkdCMQ8wDQYDVQQHDAZMb25kb24xDTALBgNVBAoMBFRlc3QwIBcNMTgwOTE3\n"
+            + "MTIxNzU3WhgPMjExODA4MjQxMjE3NTdaMC0xCzAJBgNVBAYTAkdCMQ8wDQYDVQQH\n"
+            + "DAZMb25kb24xDTALBgNVBAoMBFRlc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n"
+            + "ggIKAoICAQDCMhBrRAGGw+n2GdctBr/cEK4FZA6ajiHjihgpCHoSBdyL4R2jGKLS\n"
+            + "g0WgaMXa1HpkKN7LcIySosEBPlmcRkr1RqbEvQStOSvoFCXYvtx3alM6HTbXMcDR\n"
+            + "mqoKoABP6LXsPSoMWIgqMtP2X9EOppzHVIK1yFYFfbIlvYUV2Ka+MuMe0Vh5wvD1\n"
+            + "4GanPb+cWSKgdRSVQovCCMY3yWtZKVEaxRpCsk/mYYIFWz0tcgMjIKwDx1XXgiAV\n"
+            + "nU6NK43xbaw3XhtnaD/pv9lhTTbNrlcln9LjTD097BaK4R+1AEPHnpfxA9Ui3upn\n"
+            + "kbsNUdGdOB0ksZi/vd7lh833YgquQUIAhYrbfvq/HFCpVV1gljzlS3sqULYpLE//\n"
+            + "i3OsuL2mE+CYIJGpIi2GeJJWXciNMTJDOqTn+fRDtVb4RPp4Y70DJirp7XzaBi3q\n"
+            + "H0edANCzPSRCDbZsOhzIXhXshldiXVRX666DDlbMQgLTEnNKrkwv6DmU8o15XQsb\n"
+            + "8k1Os2YwXmkEOxUQ7AJZXVTZSf6UK9Znmdq1ZrHjybMfRUkHVxJcnKvrxfryralv\n"
+            + "gzfvu+D6HuxrCo3Ojqa+nDgIbxKEBtdrcsMhq1jWPFhjwo1fSadAkKOfdCAuXJRD\n"
+            + "THg3b4Sf+W7Cpc570YHrIpBf7WFl2XsPcEM0mJZ5+yATASCubNozQwIDAQABo1Mw\n"
+            + "UTAdBgNVHQ4EFgQUES0hupZSqY21JOba10QyZuxm91EwHwYDVR0jBBgwFoAUES0h\n"
+            + "upZSqY21JOba10QyZuxm91EwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF\n"
+            + "AAOCAgEABTN5S30ng/RMpBweDm2N561PdpaCdiRXtAFCRVWR2mkDYC/Xj9Vqe6be\n"
+            + "PyM7L/5OKYVjzF1yJu67z/dx+ja5o+41g17jdqla7hyPx+9B4uRyDh+1KJTa+duj\n"
+            + "mw/aA1LCr6O6W4WizDOsChJ6FaB2Y1+GlFnKWb5nUdhVJqXQE1WOX9dZnw8Y4Npd\n"
+            + "VmAsjWot0BZorJrt3fwfcv3QfA896twkbo7Llv/8qzg4sXZXZ4ZtgAOqnPngiSn+\n"
+            + "JT/vYCXZ406VvAFpFqMcVz2dO/VGuL8lGIMHRKNyafrsV81EzH1W/XmRWOgvgj6r\n"
+            + "yQI63ln/AMY72HQ97xLkE1xKunGz6bK5Ug5+O43Uftc4Mb6MUgzo+ZqEQ3Ob+cAV\n"
+            + "cvjmtwDaPO/O39O5Xq0tLTlkn2/cKf4OQ6S++GDxzyRVHh5JXgP4j9+jfZY57Woy\n"
+            + "R1bE7N50JjY4cDermBJKdlBIjL7UPhqmLyaG7V0hBitFlgGBUCcJtJOV0xYd5aF3\n"
+            + "pxNkvMXhBmh95fjxJ0cJjpO7tN1RAwtMMNgsl7OUbuVRQCHOPW5DgP5qY21jDeRn\n"
+            + "BY82382l+9QzykmJLI5MZnmj4BA9uIDCwMtoTTvP++SsvhUAbuvh7MOOUQL0EY4m\n"
+            + "KStYq7X9PKseN+PvmfeoffIKc5R/Ha39oi7cGMVHCr8aiEhsf94=\n"
+            + "-----END CERTIFICATE-----\n";
+
+    /**
+     * This cert has an EC key with curve prime256v1 encoded using explicit params.
+     */
+    private static final String EC_EXPLICIT_KEY_CERT =
+            "-----BEGIN CERTIFICATE-----\n"
+            + "MIICAjCCAagCCQCrIzClvU58azAKBggqhkjOPQQDAjAPMQ0wCwYDVQQDDARUZXN0\n"
+            + "MB4XDTE4MTAwMjEyNDQzMloXDTE4MTEwMTEyNDQzMlowDzENMAsGA1UEAwwEVGVz\n"
+            + "dDCCAUswggEDBgcqhkjOPQIBMIH3AgEBMCwGByqGSM49AQECIQD/////AAAAAQAA\n"
+            + "AAAAAAAAAAAAAP///////////////zBbBCD/////AAAAAQAAAAAAAAAAAAAAAP//\n"
+            + "/////////////AQgWsY12Ko6k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsDFQDE\n"
+            + "nTYIhucEk2pmeOETnSa3gZ9+kARBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLeszoPSh\n"
+            + "OUXYmMKWT+NC4v4af5uO5+tKfA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////AAAA\n"
+            + "AP//////////vOb6racXnoTzucrC/GMlUQIBAQNCAAQXU+GFdLabcY/RvzoNjLhC\n"
+            + "6uN1Yt1baN2NYyKYEhwR9nb8nLa/m7f30OOi/8OrxQhnUl5qW0I0IbHflGnsqQ6s\n"
+            + "MAoGCCqGSM49BAMCA0gAMEUCIQDRXoZwmnsIJfg4mTemkM+heMS1iXRYUO0Dar5u\n"
+            + "Qhy0YgIgYWr0qSCLqxUQv3oQHMUpSmfHtP0Pwvb3DbbH6lY7TkI=\n"
+            + "-----END CERTIFICATE-----\n";
+
+    // See issue #539.
+    @Test
+    public void testMismatchedAlgorithm() throws Exception {
+        ServiceTester.test("CertificateFactory")
+                .withAlgorithm("X509")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        CertificateFactory cf = CertificateFactory.getInstance("X509", p);
+                        try {
+                            Certificate c = cf.generateCertificate(
+                                    new ByteArrayInputStream(MISMATCHED_ALGORITHM_CERT.getBytes(
+                                            Charset.forName("US-ASCII"))));
+                            c.verify(c.getPublicKey());
+                            fail();
+                        } catch (CertificateException expected) {
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Confirm that explicit EC params aren't accepted in certificates.
+     */
+    @Test
+    public void testExplicitEcParams() throws Exception {
+        ServiceTester.test("CertificateFactory")
+                .withAlgorithm("X509")
+                // Bouncy Castle allows explicit EC params in certificates, even though they're
+                // barred by RFC 5480
+                .skipProvider("BC")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        try {
+                            CertificateFactory cf = CertificateFactory.getInstance("X509", p);
+                            Certificate c = cf.generateCertificate(new ByteArrayInputStream(
+                                    EC_EXPLICIT_KEY_CERT.getBytes(Charset.forName("US-ASCII"))));
+                            c.verify(c.getPublicKey());
+                            fail();
+                        } catch (InvalidKeyException expected) {
+                            // TODO: Should we throw CertificateParsingException at parse time
+                            // instead of waiting for when the user accesses the key?
+                        } catch (CertificateParsingException expected) {
+                        }
+                    }
+                });
+    }
+
+    @Test
+    public void testSigAlgName() throws Exception {
+        ServiceTester.test("CertificateFactory")
+                .withAlgorithm("X509")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        CertificateFactory cf = CertificateFactory.getInstance("X509", p);
+                        Certificate c = cf.generateCertificate(new ByteArrayInputStream(
+                                VALID_CERT.getBytes(Charset.forName("US-ASCII"))));
+                        assertEquals("SHA256WITHRSA",
+                                ((X509Certificate) c).getSigAlgName().toUpperCase());
+                    }
+                });
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/AeadCipherTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/AeadCipherTest.java
new file mode 100644
index 0000000..fd70f86
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/AeadCipherTest.java
@@ -0,0 +1,330 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.nio.ByteBuffer;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class AeadCipherTest {
+
+  @BeforeClass
+  public static void setUp() {
+    TestUtils.assumeAllowsUnsignedCrypto();
+  }
+
+  @Parameterized.Parameters(name = "{0}")
+  public static Iterable<String> ciphers() {
+    return Arrays.asList(
+      "AES/GCM/NoPadding",
+      "AES/GCM-SIV/NoPadding",
+      "ChaCha20/Poly1305/NoPadding");
+  }
+
+  private final String cipher;
+  private byte counter;
+
+  public AeadCipherTest(String cipher) {
+    this.cipher = cipher;
+  }
+
+  private Key newKey() {
+    if (cipher.startsWith("AES/")) {
+      byte[] keyData = new byte[16];
+      keyData[0] = counter++;
+      return new SecretKeySpec(keyData, "AES");
+    } else if (cipher.startsWith("ChaCha20/")) {
+      byte[] keyData = new byte[32];
+      keyData[0] = counter++;
+      return new SecretKeySpec(keyData, "ChaCha20");
+    } else {
+      throw new IllegalStateException("Couldn't generate key for " + cipher);
+    }
+  }
+
+  private AlgorithmParameterSpec newParamSpec() {
+    if (cipher.startsWith("AES/GCM")) {
+      byte[] nonce = new byte[12];
+      nonce[0] = counter++;
+      return new GCMParameterSpec(128, nonce);
+    } else if (cipher.startsWith("ChaCha20/")) {
+      byte[] nonce = new byte[12];
+      nonce[0] = counter++;
+      return new IvParameterSpec(nonce);
+    } else {
+      throw new IllegalStateException("Couldn't generate algorithm parameter spec for " + cipher);
+    }
+  }
+
+  @Test
+  public void testUpdateAAD_AfterInit() throws Exception {
+    Cipher c = Cipher.getInstance(cipher);
+    c.init(Cipher.ENCRYPT_MODE, newKey());
+    c.updateAAD(new byte[8]);
+    c.updateAAD(ByteBuffer.wrap(new byte[8]));
+  }
+
+  @Test
+  public void testUpdateAAD_AfterUpdate() throws Exception {
+    Cipher c = Cipher.getInstance(cipher);
+    c.init(Cipher.ENCRYPT_MODE, newKey());
+    c.updateAAD(new byte[8]);
+    c.update(new byte[8]);
+    c.updateAAD(ByteBuffer.wrap(new byte[8]));
+  }
+
+  /*
+   * Check that two AAD updates are equivalent to one.
+   * http://b/27371173
+   */
+  @Test
+  public void testUpdateAAD_Twice() throws Exception {
+    Key key = newKey();
+    AlgorithmParameterSpec spec = newParamSpec();
+    Cipher c1 = Cipher.getInstance(cipher);
+    Cipher c2 = Cipher.getInstance(cipher);
+
+    c1.init(Cipher.ENCRYPT_MODE, key, spec);
+    c1.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+    });
+    c1.updateAAD(new byte[] {
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    c2.init(Cipher.ENCRYPT_MODE, key, spec);
+    c2.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    assertEquals(Arrays.toString(c1.doFinal()), Arrays.toString(c2.doFinal()));
+  }
+
+  @Test
+  public void testUpdateAAD_ByteBuffer() throws Exception {
+    Key key = newKey();
+    AlgorithmParameterSpec spec = newParamSpec();
+    Cipher c1 = Cipher.getInstance(cipher);
+    Cipher c2 = Cipher.getInstance(cipher);
+    Cipher c3 = Cipher.getInstance(cipher);
+
+    c1.init(Cipher.ENCRYPT_MODE, key, spec);
+    c1.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    c2.init(Cipher.ENCRYPT_MODE, key, spec);
+    c2.updateAAD(ByteBuffer.wrap(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    }));
+
+    c3.init(Cipher.ENCRYPT_MODE, key, spec);
+    ByteBuffer buf = ByteBuffer.allocateDirect(10);
+    buf.put(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+    buf.flip();
+    c3.updateAAD(buf);
+
+    byte[] c1Final = c1.doFinal();
+    byte[] c2Final = c2.doFinal();
+    byte[] c3Final = c3.doFinal();
+    assertEquals(Arrays.toString(c1Final), Arrays.toString(c2Final));
+    assertEquals(Arrays.toString(c1Final), Arrays.toString(c3Final));
+  }
+
+  @Test
+  public void testUpdateAAD_ByteBuffer_MultipleUpdates() throws Exception {
+    Key key = newKey();
+    AlgorithmParameterSpec spec = newParamSpec();
+    Cipher c1 = Cipher.getInstance(cipher);
+    Cipher c2 = Cipher.getInstance(cipher);
+    Cipher c3 = Cipher.getInstance(cipher);
+
+    c1.init(Cipher.ENCRYPT_MODE, key, spec);
+    c1.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+    });
+    c1.updateAAD(new byte[] {
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    c2.init(Cipher.ENCRYPT_MODE, key, spec);
+    c2.updateAAD(ByteBuffer.wrap(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+    }));
+    c2.updateAAD(ByteBuffer.wrap(new byte[] {
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    }));
+
+    c3.init(Cipher.ENCRYPT_MODE, key, spec);
+    ByteBuffer buf = ByteBuffer.allocateDirect(10);
+    buf.put(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+    buf.flip();
+    buf.limit(5);
+    c3.updateAAD(buf);
+    buf.limit(10);
+    c3.updateAAD(buf);
+
+    byte[] c1Final = c1.doFinal();
+    byte[] c2Final = c2.doFinal();
+    byte[] c3Final = c3.doFinal();
+    assertEquals(Arrays.toString(c1Final), Arrays.toString(c2Final));
+    assertEquals(Arrays.toString(c1Final), Arrays.toString(c3Final));
+  }
+
+  @Test
+  public void testUpdateAAD_ByteBuffer_MixedCalls() throws Exception {
+    Key key = newKey();
+    AlgorithmParameterSpec spec = newParamSpec();
+    Cipher c1 = Cipher.getInstance(cipher);
+    Cipher c2 = Cipher.getInstance(cipher);
+    Cipher c3 = Cipher.getInstance(cipher);
+
+    c1.init(Cipher.ENCRYPT_MODE, key, spec);
+    c1.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    c2.init(Cipher.ENCRYPT_MODE, key, spec);
+    c2.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+    });
+    c2.updateAAD(ByteBuffer.wrap(new byte[] {
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    }));
+
+    c3.init(Cipher.ENCRYPT_MODE, key, spec);
+    ByteBuffer buf = ByteBuffer.allocateDirect(10);
+    buf.put(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+    buf.flip();
+    buf.limit(5);
+    c3.updateAAD(buf);
+    c3.updateAAD(new byte[] {
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    byte[] c1Final = c1.doFinal();
+    byte[] c2Final = c2.doFinal();
+    byte[] c3Final = c3.doFinal();
+    assertEquals(Arrays.toString(c1Final), Arrays.toString(c2Final));
+    assertEquals(Arrays.toString(c1Final), Arrays.toString(c3Final));
+  }
+
+  @Test
+  public void testUpdateAAD_ByteBuffer_Unequal() throws Exception {
+    Key key = newKey();
+    AlgorithmParameterSpec spec = newParamSpec();
+    Cipher c1 = Cipher.getInstance(cipher);
+    Cipher c2 = Cipher.getInstance(cipher);
+    Cipher c3 = Cipher.getInstance(cipher);
+
+    c1.init(Cipher.ENCRYPT_MODE, key, spec);
+    c1.updateAAD(ByteBuffer.wrap(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+    }));
+
+    c2.init(Cipher.ENCRYPT_MODE, key, spec);
+    c2.updateAAD(new byte[] {
+        0x06, 0x07, 0x08, 0x09, 0x10,
+    });
+
+    c3.init(Cipher.ENCRYPT_MODE, key, spec);
+    ByteBuffer buf = ByteBuffer.allocateDirect(10);
+    buf.put(new byte[] {
+        0x11, 0x12, 0x13, 0x14, 0x15,
+    });
+    buf.flip();
+    c3.updateAAD(buf);
+
+    byte[] c1Final = c1.doFinal();
+    byte[] c2Final = c2.doFinal();
+    byte[] c3Final = c3.doFinal();
+    assertFalse(Arrays.equals(c1Final, c2Final));
+    assertFalse(Arrays.equals(c2Final, c3Final));
+    assertFalse(Arrays.equals(c1Final, c3Final));
+  }
+
+  /*
+   * Check that encryption with old and new instances update correctly.
+   * http://b/27324690
+   */
+  @Test
+  public void testReuse() throws Exception {
+    Key key = newKey();
+    Key key2 = newKey();
+    AlgorithmParameterSpec spec = newParamSpec();
+    Cipher c1 = Cipher.getInstance(cipher);
+    Cipher c2 = Cipher.getInstance(cipher);
+
+    // Pollute the c1 cipher with AAD
+    c1.init(Cipher.ENCRYPT_MODE, key, spec);
+    c1.updateAAD(new byte[] {
+        0x01, 0x02, 0x03, 0x04, 0x05,
+    });
+
+    // Now init each again and make sure the outputs are the same.  We have to use a
+    // different key because reiniting an AEAD cipher with the same key and IV should fail.
+    c1.init(Cipher.ENCRYPT_MODE, key2, spec);
+    c2.init(Cipher.ENCRYPT_MODE, key2, spec);
+
+    byte[] aad = new byte[] {
+        0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
+    };
+    c1.updateAAD(aad);
+    c2.updateAAD(aad);
+
+    assertEquals(Arrays.toString(c1.doFinal()), Arrays.toString(c2.doFinal()));
+
+    // .doFinal should also not allow reuse without re-initialization
+    byte[] aad2 = new byte[] {
+        0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
+    };
+    try {
+      c1.updateAAD(aad2);
+      fail("Should not allow updateAAD without re-initialization");
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      c1.update(new byte[8]);
+      fail("Should not allow update without re-initialization");
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      c1.doFinal();
+      fail("Should not allow doFinal without re-initialization");
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/CipherBasicsTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/CipherBasicsTest.java
new file mode 100644
index 0000000..0ae78f4
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/CipherBasicsTest.java
@@ -0,0 +1,280 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for basic compliance for ciphers.  This test uses reference vectors produced by
+ * standards bodies and confirms that all implementations produce the correct answer
+ * for the given inputs.
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public final class CipherBasicsTest {
+
+    private static final Map<String, String> BASIC_CIPHER_TO_TEST_DATA = new HashMap<String, String>();
+    static {
+        BASIC_CIPHER_TO_TEST_DATA.put("AES/ECB/NoPadding", "/crypto/aes-ecb.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("AES/CBC/NoPadding", "/crypto/aes-cbc.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("AES/CFB8/NoPadding", "/crypto/aes-cfb8.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("AES/CFB128/NoPadding", "/crypto/aes-cfb128.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("AES/OFB/NoPadding", "/crypto/aes-ofb.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("DESEDE/ECB/NoPadding", "/crypto/desede-ecb.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("DESEDE/CBC/NoPadding", "/crypto/desede-cbc.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("DESEDE/CFB8/NoPadding", "/crypto/desede-cfb8.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("DESEDE/CFB64/NoPadding", "/crypto/desede-cfb64.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("DESEDE/OFB/NoPadding", "/crypto/desede-ofb.csv");
+        BASIC_CIPHER_TO_TEST_DATA.put("ChaCha20", "/crypto/chacha20.csv");
+    }
+
+    private static final Map<String, String> AEAD_CIPHER_TO_TEST_DATA = new HashMap<String, String>();
+    static {
+        AEAD_CIPHER_TO_TEST_DATA.put("AES/GCM/NoPadding", "/crypto/aes-gcm.csv");
+        AEAD_CIPHER_TO_TEST_DATA.put("AES/GCM-SIV/NoPadding", "/crypto/aes-gcm-siv.csv");
+        AEAD_CIPHER_TO_TEST_DATA.put("ChaCha20/Poly1305/NoPadding", "/crypto/chacha20-poly1305.csv");
+    }
+
+    private static final int KEY_INDEX = 0;
+    private static final int IV_INDEX = 1;
+    private static final int PLAINTEXT_INDEX = 2;
+    private static final int CIPHERTEXT_INDEX = 3;
+    private static final int TAG_INDEX = 4;
+    private static final int AAD_INDEX = 5;
+
+    @BeforeClass
+    public static void setUp() {
+        TestUtils.assumeAllowsUnsignedCrypto();
+    }
+
+    @Test
+    public void testBasicEncryption() throws Exception {
+        for (Provider p : Security.getProviders()) {
+            for (Map.Entry<String, String> entry : BASIC_CIPHER_TO_TEST_DATA.entrySet()) {
+                String transformation = entry.getKey();
+
+                // In OpenJDK 6, the SunPKCS11-NSS implementation of AES/ECB/NoPadding thinks
+                // that it's AES/CTR/NoPadding during init() for some reason, which causes it
+                // to throw an exception due to a lack of IV (required for CTR, prohibited for ECB).
+                // We don't strongly care about checking this implementation, so just skip it.
+                if (p.getName().equals("SunPKCS11-NSS")
+                        && transformation.equals("AES/ECB/NoPadding")) {
+                    continue;
+                }
+
+                // The SunJCE implementation of ChaCha20 only supports initializing with
+                // ChaCha20ParameterSpec, introduced in Java 11.  For now, just skip testing it.
+                if (transformation.equals("ChaCha20") && p.getName().equals("SunJCE")) {
+                    continue;
+                }
+
+                Cipher cipher;
+                try {
+                    cipher = Cipher.getInstance(transformation, p);
+                } catch (NoSuchAlgorithmException e) {
+                    // This provider doesn't provide this algorithm, ignore it
+                    continue;
+                }
+
+                List<String[]> data = readCsvResource(entry.getValue());
+                for (String[] line : data) {
+                    Key key = new SecretKeySpec(toBytes(line[KEY_INDEX]),
+                            getBaseAlgorithm(transformation));
+                    byte[] iv = toBytes(line[IV_INDEX]);
+                    byte[] plaintext = toBytes(line[PLAINTEXT_INDEX]);
+                    byte[] ciphertext = toBytes(line[CIPHERTEXT_INDEX]);
+
+                    // Initialize the IV, if there is one
+                    AlgorithmParameters params;
+                    if (iv.length > 0) {
+                        params = AlgorithmParameters.getInstance(getBaseAlgorithm(transformation));
+                        params.init(iv, "RAW");
+                    } else {
+                        params = null;
+                    }
+
+                    try {
+                        cipher.init(Cipher.ENCRYPT_MODE, key, params);
+                        assertEquals("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " reported the wrong output size",
+                                ciphertext.length, cipher.getOutputSize(plaintext.length));
+                        assertTrue("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " failed on encryption, data is " + Arrays.toString(line),
+                                Arrays.equals(ciphertext, cipher.doFinal(plaintext)));
+
+                        cipher.init(Cipher.DECRYPT_MODE, key, params);
+                        assertEquals("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " reported the wrong output size",
+                                plaintext.length, cipher.getOutputSize(ciphertext.length));
+                        assertTrue("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " failed on decryption, data is " + Arrays.toString(line),
+                                Arrays.equals(plaintext, cipher.doFinal(ciphertext)));
+                    } catch (InvalidKeyException e) {
+                        // Some providers may not support raw SecretKeySpec keys, that's allowed
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testAeadEncryption() throws Exception {
+        TestUtils.assumeAEADAvailable();
+        for (Provider p : Security.getProviders()) {
+            for (Map.Entry<String, String> entry : AEAD_CIPHER_TO_TEST_DATA.entrySet()) {
+                String transformation = entry.getKey();
+
+                Cipher cipher;
+                try {
+                    cipher = Cipher.getInstance(transformation, p);
+                } catch (NoSuchAlgorithmException e) {
+                    // This provider doesn't provide this algorithm, ignore it
+                    continue;
+                }
+
+                List<String[]> data = readCsvResource(entry.getValue());
+                for (String[] line : data) {
+                    Key key = new SecretKeySpec(toBytes(line[KEY_INDEX]),
+                            getBaseAlgorithm(transformation));
+                    byte[] iv = toBytes(line[IV_INDEX]);
+                    byte[] plaintext = toBytes(line[PLAINTEXT_INDEX]);
+                    byte[] ciphertext = toBytes(line[CIPHERTEXT_INDEX]);
+                    byte[] tag = toBytes(line[TAG_INDEX]);
+                    byte[] aad = toBytes(line[AAD_INDEX]);
+
+                    // Some ChaCha20 tests include truncated tags, which the Java API doesn't
+                    // support.  Skip those tests.
+                    if (transformation.startsWith("ChaCha20") && tag.length < 16) {
+                        continue;
+                    }
+
+                    AlgorithmParameterSpec params;
+                    if (transformation.contains("GCM")) {
+                        params = new GCMParameterSpec(8 * tag.length, iv);
+                    } else {
+                        params = new IvParameterSpec(iv);
+                    }
+
+                    try {
+                        cipher.init(Cipher.ENCRYPT_MODE, key, params);
+                        if (aad.length > 0) {
+                            cipher.updateAAD(aad);
+                        }
+                        byte[] combinedOutput = new byte[ciphertext.length + tag.length];
+                        assertEquals("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " reported the wrong output size",
+                                combinedOutput.length, cipher.getOutputSize(plaintext.length));
+                        System.arraycopy(ciphertext, 0, combinedOutput, 0, ciphertext.length);
+                        System.arraycopy(tag, 0, combinedOutput, ciphertext.length, tag.length);
+                        assertTrue("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " failed on encryption, data is " + Arrays.toString(line),
+                                Arrays.equals(combinedOutput, cipher.doFinal(plaintext)));
+
+                        cipher.init(Cipher.DECRYPT_MODE, key, params);
+                        if (aad.length > 0) {
+                            cipher.updateAAD(aad);
+                        }
+                        assertEquals("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " reported the wrong output size",
+                                plaintext.length, cipher.getOutputSize(combinedOutput.length));
+                        assertTrue("Provider " + p.getName()
+                                        + ", algorithm " + transformation
+                                        + " failed on decryption, data is " + Arrays.toString(line),
+                                Arrays.equals(plaintext, cipher.doFinal(combinedOutput)));
+                    } catch (InvalidKeyException e) {
+                        // Some providers may not support raw SecretKeySpec keys, that's allowed
+                    } catch (InvalidAlgorithmParameterException e) {
+                        // Some providers may not support all tag lengths or nonce lengths,
+                        // that's allowed
+                    }
+                }
+            }
+        }
+    }
+
+    private static List<String[]> readCsvResource(String resourceName) throws IOException {
+        InputStream stream = CipherBasicsTest.class.getResourceAsStream(resourceName);
+        List<String[]> lines = new ArrayList<String[]>();
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (line.isEmpty() || line.startsWith("#")) {
+                    continue;
+                }
+                lines.add(line.split(",", -1));
+            }
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+        return lines;
+    }
+
+    /**
+     * Returns the underlying cipher name given a cipher transformation.  For example,
+     * passing {@code AES/CBC/NoPadding} returns {@code AES}.
+     */
+    private static String getBaseAlgorithm(String transformation) {
+        if (transformation.contains("/")) {
+            return transformation.substring(0, transformation.indexOf('/'));
+        }
+        return transformation;
+    }
+
+    private static byte[] toBytes(String hex) {
+        return TestUtils.decodeHex(hex, /* allowSingleChar= */ true);
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
new file mode 100644
index 0000000..0e0ab48
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
@@ -0,0 +1,4754 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.crypto.AEADBadTagException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.PSource;
+import javax.crypto.spec.SecretKeySpec;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.AfterClass;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import dalvik.system.VMRuntime;
+import sun.security.jca.Providers;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public final class CipherTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    @BeforeClass
+    public static void setUp() {
+        TestUtils.assumeAllowsUnsignedCrypto();
+    }
+
+    /** GCM tag size used for tests. */
+    private static final int GCM_TAG_SIZE_BITS = 96;
+    private static final int GCM_SIV_TAG_SIZE_BITS = 128;
+
+    private static final String[] RSA_PROVIDERS = StandardNames.IS_RI
+            ? new String[] {"SunJCE", StandardNames.JSSE_PROVIDER_NAME}
+            : new String[] {"BC", StandardNames.JSSE_PROVIDER_NAME};
+
+    private static final String[] AES_PROVIDERS = StandardNames.IS_RI
+            ? new String[] {"SunJCE", StandardNames.JSSE_PROVIDER_NAME}
+            : new String[] {"BC", StandardNames.JSSE_PROVIDER_NAME};
+
+    private static boolean isSupported(String algorithm, String provider) {
+        if (algorithm.equals("RC2")) {
+            return false;
+        }
+        if (algorithm.equals("PBEWITHMD5ANDRC2")) {
+            return false;
+        }
+        if (algorithm.startsWith("PBEWITHSHA1ANDRC2")) {
+            return false;
+        }
+        if (algorithm.equals("PBEWITHSHAAND40BITRC2-CBC")) {
+            return false;
+        }
+        if (algorithm.equals("PBEWITHSHAAND128BITRC2-CBC")) {
+            return false;
+        }
+        if (algorithm.equals("PBEWITHSHAANDTWOFISH-CBC")) {
+            return false;
+        }
+        if (!IS_UNLIMITED) {
+            if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
+                return false;
+            }
+        }
+        // stream modes CFB, CTR, CTS, OFB with PKCS5Padding or PKCS7Padding don't really make sense
+        if (!provider.equals("AndroidOpenSSL") &&
+            (algorithm.equals("AES/CFB/PKCS5PADDING")
+             || algorithm.equals("AES/CFB/PKCS7PADDING")
+             || algorithm.equals("AES/CTR/PKCS5PADDING")
+             || algorithm.equals("AES/CTR/PKCS7PADDING")
+             || algorithm.equals("AES/CTS/PKCS5PADDING")
+             || algorithm.equals("AES/CTS/PKCS7PADDING")
+             || algorithm.equals("AES/OFB/PKCS5PADDING")
+             || algorithm.equals("AES/OFB/PKCS7PADDING"))) {
+            return false;
+        }
+        return true;
+    }
+
+    private static boolean isSupportedForWrapping(String algorithm) {
+        if (isOnlyWrappingAlgorithm(algorithm)) {
+            return true;
+        }
+        // http://b/9097343 RSA with NoPadding won't work since
+        // leading zeroes in the underlying key material are lost.
+        if (algorithm.equals("RSA/ECB/NOPADDING")) {
+            return false;
+        }
+        // AESWRAP should be used instead, fails with BC and SunJCE otherwise.
+        if (algorithm.startsWith("AES") || algorithm.startsWith("DESEDE")) {
+            return false;
+        }
+        return true;
+    }
+
+    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";
+        }
+        if (algorithm.startsWith("AES/")) {
+            return "AES";
+        }
+        if (algorithm.startsWith("AES_128/") || algorithm.startsWith("AES_256/")) {
+            return "AES";
+        }
+        if (algorithm.equals("GCM")) {
+            return "AES";
+        }
+        if (algorithm.startsWith("CHACHA20/")) {
+            return "CHACHA20";
+        }
+        if (algorithm.startsWith("DESEDE/")) {
+            return "DESEDE";
+        }
+        if (algorithm.equals("PBEWITHMD5AND128BITAES-CBC-OPENSSL")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHMD5AND192BITAES-CBC-OPENSSL")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHMD5AND256BITAES-CBC-OPENSSL")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHSHA256AND128BITAES-CBC-BC")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHSHA256AND192BITAES-CBC-BC")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHSHA256AND256BITAES-CBC-BC")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHSHAAND128BITAES-CBC-BC")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHSHAAND192BITAES-CBC-BC")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHSHAAND256BITAES-CBC-BC")) {
+            return "AES";
+        }
+        if (algorithm.equals("PBEWITHMD5ANDDES")) {
+            return "DES";
+        }
+        if (algorithm.equals("PBEWITHSHA1ANDDES")) {
+            return "DES";
+        }
+        if (algorithm.equals("DESEDEWRAP")) {
+            return "DESEDE";
+        }
+        if (algorithm.equals("PBEWITHSHAAND2-KEYTRIPLEDES-CBC")) {
+            return "DESEDE";
+        }
+        if (algorithm.equals("PBEWITHSHAAND3-KEYTRIPLEDES-CBC")) {
+            return "DESEDE";
+        }
+        if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
+            return "DESEDE";
+        }
+        if (algorithm.equals("PBEWITHSHA1ANDDESEDE")) {
+            return "DESEDE";
+        }
+        if (algorithm.equals("RSA/ECB/NOPADDING")) {
+            return "RSA";
+        }
+        if (algorithm.equals("RSA/ECB/PKCS1PADDING")) {
+            return "RSA";
+        }
+        if (algorithm.equals("PBEWITHSHAAND40BITRC4")) {
+            return "ARC4";
+        }
+        if (algorithm.equals("PBEWITHSHAAND128BITRC4")) {
+            return "ARC4";
+        }
+        return algorithm;
+    }
+
+    private static boolean isAsymmetric(String algorithm) {
+        return getBaseAlgorithm(algorithm).equals("RSA");
+    }
+
+    private static boolean isOnlyWrappingAlgorithm(String algorithm) {
+        return algorithm.endsWith("WRAP");
+    }
+
+    private static boolean isPBE(String algorithm) {
+        return algorithm.startsWith("PBE");
+    }
+
+    private static boolean isAEAD(String algorithm) {
+        return "GCM".equals(algorithm) || algorithm.contains("/GCM/")
+                || algorithm.contains("/GCM-SIV/")
+                || algorithm.equals("CHACHA20/POLY1305/NOPADDING");
+    }
+
+    private static boolean isStreamMode(String algorithm) {
+        return algorithm.contains("/CTR/") || algorithm.contains("/OFB")
+                || algorithm.contains("/CFB");
+    }
+
+    private static boolean isRandomizedEncryption(String algorithm) {
+        return algorithm.endsWith("/PKCS1PADDING") || algorithm.endsWith("/OAEPPADDING")
+                || algorithm.contains("/OAEPWITH");
+    }
+
+    private static Map<String, Key> ENCRYPT_KEYS = new HashMap<String, Key>();
+
+    /**
+     * Returns the key meant for enciphering for {@code algorithm}.
+     */
+    private synchronized static Key getEncryptKey(String algorithm) {
+        Key key = ENCRYPT_KEYS.get(algorithm);
+        if (key != null) {
+            return key;
+        }
+        try {
+            if (algorithm.startsWith("RSA")) {
+                KeyFactory kf = KeyFactory.getInstance("RSA");
+                RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus,
+                        RSA_2048_publicExponent);
+                key = kf.generatePublic(keySpec);
+            } else if (isPBE(algorithm)) {
+                SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
+                key = skf.generateSecret(new PBEKeySpec("secret".toCharArray()));
+            } else {
+                KeyGenerator kg = KeyGenerator.getInstance(getBaseAlgorithm(algorithm));
+                if (algorithm.startsWith("AES_256/")) {
+                    // This is the 256-bit constrained version, so we have to switch from the
+                    // default of 128-bit keys.
+                    kg.init(256);
+                }
+                key = kg.generateKey();
+            }
+        } catch (Exception e) {
+            throw new AssertionError("Error generating keys for test setup", e);
+        }
+        ENCRYPT_KEYS.put(algorithm, key);
+        return key;
+    }
+
+    private static Map<String, Key> DECRYPT_KEYS = new HashMap<String, Key>();
+
+    /**
+     * Returns the key meant for deciphering for {@code algorithm}.
+     */
+    private synchronized static Key getDecryptKey(String algorithm) {
+        Key key = DECRYPT_KEYS.get(algorithm);
+        if (key != null) {
+            return key;
+        }
+        try {
+            if (algorithm.startsWith("RSA")) {
+                KeyFactory kf = KeyFactory.getInstance("RSA");
+                RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(RSA_2048_modulus,
+                        RSA_2048_publicExponent, RSA_2048_privateExponent, RSA_2048_primeP,
+                        RSA_2048_primeQ, RSA_2048_primeExponentP, RSA_2048_primeExponentQ,
+                        RSA_2048_crtCoefficient);
+                key = kf.generatePrivate(keySpec);
+            } else {
+                assertFalse(algorithm, isAsymmetric(algorithm));
+                key = getEncryptKey(algorithm);
+            }
+        } catch (Exception e) {
+            throw new AssertionError("Error generating keys for test setup", e);
+        }
+        DECRYPT_KEYS.put(algorithm, key);
+        return key;
+    }
+
+    private static Map<String, Integer> EXPECTED_BLOCK_SIZE = new HashMap<String, Integer>();
+    static {
+        setExpectedBlockSize("AES", 16);
+        setExpectedBlockSize("AES/CBC/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES/CBC/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES/CBC/NOPADDING", 16);
+        setExpectedBlockSize("AES/CFB/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES/CFB/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES/CFB/NOPADDING", 16);
+        setExpectedBlockSize("AES/CTR/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES/CTR/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES/CTR/NOPADDING", 16);
+        setExpectedBlockSize("AES/CTS/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES/CTS/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES/CTS/NOPADDING", 16);
+        setExpectedBlockSize("AES/ECB/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES/ECB/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES/ECB/NOPADDING", 16);
+        setExpectedBlockSize("AES/GCM/NOPADDING", 16);
+        setExpectedBlockSize("AES/GCM-SIV/NOPADDING", 16);
+        setExpectedBlockSize("AES/OFB/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES/OFB/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES/OFB/NOPADDING", 16);
+        setExpectedBlockSize("AES_128/CBC/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES_128/CBC/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES_128/CBC/NOPADDING", 16);
+        setExpectedBlockSize("AES_128/ECB/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES_128/ECB/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES_128/ECB/NOPADDING", 16);
+        setExpectedBlockSize("AES_128/GCM/NOPADDING", 16);
+        setExpectedBlockSize("AES_128/GCM-SIV/NOPADDING", 16);
+        setExpectedBlockSize("AES_256/CBC/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES_256/CBC/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES_256/CBC/NOPADDING", 16);
+        setExpectedBlockSize("AES_256/ECB/PKCS5PADDING", 16);
+        setExpectedBlockSize("AES_256/ECB/PKCS7PADDING", 16);
+        setExpectedBlockSize("AES_256/ECB/NOPADDING", 16);
+        setExpectedBlockSize("AES_256/GCM/NOPADDING", 16);
+        setExpectedBlockSize("AES_256/GCM-SIV/NOPADDING", 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) {
+            setExpectedBlockSize("AESWRAP", 16);
+        } else {
+            setExpectedBlockSize("AESWRAP", 0);
+        }
+
+        setExpectedBlockSize("ARC4", 0);
+        setExpectedBlockSize("ARCFOUR", 0);
+        setExpectedBlockSize("CHACHA20", 0);
+        setExpectedBlockSize("CHACHA20/POLY1305/NOPADDING", 0);
+        setExpectedBlockSize("PBEWITHSHAAND40BITRC4", 0);
+        setExpectedBlockSize("PBEWITHSHAAND128BITRC4", 0);
+
+        setExpectedBlockSize("BLOWFISH", 8);
+
+        setExpectedBlockSize("DES", 8);
+        setExpectedBlockSize("PBEWITHMD5ANDDES", 8);
+        setExpectedBlockSize("PBEWITHSHA1ANDDES", 8);
+
+        setExpectedBlockSize("DESEDE", 8);
+        setExpectedBlockSize("DESEDE/CBC/PKCS5PADDING", 8);
+        setExpectedBlockSize("DESEDE/CBC/PKCS7PADDING", 8);
+        setExpectedBlockSize("DESEDE/CBC/NOPADDING", 8);
+        setExpectedBlockSize("DESEDE/CFB/PKCS5PADDING", 8);
+        setExpectedBlockSize("DESEDE/CFB/PKCS7PADDING", 8);
+        setExpectedBlockSize("DESEDE/CFB/NOPADDING", 8);
+        setExpectedBlockSize("DESEDE/CTR/PKCS5PADDING", 8);
+        setExpectedBlockSize("DESEDE/CTR/PKCS7PADDING", 8);
+        setExpectedBlockSize("DESEDE/CTR/NOPADDING", 8);
+        setExpectedBlockSize("DESEDE/CTS/PKCS5PADDING", 8);
+        setExpectedBlockSize("DESEDE/CTS/PKCS7PADDING", 8);
+        setExpectedBlockSize("DESEDE/CTS/NOPADDING", 8);
+        setExpectedBlockSize("DESEDE/ECB/PKCS5PADDING", 8);
+        setExpectedBlockSize("DESEDE/ECB/PKCS7PADDING", 8);
+        setExpectedBlockSize("DESEDE/ECB/NOPADDING", 8);
+        setExpectedBlockSize("DESEDE/OFB/PKCS5PADDING", 8);
+        setExpectedBlockSize("DESEDE/OFB/PKCS7PADDING", 8);
+        setExpectedBlockSize("DESEDE/OFB/NOPADDING", 8);
+        setExpectedBlockSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
+        setExpectedBlockSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
+        setExpectedBlockSize("PBEWITHMD5ANDTRIPLEDES", 8);
+        setExpectedBlockSize("PBEWITHSHA1ANDDESEDE", 8);
+
+
+        if (StandardNames.IS_RI) {
+            setExpectedBlockSize("DESEDEWRAP", 8);
+        } else {
+            setExpectedBlockSize("DESEDEWRAP", 0);
+        }
+
+        setExpectedBlockSize("RSA", "SunJCE",0);
+        setExpectedBlockSize("RSA/ECB/NoPadding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/PKCS1Padding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/OAEPPadding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", "SunJCE", 0);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", "SunJCE", 0);
+
+        setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 245);
+
+        // 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);
+
+        setExpectedBlockSize("RSA", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 256);
+
+        // OAEP padding modes change the output and block size. SHA-1 is the default.
+        setExpectedBlockSize("RSA/ECB/OAEPPadding", Cipher.ENCRYPT_MODE, 214);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.ENCRYPT_MODE, 214);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.ENCRYPT_MODE, 198);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.ENCRYPT_MODE, 190);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.ENCRYPT_MODE, 158);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.ENCRYPT_MODE, 126);
+
+        setExpectedBlockSize("RSA/ECB/OAEPPadding", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+        setExpectedBlockSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+    }
+
+    private static String modeKey(String algorithm, int mode) {
+        return algorithm + ":" + mode;
+    }
+
+    private static String modeProviderKey(String algorithm, int mode, String provider) {
+        return algorithm + ":" + mode + ":" + provider;
+    }
+
+    private static String providerKey(String algorithm, String provider) {
+        return algorithm + ":" + 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 void setExpectedSize(Map<String, Integer> map,
+            String algorithm, String provider, int value) {
+        setExpectedSize(map, providerKey(algorithm, provider), value);
+    }
+
+    private static int getExpectedSize(Map<String, Integer> map, String algorithm, int mode, String provider) {
+        algorithm = algorithm.toUpperCase(Locale.US);
+        provider = provider.toUpperCase(Locale.US);
+        Integer expected = map.get(modeProviderKey(algorithm, mode, provider));
+        if (expected != null) {
+            return expected;
+        }
+        expected = map.get(providerKey(algorithm, provider));
+        if (expected != null) {
+            return expected;
+        }
+        expected = map.get(modeKey(algorithm, mode));
+        if (expected != null) {
+            return expected;
+        }
+        expected = map.get(algorithm);
+        assertNotNull("Algorithm " + algorithm + " with mode " + mode + " and provider " + provider
+                      + " 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, String provider, int value) {
+        setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, provider, 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 {
+        setExpectedOutputSize("AES/CBC/NOPADDING", 0);
+        setExpectedOutputSize("AES/CFB/NOPADDING", 0);
+        setExpectedOutputSize("AES/CTR/NOPADDING", 0);
+        setExpectedOutputSize("AES/CTS/NOPADDING", 0);
+        setExpectedOutputSize("AES/ECB/NOPADDING", 0);
+        setExpectedOutputSize("AES/OFB/NOPADDING", 0);
+        setExpectedOutputSize("AES_128/CBC/NOPADDING", 0);
+        setExpectedOutputSize("AES_128/ECB/NOPADDING", 0);
+        setExpectedOutputSize("AES_256/CBC/NOPADDING", 0);
+        setExpectedOutputSize("AES_256/ECB/NOPADDING", 0);
+
+        setExpectedOutputSize("AES", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/GCM/NOPADDING", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8);
+        setExpectedOutputSize(
+                "AES/GCM-SIV/NOPADDING", Cipher.ENCRYPT_MODE, GCM_SIV_TAG_SIZE_BITS / 8);
+        setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_128/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_128/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_128/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_128/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_128/GCM/NOPADDING", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8);
+        setExpectedOutputSize(
+                "AES_128/GCM-SIV/NOPADDING", Cipher.ENCRYPT_MODE, GCM_SIV_TAG_SIZE_BITS / 8);
+        setExpectedOutputSize("AES_256/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_256/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_256/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_256/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
+        setExpectedOutputSize("AES_256/GCM/NOPADDING", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8);
+        setExpectedOutputSize(
+                "AES_256/GCM-SIV/NOPADDING", Cipher.ENCRYPT_MODE, GCM_SIV_TAG_SIZE_BITS / 8);
+        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);
+        // AndroidOpenSSL returns zero for the non-block ciphers
+        setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
+
+        setExpectedOutputSize("AES", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/GCM/NOPADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/GCM-SIV/NOPADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_128/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_128/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_128/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_128/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_128/GCM/NOPADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_128/GCM-SIV/NOPADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_256/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_256/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_256/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_256/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_256/GCM/NOPADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("AES_256/GCM-SIV/NOPADDING", 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);
+        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+
+        if (StandardNames.IS_RI) {
+            setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
+            setExpectedOutputSize("AESWRAP", Cipher.UNWRAP_MODE, 0);
+        } else {
+            setExpectedOutputSize("AESWRAP", -1);
+        }
+
+        setExpectedOutputSize("ARC4", 0);
+        setExpectedOutputSize("ARCFOUR", 0);
+        setExpectedOutputSize("CHACHA20", 0);
+        setExpectedOutputSize("CHACHA20/POLY1305/NOPADDING", 0);
+        setExpectedOutputSize("PBEWITHSHAAND40BITRC4", 0);
+        setExpectedOutputSize("PBEWITHSHAAND128BITRC4", 0);
+
+        setExpectedOutputSize("BLOWFISH", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("BLOWFISH", Cipher.DECRYPT_MODE, 0);
+
+        setExpectedOutputSize("DES", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.ENCRYPT_MODE, 8);
+
+        setExpectedOutputSize("DES", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.DECRYPT_MODE, 0);
+
+        setExpectedOutputSize("DESEDE/CBC/NOPADDING", 0);
+        setExpectedOutputSize("DESEDE/CFB/NOPADDING", 0);
+        setExpectedOutputSize("DESEDE/CTR/NOPADDING", 0);
+        setExpectedOutputSize("DESEDE/CTS/NOPADDING", 0);
+        setExpectedOutputSize("DESEDE/ECB/NOPADDING", 0);
+        setExpectedOutputSize("DESEDE/OFB/NOPADDING", 0);
+
+        setExpectedOutputSize("DESEDE", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+        setExpectedOutputSize("DESEDE/OFB/PKCS7PADDING", 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("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CTR/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+        setExpectedOutputSize("DESEDE/OFB/PKCS7PADDING", 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) {
+            setExpectedOutputSize("DESEDEWRAP", Cipher.WRAP_MODE, 16);
+            setExpectedOutputSize("DESEDEWRAP", Cipher.UNWRAP_MODE, 0);
+        } else {
+            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);
+        setExpectedOutputSize("RSA/ECB/OAEPPadding", Cipher.DECRYPT_MODE, 256);
+
+        // SunJCE returns the full for size even when PKCS1Padding is specified
+        setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, "SunJCE", 256);
+
+        // 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);
+
+        // OAEP padding modes change the output and block size. SHA-1 is the default.
+        setExpectedOutputSize("RSA/ECB/OAEPPadding", Cipher.DECRYPT_MODE, 214);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.DECRYPT_MODE, 214);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.DECRYPT_MODE, 198);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.DECRYPT_MODE, 190);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.DECRYPT_MODE, 158);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.DECRYPT_MODE, 126);
+
+        setExpectedOutputSize("RSA/ECB/OAEPPadding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+    }
+
+    private static void setExpectedOutputSize(String algorithm, int value) {
+        setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, value);
+    }
+
+    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 };
+    private static byte[] SIXTEEN_BYTE_BLOCK_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c, 0x00,
+                                                                       0x00, 0x00, 0x00, 0x00,
+                                                                       0x00, 0x00, 0x00, 0x00,
+                                                                       0x00, 0x00, 0x00, 0x00 };
+    private static byte[] EIGHT_BYTE_BLOCK_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c, 0x00,
+                                                                     0x00, 0x00, 0x00, 0x00 };
+    private static byte[] PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT = new byte[] {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0x0b, 0x0c
+    };
+    private static byte[] PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT = new byte[] {
+        (byte) 0x00, (byte) 0x01, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c
+    };
+    private static byte[] PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT = new byte[] {
+        (byte) 0x00, (byte) 0x02, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c
+    };
+
+
+    private static byte[] getActualPlainText(String algorithm) {
+        // Block mode AES with NoPadding needs to match underlying block size
+        if (algorithm.equals("AES")
+            || algorithm.equals("AES/CBC/NOPADDING")
+            || algorithm.equals("AES/CTS/NOPADDING")
+            || algorithm.equals("AES/ECB/NOPADDING")
+            || algorithm.equals("AES_128/CBC/NOPADDING")
+            || algorithm.equals("AES_128/ECB/NOPADDING")
+            || algorithm.equals("AES_256/CBC/NOPADDING")
+            || algorithm.equals("AES_256/ECB/NOPADDING")) {
+            return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
+        }
+        if (algorithm.equals("DESEDE")
+            || algorithm.equals("DESEDE/CBC/NOPADDING")
+            || algorithm.equals("DESEDE/ECB/NOPADDING")) {
+            return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
+        }
+        return ORIGINAL_PLAIN_TEXT;
+    }
+
+    private static byte[] getExpectedPlainText(String algorithm, String provider) {
+        // Block mode AES with NoPadding needs to match underlying block size
+        if (algorithm.equals("AES")
+            || algorithm.equals("AES/CBC/NOPADDING")
+            || algorithm.equals("AES/CTS/NOPADDING")
+            || algorithm.equals("AES/ECB/NOPADDING")
+            || algorithm.equals("AES_128/CBC/NOPADDING")
+            || algorithm.equals("AES_128/ECB/NOPADDING")
+            || algorithm.equals("AES_256/CBC/NOPADDING")
+            || algorithm.equals("AES_256/ECB/NOPADDING")) {
+            return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
+        }
+        if (algorithm.equals("DESEDE")
+            || algorithm.equals("DESEDE/CBC/NOPADDING")
+            || algorithm.equals("DESEDE/ECB/NOPADDING")) {
+            return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
+        }
+        // BC strips the leading 0 for us even when NoPadding is specified
+        if (!provider.equals("BC") && algorithm.equals("RSA/ECB/NOPADDING")) {
+            return PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT;
+        }
+        return ORIGINAL_PLAIN_TEXT;
+    }
+
+    private static AlgorithmParameterSpec getEncryptAlgorithmParameterSpec(String algorithm) {
+        if (isPBE(algorithm)) {
+            final byte[] salt = new byte[8];
+            new SecureRandom().nextBytes(salt);
+            return new PBEParameterSpec(salt, 1024);
+        }
+        if (algorithm.equals("AES/GCM/NOPADDING")
+            || algorithm.equals("AES_128/GCM/NOPADDING")
+            || algorithm.equals("AES_256/GCM/NOPADDING")) {
+            final byte[] iv = new byte[12];
+            new SecureRandom().nextBytes(iv);
+            return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
+        }
+        if (algorithm.equals("AES/GCM-SIV/NOPADDING")
+                || algorithm.equals("AES_128/GCM-SIV/NOPADDING")
+                || algorithm.equals("AES_256/GCM-SIV/NOPADDING")) {
+            final byte[] iv = new byte[12];
+            new SecureRandom().nextBytes(iv);
+            return new GCMParameterSpec(GCM_SIV_TAG_SIZE_BITS, iv);
+        }
+        if (algorithm.equals("AES/CBC/NOPADDING")
+            || algorithm.equals("AES/CBC/PKCS5PADDING")
+            || algorithm.equals("AES/CBC/PKCS7PADDING")
+            || algorithm.equals("AES/CFB/NOPADDING")
+            || algorithm.equals("AES/CTR/NOPADDING")
+            || algorithm.equals("AES/CTS/NOPADDING")
+            || algorithm.equals("AES/OFB/NOPADDING")
+            || algorithm.equals("AES_128/CBC/NOPADDING")
+            || algorithm.equals("AES_128/CBC/PKCS5PADDING")
+            || algorithm.equals("AES_128/CBC/PKCS7PADDING")
+            || algorithm.equals("AES_256/CBC/NOPADDING")
+            || algorithm.equals("AES_256/CBC/PKCS5PADDING")
+            || algorithm.equals("AES_256/CBC/PKCS7PADDING")) {
+            final byte[] iv = new byte[16];
+            new SecureRandom().nextBytes(iv);
+            return new IvParameterSpec(iv);
+        }
+        if (algorithm.equals("DESEDE/CBC/NOPADDING")
+            || algorithm.equals("DESEDE/CBC/PKCS5PADDING")
+            || algorithm.equals("DESEDE/CBC/PKCS7PADDING")
+            || algorithm.equals("DESEDE/CFB/NOPADDING")
+            || algorithm.equals("DESEDE/CTR/NOPADDING")
+            || algorithm.equals("DESEDE/CTS/NOPADDING")
+            || algorithm.equals("DESEDE/OFB/NOPADDING")) {
+            final byte[] iv = new byte[8];
+            new SecureRandom().nextBytes(iv);
+            return new IvParameterSpec(iv);
+        }
+        if (algorithm.equals("CHACHA20")
+            || algorithm.equals("CHACHA20/POLY1305/NOPADDING")) {
+            final byte[] iv = new byte[12];
+            new SecureRandom().nextBytes(iv);
+            return new IvParameterSpec(iv);
+        }
+        return null;
+    }
+
+    private static AlgorithmParameterSpec getDecryptAlgorithmParameterSpec(AlgorithmParameterSpec encryptSpec,
+                                                                           Cipher encryptCipher) {
+        String algorithm = encryptCipher.getAlgorithm().toUpperCase(Locale.US);
+        if (isPBE(algorithm)) {
+            return encryptSpec;
+        }
+        if (isOnlyWrappingAlgorithm(algorithm)) {
+            return null;
+        }
+        byte[] iv = encryptCipher.getIV();
+        if (iv != null) {
+            if ("AES/GCM/NOPADDING".equals(algorithm)
+                    || "AES_128/GCM/NOPADDING".equals(algorithm)
+                    || "AES_256/GCM/NOPADDING".equals(algorithm)) {
+                return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
+            }
+            if ("AES/GCM-SIV/NOPADDING".equals(algorithm)
+                    || "AES_128/GCM-SIV/NOPADDING".equals(algorithm)
+                    || "AES_256/GCM-SIV/NOPADDING".equals(algorithm)) {
+                return new GCMParameterSpec(GCM_SIV_TAG_SIZE_BITS, iv);
+            }
+            return new IvParameterSpec(iv);
+        }
+        return null;
+    }
+
+    /*
+     * This must be below everything else to make sure the other static blocks
+     * have run first.
+     */
+    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),
+                                                   getEncryptAlgorithmParameterSpec(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;
+    }
+
+    @Test
+    public void test_getInstance() throws Exception {
+        final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
+        PrintStream out = new PrintStream(errBuffer);
+
+        Set<String> seenBaseCipherNames = new HashSet<String>();
+        Set<String> seenCiphersWithModeAndPadding = new HashSet<String>();
+
+        Provider[] providers = Security.getProviders();
+        for (Provider provider : providers) {
+            Set<Provider.Service> services = provider.getServices();
+            for (Provider.Service service : services) {
+                String type = service.getType();
+                if (!type.equals("Cipher")) {
+                    continue;
+                }
+
+                String algorithm = service.getAlgorithm().toUpperCase(Locale.US);
+
+                /*
+                 * Any specific modes and paddings aren't tested directly here,
+                 * but we need to make sure we see the bare algorithm from some
+                 * provider. We will test each mode specifically when we get the
+                 * base cipher.
+                 */
+                final int firstSlash = algorithm.indexOf('/');
+                if (firstSlash == -1) {
+                    seenBaseCipherNames.add(algorithm);
+                } else {
+                    final String baseCipherName = algorithm.substring(0, firstSlash);
+                    if (!seenBaseCipherNames.contains(baseCipherName)
+                            && !(baseCipherName.equals("AES_128")
+                                || baseCipherName.equals("AES_192")
+                                || baseCipherName.equals("AES_256"))) {
+                        seenCiphersWithModeAndPadding.add(baseCipherName);
+                    }
+                    if (!Conscrypt.isConscrypt(provider)) {
+                        continue;
+                    }
+                }
+
+                if (provider.getName().equals("SunJCE")) {
+                    // The SunJCE provider acts in numerous idiosyncratic ways that don't
+                    // match any other provider.  Examples include returning non-null IVs
+                    // when no IV was provided on init, NullPointerExceptions when null
+                    // SecureRandoms are supplied (but only to PBE ciphers), and not
+                    // supplying KeyGenerators for some algorithms.  We aren't sufficiently
+                    // interested in verifying this provider's behavior to adapt the
+                    // tests and Oracle presumably tests them well anyway, so just skip
+                    // verifying them.
+                    continue;
+                }
+
+                try {
+                    test_Cipher_Algorithm(provider, algorithm);
+                } catch (Throwable e) {
+                    out.append("Error encountered checking " + algorithm
+                               + " with provider " + provider.getName() + "\n");
+                    e.printStackTrace(out);
+                }
+
+                Set<String> modes = StandardNames.getModesForCipher(algorithm);
+                if (modes != null) {
+                    for (String mode : modes) {
+                        Set<String> paddings = StandardNames.getPaddingsForCipher(algorithm);
+                        if (paddings != null) {
+                            for (String padding : paddings) {
+                                final String algorithmName = algorithm + "/" + mode + "/" + padding;
+                                try {
+                                    test_Cipher_Algorithm(provider, algorithmName);
+                                } catch (Throwable e) {
+                                    out.append("Error encountered checking " + algorithmName
+                                               + " with provider " + provider.getName() + "\n");
+                                    e.printStackTrace(out);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        seenCiphersWithModeAndPadding.removeAll(seenBaseCipherNames);
+        assertEquals("Ciphers seen with mode and padding but not base cipher",
+                Collections.EMPTY_SET, seenCiphersWithModeAndPadding);
+
+        out.flush();
+        if (errBuffer.size() > 0) {
+            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
+        }
+    }
+
+    private void test_Cipher_Algorithm(Provider provider, String algorithm) throws Exception {
+        if (algorithm.equals("RSA") && provider.getName().equals("BC")) {
+            // http://b/9097343 BC's Cipher.RSA defaults to NoPadding
+            // which makes it fail the key wrapping test if the
+            // generated AES key to wrap starts with a leading
+            // zero. For the purposes of the test, use the same
+            // default behavior as the RI. Real code really should
+            // specify the exact mode and padding they need and not
+            // rely on defaults. http://b/9097343
+            algorithm = "RSA/ECB/PKCS1Padding";
+        }
+
+        // Cipher.getInstance(String)
+        Cipher c1 = Cipher.getInstance(algorithm);
+        if (provider.equals(c1.getProvider())) {
+            assertEquals(algorithm, c1.getAlgorithm());
+            test_Cipher(c1);
+        }
+
+        // Cipher.getInstance(String, Provider)
+        Cipher c2 = Cipher.getInstance(algorithm, provider);
+        assertEquals(algorithm, c2.getAlgorithm());
+        assertEquals(provider, c2.getProvider());
+        test_Cipher(c2);
+
+        // Cipher.getInstance(String, String)
+        Cipher c3 = Cipher.getInstance(algorithm, provider.getName());
+        assertEquals(algorithm, c3.getAlgorithm());
+        assertEquals(provider, c3.getProvider());
+        test_Cipher(c3);
+    }
+
+    private void test_Cipher(Cipher c) throws Exception {
+        String algorithm = c.getAlgorithm().toUpperCase(Locale.US);
+        String providerName = c.getProvider().getName();
+        if (!isSupported(algorithm, providerName)) {
+            return;
+        }
+        String cipherID = algorithm + ":" + providerName;
+
+        try {
+            c.getOutputSize(0);
+            fail("getOutputSize() should throw if called before Cipher initialization");
+        } catch (IllegalStateException expected) {
+        }
+
+        // TODO: test keys from different factories (e.g. OpenSSLRSAPrivateKey vs BCRSAPrivateKey)
+        Key encryptKey = getEncryptKey(algorithm);
+
+        AlgorithmParameterSpec encryptSpec = getEncryptAlgorithmParameterSpec(algorithm);
+        int encryptMode = getEncryptMode(algorithm);
+
+        // Bouncycastle doesn't return a default PBEParameterSpec
+        if (isPBE(algorithm) && !"BC".equals(providerName)) {
+            assertNotNull(cipherID + " getParameters()", c.getParameters());
+            assertNotNull(c.getParameters().getParameterSpec(PBEParameterSpec.class));
+        } else {
+            assertNull(cipherID + " getParameters()", c.getParameters());
+        }
+        try {
+            assertNull(cipherID + " getIV()", c.getIV());
+        } catch (NullPointerException e) {
+            // Bouncycastle apparently has a bug here with AESWRAP, et al.
+            if (!("BC".equals(providerName) && isOnlyWrappingAlgorithm(algorithm))) {
+                throw e;
+            }
+        }
+
+        test_Cipher_init_NullParameters(c, encryptMode, encryptKey);
+
+        c.init(encryptMode, encryptKey, encryptSpec);
+        assertEquals(cipherID + " getBlockSize() encryptMode",
+                getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize());
+        assertTrue(cipherID + " getOutputSize(0) encryptMode",
+                getExpectedOutputSize(algorithm, encryptMode, providerName) <= c.getOutputSize(0));
+        if ((algorithm.endsWith("/PKCS5PADDING") || algorithm.endsWith("/PKCS7PADDING"))
+                && isStreamMode(algorithm)) {
+            assertEquals(getExpectedOutputSize(algorithm, encryptMode, providerName),
+                    c.doFinal(new byte[1]).length);
+        }
+
+        if (isPBE(algorithm)) {
+            if (algorithm.endsWith("RC4")) {
+                assertNull(cipherID + " getIV()", c.getIV());
+            } else {
+                assertNotNull(cipherID + " getIV()", c.getIV());
+            }
+        } else if (encryptSpec instanceof IvParameterSpec) {
+            assertEquals(cipherID + " getIV()",
+                    Arrays.toString(((IvParameterSpec) encryptSpec).getIV()),
+                    Arrays.toString(c.getIV()));
+        } else if (encryptSpec instanceof GCMParameterSpec) {
+            assertNotNull(c.getIV());
+            assertEquals(cipherID + " getIV()",
+                    Arrays.toString(((GCMParameterSpec) encryptSpec).getIV()),
+                    Arrays.toString(c.getIV()));
+        } else {
+            try {
+                assertNull(cipherID + " getIV()", c.getIV());
+            } catch (NullPointerException e) {
+                // Bouncycastle apparently has a bug here with AESWRAP, et al.
+                if (!("BC".equals(providerName) && isOnlyWrappingAlgorithm(algorithm))) {
+                    throw e;
+                }
+            }
+        }
+
+        AlgorithmParameters encParams = c.getParameters();
+        assertCorrectAlgorithmParameters(providerName, cipherID, encryptSpec, encParams);
+
+        AlgorithmParameterSpec decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
+        int decryptMode = getDecryptMode(algorithm);
+
+        Key decryptKey = getDecryptKey(algorithm);
+
+        test_Cipher_init_Decrypt_NullParameters(c, decryptMode, decryptKey, decryptSpec != null);
+
+        c.init(decryptMode, decryptKey, decryptSpec);
+        assertEquals(cipherID + " getBlockSize() decryptMode",
+                     getExpectedBlockSize(algorithm, decryptMode, providerName), c.getBlockSize());
+        assertEquals(cipherID + " getOutputSize(0) decryptMode",
+                     getExpectedOutputSize(algorithm, decryptMode, providerName), c.getOutputSize(0));
+
+        if (isPBE(algorithm)) {
+            if (algorithm.endsWith("RC4")) {
+                assertNull(cipherID + " getIV()", c.getIV());
+            } else {
+                assertNotNull(cipherID + " getIV()", c.getIV());
+            }
+        } else if (decryptSpec instanceof IvParameterSpec) {
+            assertEquals(cipherID + " getIV()",
+                    Arrays.toString(((IvParameterSpec) decryptSpec).getIV()),
+                    Arrays.toString(c.getIV()));
+        } else if (decryptSpec instanceof GCMParameterSpec) {
+            assertNotNull(c.getIV());
+            assertEquals(cipherID + " getIV()",
+                    Arrays.toString(((GCMParameterSpec) decryptSpec).getIV()),
+                    Arrays.toString(c.getIV()));
+        } else {
+            try {
+                assertNull(cipherID + " getIV()", c.getIV());
+            } catch (NullPointerException e) {
+                // Bouncycastle apparently has a bug here with AESWRAP, et al.
+                if (!("BC".equals(providerName) && isOnlyWrappingAlgorithm(algorithm))) {
+                    throw e;
+                }
+            }
+        }
+
+        AlgorithmParameters decParams = c.getParameters();
+        assertCorrectAlgorithmParameters(providerName, cipherID, decryptSpec, decParams);
+
+        assertNull(cipherID, c.getExemptionMechanism());
+
+        // Test wrapping a key.  Every cipher should be able to wrap. Except those that can't.
+        /* Bouncycastle is broken for wrapping because getIV() fails. */
+        if (isSupportedForWrapping(algorithm) && !providerName.equals("BC")) {
+            // Generate a small SecretKey for AES.
+            KeyGenerator kg = KeyGenerator.getInstance("AES");
+            kg.init(128);
+            SecretKey sk = kg.generateKey();
+
+            // Wrap it.  Use a new encrypt spec so that AEAD algorithms that prohibit IV reuse
+            // don't complain.
+            encryptSpec = getEncryptAlgorithmParameterSpec(algorithm);
+            c.init(Cipher.WRAP_MODE, encryptKey, encryptSpec);
+            byte[] cipherText = c.wrap(sk);
+
+            // Unwrap it
+            c.init(Cipher.UNWRAP_MODE, decryptKey, getDecryptAlgorithmParameterSpec(encryptSpec, c));
+            Key decryptedKey = c.unwrap(cipherText, sk.getAlgorithm(), Cipher.SECRET_KEY);
+
+            assertEquals(cipherID
+                    + " sk.getAlgorithm()=" + sk.getAlgorithm()
+                    + " decryptedKey.getAlgorithm()=" + decryptedKey.getAlgorithm()
+                    + " encryptKey.getEncoded()=" + Arrays.toString(sk.getEncoded())
+                    + " decryptedKey.getEncoded()=" + Arrays.toString(decryptedKey.getEncoded()),
+                    sk, decryptedKey);
+        }
+
+        if (!isOnlyWrappingAlgorithm(algorithm)) {
+            // Use a new encrypt spec so that AEAD algorithms that prohibit IV reuse don't complain
+            encryptSpec = getEncryptAlgorithmParameterSpec(algorithm);
+            c.init(Cipher.ENCRYPT_MODE, encryptKey, encryptSpec);
+            if (isAEAD(algorithm)) {
+                c.updateAAD(new byte[24]);
+            }
+            byte[] cipherText = c.doFinal(getActualPlainText(algorithm));
+            if (!isRandomizedEncryption(algorithm) && !isAEAD(algorithm)) {
+                byte[] cipherText2 = c.doFinal(getActualPlainText(algorithm));
+                assertEquals(cipherID, Arrays.toString(cipherText), Arrays.toString(cipherText2));
+            }
+            decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
+            c.init(Cipher.DECRYPT_MODE, decryptKey, decryptSpec);
+            if (isAEAD(algorithm)) {
+                c.updateAAD(new byte[24]);
+            }
+            byte[] decryptedPlainText = c.doFinal(cipherText);
+            assertEquals(cipherID,
+                         Arrays.toString(getExpectedPlainText(algorithm, providerName)),
+                         Arrays.toString(decryptedPlainText));
+            if (isAEAD(algorithm)) {
+                c.updateAAD(new byte[24]);
+            }
+            byte[] decryptedPlainText2 = c.doFinal(cipherText);
+            assertEquals(cipherID,
+                         Arrays.toString(decryptedPlainText),
+                         Arrays.toString(decryptedPlainText2));
+
+            // Use a new encrypt spec so that AEAD algorithms that prohibit IV reuse don't complain
+            encryptSpec = getEncryptAlgorithmParameterSpec(algorithm);
+            test_Cipher_ShortBufferException(c, algorithm, Cipher.ENCRYPT_MODE, encryptSpec,
+                    encryptKey, getActualPlainText(algorithm));
+            decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
+            test_Cipher_ShortBufferException(c, algorithm, Cipher.DECRYPT_MODE, decryptSpec,
+                    decryptKey, cipherText);
+
+            test_Cipher_aborted_doFinal(c, algorithm, providerName, encryptKey, decryptKey);
+        }
+    }
+
+    private void assertCorrectAlgorithmParameters(String providerName, String cipherID,
+            final AlgorithmParameterSpec spec, AlgorithmParameters params)
+            throws InvalidParameterSpecException, Exception {
+        if (spec == null) {
+            return;
+        }
+
+        // Bouncycastle has a bug where PBE algorithms sometimes return null parameters.
+        if ("BC".equals(providerName) && isPBE(cipherID) && params == null) {
+            return;
+        }
+
+        assertNotNull(cipherID + " getParameters() should not be null", params);
+
+        if (spec instanceof GCMParameterSpec) {
+            GCMParameterSpec gcmDecryptSpec = params.getParameterSpec(GCMParameterSpec.class);
+            assertEquals(cipherID + " getIV()", Arrays.toString(((GCMParameterSpec) spec).getIV()),
+                    Arrays.toString(gcmDecryptSpec.getIV()));
+            assertEquals(cipherID + " getTLen()", ((GCMParameterSpec) spec).getTLen(),
+                    gcmDecryptSpec.getTLen());
+        } else if (spec instanceof IvParameterSpec) {
+            IvParameterSpec ivDecryptSpec = params.getParameterSpec(IvParameterSpec.class);
+            assertEquals(cipherID + " getIV()", Arrays.toString(((IvParameterSpec) spec).getIV()),
+                    Arrays.toString(ivDecryptSpec.getIV()));
+        } else if (spec instanceof PBEParameterSpec) {
+            // Bouncycastle seems to be undecided about whether it returns this
+            // or not
+            if (!"BC".equals(providerName)) {
+                assertNotNull(cipherID + " getParameters()", params);
+            }
+        } else if (spec instanceof OAEPParameterSpec) {
+            assertOAEPParametersEqual((OAEPParameterSpec) spec,
+                    params.getParameterSpec(OAEPParameterSpec.class));
+        } else {
+            fail("Unhandled algorithm specification class: " + spec.getClass().getName());
+        }
+    }
+
+    private static void assertOAEPParametersEqual(OAEPParameterSpec expectedOaepSpec,
+            OAEPParameterSpec actualOaepSpec) throws Exception {
+        assertEquals(expectedOaepSpec.getDigestAlgorithm(), actualOaepSpec.getDigestAlgorithm());
+
+        assertEquals(expectedOaepSpec.getMGFAlgorithm(), actualOaepSpec.getMGFAlgorithm());
+        if ("MGF1".equals(expectedOaepSpec.getMGFAlgorithm())) {
+            MGF1ParameterSpec expectedMgf1Spec = (MGF1ParameterSpec) expectedOaepSpec
+                    .getMGFParameters();
+            MGF1ParameterSpec actualMgf1Spec = (MGF1ParameterSpec) actualOaepSpec
+                    .getMGFParameters();
+            assertEquals(expectedMgf1Spec.getDigestAlgorithm(),
+                    actualMgf1Spec.getDigestAlgorithm());
+        } else {
+            fail("Unknown MGF algorithm: " + expectedOaepSpec.getMGFAlgorithm());
+        }
+
+        if (expectedOaepSpec.getPSource() instanceof PSource.PSpecified
+                && actualOaepSpec.getPSource() instanceof PSource.PSpecified) {
+            assertEquals(Arrays.toString(
+                                 ((PSource.PSpecified) expectedOaepSpec.getPSource()).getValue()),
+                    Arrays.toString(((PSource.PSpecified) actualOaepSpec.getPSource()).getValue()));
+        } else {
+            fail("Unknown PSource type");
+        }
+    }
+
+    /**
+     * Try various .init(...) calls with null parameters to make sure it is
+     * handled.
+     */
+    private void test_Cipher_init_NullParameters(Cipher c, int encryptMode, Key encryptKey)
+            throws Exception {
+        try {
+            c.init(encryptMode, encryptKey, (AlgorithmParameterSpec) null);
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!isPBE(c.getAlgorithm())) {
+                throw e;
+            }
+        }
+
+        try {
+            c.init(encryptMode, encryptKey, (AlgorithmParameterSpec) null, (SecureRandom) null);
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!isPBE(c.getAlgorithm())) {
+                throw e;
+            }
+        }
+
+        try {
+            c.init(encryptMode, encryptKey, (AlgorithmParameters) null);
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!isPBE(c.getAlgorithm())) {
+                throw e;
+            }
+        }
+
+        try {
+            c.init(encryptMode, encryptKey, (AlgorithmParameters) null, (SecureRandom) null);
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!isPBE(c.getAlgorithm())) {
+                throw e;
+            }
+        }
+    }
+
+    private void test_Cipher_init_Decrypt_NullParameters(Cipher c, int decryptMode, Key encryptKey,
+            boolean needsParameters) throws Exception {
+        try {
+            c.init(decryptMode, encryptKey, (AlgorithmParameterSpec) null);
+            if (needsParameters) {
+                fail("Should throw InvalidAlgorithmParameterException with null parameters");
+            }
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!needsParameters) {
+                throw e;
+            }
+        }
+
+        try {
+            c.init(decryptMode, encryptKey, (AlgorithmParameterSpec) null, (SecureRandom) null);
+            if (needsParameters) {
+                fail("Should throw InvalidAlgorithmParameterException with null parameters");
+            }
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!needsParameters) {
+                throw e;
+            }
+        }
+
+        try {
+            c.init(decryptMode, encryptKey, (AlgorithmParameters) null);
+            if (needsParameters) {
+                fail("Should throw InvalidAlgorithmParameterException with null parameters");
+            }
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!needsParameters) {
+                throw e;
+            }
+        }
+
+        try {
+            c.init(decryptMode, encryptKey, (AlgorithmParameters) null, (SecureRandom) null);
+            if (needsParameters) {
+                fail("Should throw InvalidAlgorithmParameterException with null parameters");
+            }
+        } catch (InvalidAlgorithmParameterException e) {
+            if (!needsParameters) {
+                throw e;
+            }
+        }
+    }
+
+    // Checks that the Cipher throws ShortBufferException when given a too-short buffer
+    private void test_Cipher_ShortBufferException(Cipher c, String algorithm, int encryptMode,
+            AlgorithmParameterSpec spec, Key key, byte[] text) throws Exception {
+        c.init(encryptMode, key, spec);
+        if (isAEAD(algorithm)) {
+            c.updateAAD(new byte[24]);
+        }
+        if (c.getOutputSize(text.length) > 0) {
+            byte[] output;
+            if (algorithm.startsWith("RSA/")) {
+                // RSA encryption pads the input data to a full block before encrypting,
+                // so unlike most algorithms, getOutputSize can't determine how much space
+                // is necessary until the data is actually decrypted.
+                output = new byte[1];
+            } else {
+                // Other algorithms can much more easily forsee how much output data there
+                // will be, so don't let them get away with being overly conservative.
+                output = new byte[c.getOutputSize(text.length) - 1];
+            }
+            try {
+                c.doFinal(text, 0, text.length, output);
+                fail("Short buffer should have thrown ShortBufferException");
+            } catch (ShortBufferException expected) {
+                // Ignored
+            }
+        }
+    }
+
+    // Checks that if the cipher operation is aborted by a ShortBufferException the output
+    // is still correct.
+    private void test_Cipher_aborted_doFinal(Cipher c, String algorithm, String provider,
+            Key encryptKey, Key decryptKey) throws Exception {
+        byte[] text = getActualPlainText(algorithm);
+        AlgorithmParameterSpec encryptSpec = getEncryptAlgorithmParameterSpec(algorithm);
+        c.init(Cipher.ENCRYPT_MODE, encryptKey, encryptSpec);
+        if (isAEAD(algorithm)) {
+            c.updateAAD(new byte[24]);
+        }
+        try {
+            c.doFinal(text, 0, text.length, new byte[0]);
+            fail("Short buffer should have thrown ShortBufferException");
+        } catch (ShortBufferException expected) {
+            // Ignored
+        }
+        byte[] cipherText = c.doFinal(text);
+        c.init(Cipher.DECRYPT_MODE, decryptKey, getDecryptAlgorithmParameterSpec(encryptSpec, c));
+        if (isAEAD(algorithm)) {
+            c.updateAAD(new byte[24]);
+        }
+        byte[] plainText = c.doFinal(cipherText);
+        byte[] expectedPlainText = getExpectedPlainText(algorithm, provider);
+        assertTrue("Expected " + Arrays.toString(expectedPlainText)
+                + " but was " + Arrays.toString(plainText),
+                Arrays.equals(expectedPlainText, plainText));
+    }
+
+    @Test
+    public void testInputPKCS1Padding() throws Exception {
+        for (String provider : RSA_PROVIDERS) {
+            testInputPKCS1Padding(provider);
+        }
+    }
+
+    private void testInputPKCS1Padding(String provider) throws Exception {
+        // Type 1 is for signatures (PrivateKey to "encrypt")
+        testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
+        try {
+            testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
+            fail();
+        } catch (BadPaddingException expected) {
+        }
+
+        // Type 2 is for enciphering (PublicKey to "encrypt")
+        testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
+        try {
+            testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
+            fail();
+        } catch (BadPaddingException expected) {
+        }
+    }
+
+    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);
+        encryptCipher.update(prePaddedPlainText);
+        encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
+        byte[] cipherText2 = encryptCipher.doFinal(prePaddedPlainText);
+        assertEquals(Arrays.toString(cipherText),
+                     Arrays.toString(cipherText2));
+
+        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),
+                     Arrays.toString(plainText));
+        decryptCipher.update(prePaddedPlainText);
+        decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
+        byte[] plainText2 = decryptCipher.doFinal(cipherText);
+        assertEquals(Arrays.toString(plainText),
+                     Arrays.toString(plainText2));
+    }
+
+    @Test
+    public void testOutputPKCS1Padding() throws Exception {
+        for (String provider : RSA_PROVIDERS) {
+            testOutputPKCS1Padding(provider);
+        }
+    }
+
+    private void testOutputPKCS1Padding(String provider) throws Exception {
+        // Type 1 is for signatures (PrivateKey to "encrypt")
+        testOutputPKCS1Padding(provider, (byte) 1, getDecryptKey("RSA"), getEncryptKey("RSA"));
+        // Type 2 is for enciphering (PublicKey to "encrypt")
+        testOutputPKCS1Padding(provider, (byte) 2, getEncryptKey("RSA"), getDecryptKey("RSA"));
+    }
+
+    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", provider);
+        decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
+        byte[] plainText = decryptCipher.doFinal(cipherText);
+        assertPadding(provider, expectedBlockType, ORIGINAL_PLAIN_TEXT, plainText);
+    }
+
+    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) {
+            int expectedDataOffset = expectedBlockTypeOffset + 1;
+            for (int i = expectedDataOffset; i < actualDataOffset - 1; i++) {
+                assertEquals(provider, (byte) 0xFF, actualDataWithPadding[i]);
+            }
+        }
+        assertEquals(provider, 0x00, actualDataWithPadding[actualDataOffset-1]);
+        byte[] actualData = new byte[expectedData.length];
+        System.arraycopy(actualDataWithPadding, actualDataOffset, actualData, 0, actualData.length);
+        assertEquals(provider, Arrays.toString(expectedData), Arrays.toString(actualData));
+    }
+
+    @Test
+    public void testCipherInitWithCertificate () throws Exception {
+        // no key usage specified, everything is fine
+        assertCipherInitWithKeyUsage(0,                         true,  true, true,  true);
+
+        // common case is that encrypt/wrap is prohibited when special usage is specified
+        assertCipherInitWithKeyUsage(KeyUsage.digitalSignature, false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.nonRepudiation,   false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.keyAgreement,     false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.keyCertSign,      false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.cRLSign,          false, true, false, true);
+
+        // Note they encipherOnly/decipherOnly don't have to do with
+        // ENCRYPT_MODE or DECRYPT_MODE, but restrict usage relative
+        // to keyAgreement. There is not a *_MODE option that
+        // corresponds to this in Cipher, the RI does not enforce
+        // anything in Cipher.
+        // http://code.google.com/p/android/issues/detail?id=12955
+        assertCipherInitWithKeyUsage(KeyUsage.encipherOnly,     false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.decipherOnly,     false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.keyAgreement | KeyUsage.encipherOnly,
+                                                                false, true, false, true);
+        assertCipherInitWithKeyUsage(KeyUsage.keyAgreement | KeyUsage.decipherOnly,
+                                                                false, true, false, true);
+
+        // except when wrapping a key is specifically allowed or
+        assertCipherInitWithKeyUsage(KeyUsage.keyEncipherment,  false, true, true,  true);
+        // except when wrapping data encryption is specifically allowed
+        assertCipherInitWithKeyUsage(KeyUsage.dataEncipherment, true,  true, false, true);
+    }
+
+    private void assertCipherInitWithKeyUsage (int keyUsage,
+                                               boolean allowEncrypt,
+                                               boolean allowDecrypt,
+                                               boolean allowWrap,
+                                               boolean allowUnwrap) throws Exception {
+        Certificate certificate = certificateWithKeyUsage(keyUsage);
+        assertCipherInitWithKeyUsage(certificate, allowEncrypt, Cipher.ENCRYPT_MODE);
+        assertCipherInitWithKeyUsage(certificate, allowDecrypt, Cipher.DECRYPT_MODE);
+        assertCipherInitWithKeyUsage(certificate, allowWrap,    Cipher.WRAP_MODE);
+        assertCipherInitWithKeyUsage(certificate, allowUnwrap,  Cipher.UNWRAP_MODE);
+    }
+
+    private void assertCipherInitWithKeyUsage(Certificate certificate,
+                                              boolean allowMode,
+                                              int mode) throws Exception {
+        Cipher cipher = Cipher.getInstance("RSA");
+        if (allowMode) {
+            cipher.init(mode, certificate);
+        } else {
+            try {
+                cipher.init(mode, certificate);
+                String modeString;
+                switch (mode) {
+                    case Cipher.ENCRYPT_MODE:
+                        modeString = "ENCRYPT_MODE";
+                        break;
+                    case Cipher.DECRYPT_MODE:
+                        modeString = "DECRYPT_MODE";
+                        break;
+                    case Cipher.WRAP_MODE:
+                        modeString = "WRAP_MODE";
+                        break;
+                    case Cipher.UNWRAP_MODE:
+                        modeString = "UNWRAP_MODE";
+                        break;
+                    default:
+                        throw new AssertionError("Unknown Cipher.*_MODE " + mode);
+                }
+                fail("Should have had InvalidKeyException for " + modeString
+                     + " for " + certificate);
+            } catch (InvalidKeyException expected) {
+            }
+        }
+    }
+
+    private Certificate certificateWithKeyUsage(int keyUsage) throws Exception {
+        // note the rare usage of non-zero keyUsage
+        return new TestKeyStore.Builder()
+                .aliasPrefix("rsa-dsa-ec")
+                .keyUsage(keyUsage)
+                .build()
+                .getPrivateKey("RSA", "RSA").getCertificate();
+    }
+
+    /*
+     * Test vectors generated with this private key:
+     *
+     * -----BEGIN RSA PRIVATE KEY-----
+     * MIIEpAIBAAKCAQEA4Ec+irjyKE/rnnQv+XSPoRjtmGM8kvUq63ouvg075gMpvnZq
+     * 0Q62pRXQ0s/ZvqeTDwwwZTeJn3lYzT6FsB+IGFJNMSWEqUslHjYltUFB7b/uGYgI
+     * 4buX/Hy0m56qr2jpyY19DtxTu8D6ADQ1bWMF+7zDxwAUBThqu8hzyw8+90JfPTPf
+     * ezFa4DbSoLZq/UdQOxab8247UWJRW3Ff2oPeryxYrrmr+zCXw8yd2dvl7ylsF2E5
+     * Ao6KZx5jBW1F9AGI0sQTNJCEXeUsJTTpxrJHjAe9rpKII7YtBmx3cPn2Pz26JH9T
+     * CER0e+eqqF2FO4vSRKzsPePImrRkU6tNJMOsaQIDAQABAoIBADd4R3al8XaY9ayW
+     * DfuDobZ1ZOZIvQWXz4q4CHGG8macJ6nsvdSA8Bl6gNBzCebGqW+SUzHlf4tKxvTU
+     * XtpFojJpwJ/EKMB6Tm7fc4oV3sl/q9Lyu0ehTyDqcvz+TDbgGtp3vRN82NTaELsW
+     * LpSkZilx8XX5hfoYjwVsuX7igW9Dq503R2Ekhs2owWGWwwgYqZXshdOEZ3kSZ7O/
+     * IfJzcQppJYYldoQcW2cSwS1L0govMpmtt8E12l6VFavadufK8qO+gFUdBzt4vxFi
+     * xIrSt/R0OgI47k0lL31efmUzzK5kzLOTYAdaL9HgNOw65c6cQIzL8OJeQRQCFoez
+     * 3UdUroECgYEA9UGIS8Nzeyki1BGe9F4t7izUy7dfRVBaFXqlAJ+Zxzot8HJKxGAk
+     * MGMy6omBd2NFRl3G3x4KbxQK/ztzluaomUrF2qloc0cv43dJ0U6z4HXmKdvrNYMz
+     * im82SdCiZUp6Qv2atr+krE1IHTkLsimwZL3DEcwb4bYxidp8QM3s8rECgYEA6hp0
+     * LduIHO23KIyH442GjdekCdFaQ/RF1Td6C1cx3b/KLa8oqOE81cCvzsM0fXSjniNa
+     * PNljPydN4rlPkt9DgzkR2enxz1jyfeLgj/RZZMcg0+whOdx8r8kSlTzeyy81Wi4s
+     * NaUPrXVMs7IxZkJLo7bjESoriYw4xcFe2yOGkzkCgYBRgo8exv2ZYCmQG68dfjN7
+     * pfCvJ+mE6tiVrOYr199O5FoiQInyzBUa880XP84EdLywTzhqLNzA4ANrokGfVFeS
+     * YtRxAL6TGYSj76Bb7PFBV03AebOpXEqD5sQ/MhTW3zLVEt4ZgIXlMeYWuD/X3Z0f
+     * TiYHwzM9B8VdEH0dOJNYcQKBgQDbT7UPUN6O21P/NMgJMYigUShn2izKBIl3WeWH
+     * wkQBDa+GZNWegIPRbBZHiTAfZ6nweAYNg0oq29NnV1toqKhCwrAqibPzH8zsiiL+
+     * OVeVxcbHQitOXXSh6ajzDndZufwtY5wfFWc+hOk6XvFQb0MVODw41Fy9GxQEj0ch
+     * 3IIyYQKBgQDYEUWTr0FfthLb8ZI3ENVNB0hiBadqO0MZSWjA3/HxHvD2GkozfV/T
+     * dBu8lkDkR7i2tsR8OsEgQ1fTsMVbqShr2nP2KSlvX6kUbYl2NX08dR51FIaWpAt0
+     * aFyCzjCQLWOdck/yTV4ulAfuNO3tLjtN9lqpvP623yjQe6aQPxZXaA==
+     * -----END RSA PRIVATE KEY-----
+     *
+     */
+
+    private static final BigInteger RSA_2048_modulus = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xe0, (byte) 0x47, (byte) 0x3e, (byte) 0x8a, (byte) 0xb8, (byte) 0xf2, (byte) 0x28,
+        (byte) 0x4f, (byte) 0xeb, (byte) 0x9e, (byte) 0x74, (byte) 0x2f, (byte) 0xf9, (byte) 0x74, (byte) 0x8f,
+        (byte) 0xa1, (byte) 0x18, (byte) 0xed, (byte) 0x98, (byte) 0x63, (byte) 0x3c, (byte) 0x92, (byte) 0xf5,
+        (byte) 0x2a, (byte) 0xeb, (byte) 0x7a, (byte) 0x2e, (byte) 0xbe, (byte) 0x0d, (byte) 0x3b, (byte) 0xe6,
+        (byte) 0x03, (byte) 0x29, (byte) 0xbe, (byte) 0x76, (byte) 0x6a, (byte) 0xd1, (byte) 0x0e, (byte) 0xb6,
+        (byte) 0xa5, (byte) 0x15, (byte) 0xd0, (byte) 0xd2, (byte) 0xcf, (byte) 0xd9, (byte) 0xbe, (byte) 0xa7,
+        (byte) 0x93, (byte) 0x0f, (byte) 0x0c, (byte) 0x30, (byte) 0x65, (byte) 0x37, (byte) 0x89, (byte) 0x9f,
+        (byte) 0x79, (byte) 0x58, (byte) 0xcd, (byte) 0x3e, (byte) 0x85, (byte) 0xb0, (byte) 0x1f, (byte) 0x88,
+        (byte) 0x18, (byte) 0x52, (byte) 0x4d, (byte) 0x31, (byte) 0x25, (byte) 0x84, (byte) 0xa9, (byte) 0x4b,
+        (byte) 0x25, (byte) 0x1e, (byte) 0x36, (byte) 0x25, (byte) 0xb5, (byte) 0x41, (byte) 0x41, (byte) 0xed,
+        (byte) 0xbf, (byte) 0xee, (byte) 0x19, (byte) 0x88, (byte) 0x08, (byte) 0xe1, (byte) 0xbb, (byte) 0x97,
+        (byte) 0xfc, (byte) 0x7c, (byte) 0xb4, (byte) 0x9b, (byte) 0x9e, (byte) 0xaa, (byte) 0xaf, (byte) 0x68,
+        (byte) 0xe9, (byte) 0xc9, (byte) 0x8d, (byte) 0x7d, (byte) 0x0e, (byte) 0xdc, (byte) 0x53, (byte) 0xbb,
+        (byte) 0xc0, (byte) 0xfa, (byte) 0x00, (byte) 0x34, (byte) 0x35, (byte) 0x6d, (byte) 0x63, (byte) 0x05,
+        (byte) 0xfb, (byte) 0xbc, (byte) 0xc3, (byte) 0xc7, (byte) 0x00, (byte) 0x14, (byte) 0x05, (byte) 0x38,
+        (byte) 0x6a, (byte) 0xbb, (byte) 0xc8, (byte) 0x73, (byte) 0xcb, (byte) 0x0f, (byte) 0x3e, (byte) 0xf7,
+        (byte) 0x42, (byte) 0x5f, (byte) 0x3d, (byte) 0x33, (byte) 0xdf, (byte) 0x7b, (byte) 0x31, (byte) 0x5a,
+        (byte) 0xe0, (byte) 0x36, (byte) 0xd2, (byte) 0xa0, (byte) 0xb6, (byte) 0x6a, (byte) 0xfd, (byte) 0x47,
+        (byte) 0x50, (byte) 0x3b, (byte) 0x16, (byte) 0x9b, (byte) 0xf3, (byte) 0x6e, (byte) 0x3b, (byte) 0x51,
+        (byte) 0x62, (byte) 0x51, (byte) 0x5b, (byte) 0x71, (byte) 0x5f, (byte) 0xda, (byte) 0x83, (byte) 0xde,
+        (byte) 0xaf, (byte) 0x2c, (byte) 0x58, (byte) 0xae, (byte) 0xb9, (byte) 0xab, (byte) 0xfb, (byte) 0x30,
+        (byte) 0x97, (byte) 0xc3, (byte) 0xcc, (byte) 0x9d, (byte) 0xd9, (byte) 0xdb, (byte) 0xe5, (byte) 0xef,
+        (byte) 0x29, (byte) 0x6c, (byte) 0x17, (byte) 0x61, (byte) 0x39, (byte) 0x02, (byte) 0x8e, (byte) 0x8a,
+        (byte) 0x67, (byte) 0x1e, (byte) 0x63, (byte) 0x05, (byte) 0x6d, (byte) 0x45, (byte) 0xf4, (byte) 0x01,
+        (byte) 0x88, (byte) 0xd2, (byte) 0xc4, (byte) 0x13, (byte) 0x34, (byte) 0x90, (byte) 0x84, (byte) 0x5d,
+        (byte) 0xe5, (byte) 0x2c, (byte) 0x25, (byte) 0x34, (byte) 0xe9, (byte) 0xc6, (byte) 0xb2, (byte) 0x47,
+        (byte) 0x8c, (byte) 0x07, (byte) 0xbd, (byte) 0xae, (byte) 0x92, (byte) 0x88, (byte) 0x23, (byte) 0xb6,
+        (byte) 0x2d, (byte) 0x06, (byte) 0x6c, (byte) 0x77, (byte) 0x70, (byte) 0xf9, (byte) 0xf6, (byte) 0x3f,
+        (byte) 0x3d, (byte) 0xba, (byte) 0x24, (byte) 0x7f, (byte) 0x53, (byte) 0x08, (byte) 0x44, (byte) 0x74,
+        (byte) 0x7b, (byte) 0xe7, (byte) 0xaa, (byte) 0xa8, (byte) 0x5d, (byte) 0x85, (byte) 0x3b, (byte) 0x8b,
+        (byte) 0xd2, (byte) 0x44, (byte) 0xac, (byte) 0xec, (byte) 0x3d, (byte) 0xe3, (byte) 0xc8, (byte) 0x9a,
+        (byte) 0xb4, (byte) 0x64, (byte) 0x53, (byte) 0xab, (byte) 0x4d, (byte) 0x24, (byte) 0xc3, (byte) 0xac,
+        (byte) 0x69,
+    });
+
+    private static final BigInteger RSA_2048_privateExponent = new BigInteger(new byte[] {
+        (byte) 0x37, (byte) 0x78, (byte) 0x47, (byte) 0x76, (byte) 0xa5, (byte) 0xf1, (byte) 0x76, (byte) 0x98,
+        (byte) 0xf5, (byte) 0xac, (byte) 0x96, (byte) 0x0d, (byte) 0xfb, (byte) 0x83, (byte) 0xa1, (byte) 0xb6,
+        (byte) 0x75, (byte) 0x64, (byte) 0xe6, (byte) 0x48, (byte) 0xbd, (byte) 0x05, (byte) 0x97, (byte) 0xcf,
+        (byte) 0x8a, (byte) 0xb8, (byte) 0x08, (byte) 0x71, (byte) 0x86, (byte) 0xf2, (byte) 0x66, (byte) 0x9c,
+        (byte) 0x27, (byte) 0xa9, (byte) 0xec, (byte) 0xbd, (byte) 0xd4, (byte) 0x80, (byte) 0xf0, (byte) 0x19,
+        (byte) 0x7a, (byte) 0x80, (byte) 0xd0, (byte) 0x73, (byte) 0x09, (byte) 0xe6, (byte) 0xc6, (byte) 0xa9,
+        (byte) 0x6f, (byte) 0x92, (byte) 0x53, (byte) 0x31, (byte) 0xe5, (byte) 0x7f, (byte) 0x8b, (byte) 0x4a,
+        (byte) 0xc6, (byte) 0xf4, (byte) 0xd4, (byte) 0x5e, (byte) 0xda, (byte) 0x45, (byte) 0xa2, (byte) 0x32,
+        (byte) 0x69, (byte) 0xc0, (byte) 0x9f, (byte) 0xc4, (byte) 0x28, (byte) 0xc0, (byte) 0x7a, (byte) 0x4e,
+        (byte) 0x6e, (byte) 0xdf, (byte) 0x73, (byte) 0x8a, (byte) 0x15, (byte) 0xde, (byte) 0xc9, (byte) 0x7f,
+        (byte) 0xab, (byte) 0xd2, (byte) 0xf2, (byte) 0xbb, (byte) 0x47, (byte) 0xa1, (byte) 0x4f, (byte) 0x20,
+        (byte) 0xea, (byte) 0x72, (byte) 0xfc, (byte) 0xfe, (byte) 0x4c, (byte) 0x36, (byte) 0xe0, (byte) 0x1a,
+        (byte) 0xda, (byte) 0x77, (byte) 0xbd, (byte) 0x13, (byte) 0x7c, (byte) 0xd8, (byte) 0xd4, (byte) 0xda,
+        (byte) 0x10, (byte) 0xbb, (byte) 0x16, (byte) 0x2e, (byte) 0x94, (byte) 0xa4, (byte) 0x66, (byte) 0x29,
+        (byte) 0x71, (byte) 0xf1, (byte) 0x75, (byte) 0xf9, (byte) 0x85, (byte) 0xfa, (byte) 0x18, (byte) 0x8f,
+        (byte) 0x05, (byte) 0x6c, (byte) 0xb9, (byte) 0x7e, (byte) 0xe2, (byte) 0x81, (byte) 0x6f, (byte) 0x43,
+        (byte) 0xab, (byte) 0x9d, (byte) 0x37, (byte) 0x47, (byte) 0x61, (byte) 0x24, (byte) 0x86, (byte) 0xcd,
+        (byte) 0xa8, (byte) 0xc1, (byte) 0x61, (byte) 0x96, (byte) 0xc3, (byte) 0x08, (byte) 0x18, (byte) 0xa9,
+        (byte) 0x95, (byte) 0xec, (byte) 0x85, (byte) 0xd3, (byte) 0x84, (byte) 0x67, (byte) 0x79, (byte) 0x12,
+        (byte) 0x67, (byte) 0xb3, (byte) 0xbf, (byte) 0x21, (byte) 0xf2, (byte) 0x73, (byte) 0x71, (byte) 0x0a,
+        (byte) 0x69, (byte) 0x25, (byte) 0x86, (byte) 0x25, (byte) 0x76, (byte) 0x84, (byte) 0x1c, (byte) 0x5b,
+        (byte) 0x67, (byte) 0x12, (byte) 0xc1, (byte) 0x2d, (byte) 0x4b, (byte) 0xd2, (byte) 0x0a, (byte) 0x2f,
+        (byte) 0x32, (byte) 0x99, (byte) 0xad, (byte) 0xb7, (byte) 0xc1, (byte) 0x35, (byte) 0xda, (byte) 0x5e,
+        (byte) 0x95, (byte) 0x15, (byte) 0xab, (byte) 0xda, (byte) 0x76, (byte) 0xe7, (byte) 0xca, (byte) 0xf2,
+        (byte) 0xa3, (byte) 0xbe, (byte) 0x80, (byte) 0x55, (byte) 0x1d, (byte) 0x07, (byte) 0x3b, (byte) 0x78,
+        (byte) 0xbf, (byte) 0x11, (byte) 0x62, (byte) 0xc4, (byte) 0x8a, (byte) 0xd2, (byte) 0xb7, (byte) 0xf4,
+        (byte) 0x74, (byte) 0x3a, (byte) 0x02, (byte) 0x38, (byte) 0xee, (byte) 0x4d, (byte) 0x25, (byte) 0x2f,
+        (byte) 0x7d, (byte) 0x5e, (byte) 0x7e, (byte) 0x65, (byte) 0x33, (byte) 0xcc, (byte) 0xae, (byte) 0x64,
+        (byte) 0xcc, (byte) 0xb3, (byte) 0x93, (byte) 0x60, (byte) 0x07, (byte) 0x5a, (byte) 0x2f, (byte) 0xd1,
+        (byte) 0xe0, (byte) 0x34, (byte) 0xec, (byte) 0x3a, (byte) 0xe5, (byte) 0xce, (byte) 0x9c, (byte) 0x40,
+        (byte) 0x8c, (byte) 0xcb, (byte) 0xf0, (byte) 0xe2, (byte) 0x5e, (byte) 0x41, (byte) 0x14, (byte) 0x02,
+        (byte) 0x16, (byte) 0x87, (byte) 0xb3, (byte) 0xdd, (byte) 0x47, (byte) 0x54, (byte) 0xae, (byte) 0x81,
+    });
+
+    private static final BigInteger RSA_2048_publicExponent = new BigInteger(new byte[] {
+        (byte) 0x01, (byte) 0x00, (byte) 0x01,
+    });
+
+    private static final BigInteger RSA_2048_primeP = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xf5, (byte) 0x41, (byte) 0x88, (byte) 0x4b, (byte) 0xc3, (byte) 0x73, (byte) 0x7b,
+        (byte) 0x29, (byte) 0x22, (byte) 0xd4, (byte) 0x11, (byte) 0x9e, (byte) 0xf4, (byte) 0x5e, (byte) 0x2d,
+        (byte) 0xee, (byte) 0x2c, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x5f, (byte) 0x45, (byte) 0x50,
+        (byte) 0x5a, (byte) 0x15, (byte) 0x7a, (byte) 0xa5, (byte) 0x00, (byte) 0x9f, (byte) 0x99, (byte) 0xc7,
+        (byte) 0x3a, (byte) 0x2d, (byte) 0xf0, (byte) 0x72, (byte) 0x4a, (byte) 0xc4, (byte) 0x60, (byte) 0x24,
+        (byte) 0x30, (byte) 0x63, (byte) 0x32, (byte) 0xea, (byte) 0x89, (byte) 0x81, (byte) 0x77, (byte) 0x63,
+        (byte) 0x45, (byte) 0x46, (byte) 0x5d, (byte) 0xc6, (byte) 0xdf, (byte) 0x1e, (byte) 0x0a, (byte) 0x6f,
+        (byte) 0x14, (byte) 0x0a, (byte) 0xff, (byte) 0x3b, (byte) 0x73, (byte) 0x96, (byte) 0xe6, (byte) 0xa8,
+        (byte) 0x99, (byte) 0x4a, (byte) 0xc5, (byte) 0xda, (byte) 0xa9, (byte) 0x68, (byte) 0x73, (byte) 0x47,
+        (byte) 0x2f, (byte) 0xe3, (byte) 0x77, (byte) 0x49, (byte) 0xd1, (byte) 0x4e, (byte) 0xb3, (byte) 0xe0,
+        (byte) 0x75, (byte) 0xe6, (byte) 0x29, (byte) 0xdb, (byte) 0xeb, (byte) 0x35, (byte) 0x83, (byte) 0x33,
+        (byte) 0x8a, (byte) 0x6f, (byte) 0x36, (byte) 0x49, (byte) 0xd0, (byte) 0xa2, (byte) 0x65, (byte) 0x4a,
+        (byte) 0x7a, (byte) 0x42, (byte) 0xfd, (byte) 0x9a, (byte) 0xb6, (byte) 0xbf, (byte) 0xa4, (byte) 0xac,
+        (byte) 0x4d, (byte) 0x48, (byte) 0x1d, (byte) 0x39, (byte) 0x0b, (byte) 0xb2, (byte) 0x29, (byte) 0xb0,
+        (byte) 0x64, (byte) 0xbd, (byte) 0xc3, (byte) 0x11, (byte) 0xcc, (byte) 0x1b, (byte) 0xe1, (byte) 0xb6,
+        (byte) 0x31, (byte) 0x89, (byte) 0xda, (byte) 0x7c, (byte) 0x40, (byte) 0xcd, (byte) 0xec, (byte) 0xf2,
+        (byte) 0xb1,
+    });
+
+    private static final BigInteger RSA_2048_primeQ = new BigInteger(new byte[] {
+        (byte) 0x00, (byte) 0xea, (byte) 0x1a, (byte) 0x74, (byte) 0x2d, (byte) 0xdb, (byte) 0x88, (byte) 0x1c,
+        (byte) 0xed, (byte) 0xb7, (byte) 0x28, (byte) 0x8c, (byte) 0x87, (byte) 0xe3, (byte) 0x8d, (byte) 0x86,
+        (byte) 0x8d, (byte) 0xd7, (byte) 0xa4, (byte) 0x09, (byte) 0xd1, (byte) 0x5a, (byte) 0x43, (byte) 0xf4,
+        (byte) 0x45, (byte) 0xd5, (byte) 0x37, (byte) 0x7a, (byte) 0x0b, (byte) 0x57, (byte) 0x31, (byte) 0xdd,
+        (byte) 0xbf, (byte) 0xca, (byte) 0x2d, (byte) 0xaf, (byte) 0x28, (byte) 0xa8, (byte) 0xe1, (byte) 0x3c,
+        (byte) 0xd5, (byte) 0xc0, (byte) 0xaf, (byte) 0xce, (byte) 0xc3, (byte) 0x34, (byte) 0x7d, (byte) 0x74,
+        (byte) 0xa3, (byte) 0x9e, (byte) 0x23, (byte) 0x5a, (byte) 0x3c, (byte) 0xd9, (byte) 0x63, (byte) 0x3f,
+        (byte) 0x27, (byte) 0x4d, (byte) 0xe2, (byte) 0xb9, (byte) 0x4f, (byte) 0x92, (byte) 0xdf, (byte) 0x43,
+        (byte) 0x83, (byte) 0x39, (byte) 0x11, (byte) 0xd9, (byte) 0xe9, (byte) 0xf1, (byte) 0xcf, (byte) 0x58,
+        (byte) 0xf2, (byte) 0x7d, (byte) 0xe2, (byte) 0xe0, (byte) 0x8f, (byte) 0xf4, (byte) 0x59, (byte) 0x64,
+        (byte) 0xc7, (byte) 0x20, (byte) 0xd3, (byte) 0xec, (byte) 0x21, (byte) 0x39, (byte) 0xdc, (byte) 0x7c,
+        (byte) 0xaf, (byte) 0xc9, (byte) 0x12, (byte) 0x95, (byte) 0x3c, (byte) 0xde, (byte) 0xcb, (byte) 0x2f,
+        (byte) 0x35, (byte) 0x5a, (byte) 0x2e, (byte) 0x2c, (byte) 0x35, (byte) 0xa5, (byte) 0x0f, (byte) 0xad,
+        (byte) 0x75, (byte) 0x4c, (byte) 0xb3, (byte) 0xb2, (byte) 0x31, (byte) 0x66, (byte) 0x42, (byte) 0x4b,
+        (byte) 0xa3, (byte) 0xb6, (byte) 0xe3, (byte) 0x11, (byte) 0x2a, (byte) 0x2b, (byte) 0x89, (byte) 0x8c,
+        (byte) 0x38, (byte) 0xc5, (byte) 0xc1, (byte) 0x5e, (byte) 0xdb, (byte) 0x23, (byte) 0x86, (byte) 0x93,
+        (byte) 0x39,
+    });
+
+    private static final BigInteger RSA_2048_primeExponentP = new BigInteger(1, new byte[] {
+        (byte) 0x51, (byte) 0x82, (byte) 0x8F, (byte) 0x1E, (byte) 0xC6, (byte) 0xFD, (byte) 0x99, (byte) 0x60,
+        (byte) 0x29, (byte) 0x90, (byte) 0x1B, (byte) 0xAF, (byte) 0x1D, (byte) 0x7E, (byte) 0x33, (byte) 0x7B,
+        (byte) 0xA5, (byte) 0xF0, (byte) 0xAF, (byte) 0x27, (byte) 0xE9, (byte) 0x84, (byte) 0xEA, (byte) 0xD8,
+        (byte) 0x95, (byte) 0xAC, (byte) 0xE6, (byte) 0x2B, (byte) 0xD7, (byte) 0xDF, (byte) 0x4E, (byte) 0xE4,
+        (byte) 0x5A, (byte) 0x22, (byte) 0x40, (byte) 0x89, (byte) 0xF2, (byte) 0xCC, (byte) 0x15, (byte) 0x1A,
+        (byte) 0xF3, (byte) 0xCD, (byte) 0x17, (byte) 0x3F, (byte) 0xCE, (byte) 0x04, (byte) 0x74, (byte) 0xBC,
+        (byte) 0xB0, (byte) 0x4F, (byte) 0x38, (byte) 0x6A, (byte) 0x2C, (byte) 0xDC, (byte) 0xC0, (byte) 0xE0,
+        (byte) 0x03, (byte) 0x6B, (byte) 0xA2, (byte) 0x41, (byte) 0x9F, (byte) 0x54, (byte) 0x57, (byte) 0x92,
+        (byte) 0x62, (byte) 0xD4, (byte) 0x71, (byte) 0x00, (byte) 0xBE, (byte) 0x93, (byte) 0x19, (byte) 0x84,
+        (byte) 0xA3, (byte) 0xEF, (byte) 0xA0, (byte) 0x5B, (byte) 0xEC, (byte) 0xF1, (byte) 0x41, (byte) 0x57,
+        (byte) 0x4D, (byte) 0xC0, (byte) 0x79, (byte) 0xB3, (byte) 0xA9, (byte) 0x5C, (byte) 0x4A, (byte) 0x83,
+        (byte) 0xE6, (byte) 0xC4, (byte) 0x3F, (byte) 0x32, (byte) 0x14, (byte) 0xD6, (byte) 0xDF, (byte) 0x32,
+        (byte) 0xD5, (byte) 0x12, (byte) 0xDE, (byte) 0x19, (byte) 0x80, (byte) 0x85, (byte) 0xE5, (byte) 0x31,
+        (byte) 0xE6, (byte) 0x16, (byte) 0xB8, (byte) 0x3F, (byte) 0xD7, (byte) 0xDD, (byte) 0x9D, (byte) 0x1F,
+        (byte) 0x4E, (byte) 0x26, (byte) 0x07, (byte) 0xC3, (byte) 0x33, (byte) 0x3D, (byte) 0x07, (byte) 0xC5,
+        (byte) 0x5D, (byte) 0x10, (byte) 0x7D, (byte) 0x1D, (byte) 0x38, (byte) 0x93, (byte) 0x58, (byte) 0x71,
+    });
+
+    private static final BigInteger RSA_2048_primeExponentQ = new BigInteger(1, new byte[] {
+        (byte) 0xDB, (byte) 0x4F, (byte) 0xB5, (byte) 0x0F, (byte) 0x50, (byte) 0xDE, (byte) 0x8E, (byte) 0xDB,
+        (byte) 0x53, (byte) 0xFF, (byte) 0x34, (byte) 0xC8, (byte) 0x09, (byte) 0x31, (byte) 0x88, (byte) 0xA0,
+        (byte) 0x51, (byte) 0x28, (byte) 0x67, (byte) 0xDA, (byte) 0x2C, (byte) 0xCA, (byte) 0x04, (byte) 0x89,
+        (byte) 0x77, (byte) 0x59, (byte) 0xE5, (byte) 0x87, (byte) 0xC2, (byte) 0x44, (byte) 0x01, (byte) 0x0D,
+        (byte) 0xAF, (byte) 0x86, (byte) 0x64, (byte) 0xD5, (byte) 0x9E, (byte) 0x80, (byte) 0x83, (byte) 0xD1,
+        (byte) 0x6C, (byte) 0x16, (byte) 0x47, (byte) 0x89, (byte) 0x30, (byte) 0x1F, (byte) 0x67, (byte) 0xA9,
+        (byte) 0xF0, (byte) 0x78, (byte) 0x06, (byte) 0x0D, (byte) 0x83, (byte) 0x4A, (byte) 0x2A, (byte) 0xDB,
+        (byte) 0xD3, (byte) 0x67, (byte) 0x57, (byte) 0x5B, (byte) 0x68, (byte) 0xA8, (byte) 0xA8, (byte) 0x42,
+        (byte) 0xC2, (byte) 0xB0, (byte) 0x2A, (byte) 0x89, (byte) 0xB3, (byte) 0xF3, (byte) 0x1F, (byte) 0xCC,
+        (byte) 0xEC, (byte) 0x8A, (byte) 0x22, (byte) 0xFE, (byte) 0x39, (byte) 0x57, (byte) 0x95, (byte) 0xC5,
+        (byte) 0xC6, (byte) 0xC7, (byte) 0x42, (byte) 0x2B, (byte) 0x4E, (byte) 0x5D, (byte) 0x74, (byte) 0xA1,
+        (byte) 0xE9, (byte) 0xA8, (byte) 0xF3, (byte) 0x0E, (byte) 0x77, (byte) 0x59, (byte) 0xB9, (byte) 0xFC,
+        (byte) 0x2D, (byte) 0x63, (byte) 0x9C, (byte) 0x1F, (byte) 0x15, (byte) 0x67, (byte) 0x3E, (byte) 0x84,
+        (byte) 0xE9, (byte) 0x3A, (byte) 0x5E, (byte) 0xF1, (byte) 0x50, (byte) 0x6F, (byte) 0x43, (byte) 0x15,
+        (byte) 0x38, (byte) 0x3C, (byte) 0x38, (byte) 0xD4, (byte) 0x5C, (byte) 0xBD, (byte) 0x1B, (byte) 0x14,
+        (byte) 0x04, (byte) 0x8F, (byte) 0x47, (byte) 0x21, (byte) 0xDC, (byte) 0x82, (byte) 0x32, (byte) 0x61,
+    });
+
+    private static final BigInteger RSA_2048_crtCoefficient = new BigInteger(1, new byte[] {
+        (byte) 0xD8, (byte) 0x11, (byte) 0x45, (byte) 0x93, (byte) 0xAF, (byte) 0x41, (byte) 0x5F, (byte) 0xB6,
+        (byte) 0x12, (byte) 0xDB, (byte) 0xF1, (byte) 0x92, (byte) 0x37, (byte) 0x10, (byte) 0xD5, (byte) 0x4D,
+        (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0x05, (byte) 0xA7, (byte) 0x6A, (byte) 0x3B, (byte) 0x43,
+        (byte) 0x19, (byte) 0x49, (byte) 0x68, (byte) 0xC0, (byte) 0xDF, (byte) 0xF1, (byte) 0xF1, (byte) 0x1E,
+        (byte) 0xF0, (byte) 0xF6, (byte) 0x1A, (byte) 0x4A, (byte) 0x33, (byte) 0x7D, (byte) 0x5F, (byte) 0xD3,
+        (byte) 0x74, (byte) 0x1B, (byte) 0xBC, (byte) 0x96, (byte) 0x40, (byte) 0xE4, (byte) 0x47, (byte) 0xB8,
+        (byte) 0xB6, (byte) 0xB6, (byte) 0xC4, (byte) 0x7C, (byte) 0x3A, (byte) 0xC1, (byte) 0x20, (byte) 0x43,
+        (byte) 0x57, (byte) 0xD3, (byte) 0xB0, (byte) 0xC5, (byte) 0x5B, (byte) 0xA9, (byte) 0x28, (byte) 0x6B,
+        (byte) 0xDA, (byte) 0x73, (byte) 0xF6, (byte) 0x29, (byte) 0x29, (byte) 0x6F, (byte) 0x5F, (byte) 0xA9,
+        (byte) 0x14, (byte) 0x6D, (byte) 0x89, (byte) 0x76, (byte) 0x35, (byte) 0x7D, (byte) 0x3C, (byte) 0x75,
+        (byte) 0x1E, (byte) 0x75, (byte) 0x14, (byte) 0x86, (byte) 0x96, (byte) 0xA4, (byte) 0x0B, (byte) 0x74,
+        (byte) 0x68, (byte) 0x5C, (byte) 0x82, (byte) 0xCE, (byte) 0x30, (byte) 0x90, (byte) 0x2D, (byte) 0x63,
+        (byte) 0x9D, (byte) 0x72, (byte) 0x4F, (byte) 0xF2, (byte) 0x4D, (byte) 0x5E, (byte) 0x2E, (byte) 0x94,
+        (byte) 0x07, (byte) 0xEE, (byte) 0x34, (byte) 0xED, (byte) 0xED, (byte) 0x2E, (byte) 0x3B, (byte) 0x4D,
+        (byte) 0xF6, (byte) 0x5A, (byte) 0xA9, (byte) 0xBC, (byte) 0xFE, (byte) 0xB6, (byte) 0xDF, (byte) 0x28,
+        (byte) 0xD0, (byte) 0x7B, (byte) 0xA6, (byte) 0x90, (byte) 0x3F, (byte) 0x16, (byte) 0x57, (byte) 0x68,
+    });
+
+    /**
+     * Test data is PKCS#1 padded "Android.\n" which can be generated by:
+     * echo "Android." | openssl rsautl -inkey rsa.key -sign | openssl rsautl -inkey rsa.key -raw -verify | recode ../x1
+     */
+    private static final byte[] RSA_2048_Vector1 = new byte[] {
+        (byte) 0x00, (byte) 0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0x00, (byte) 0x41, (byte) 0x6E, (byte) 0x64, (byte) 0x72, (byte) 0x6F,
+        (byte) 0x69, (byte) 0x64, (byte) 0x2E, (byte) 0x0A,
+    };
+
+    /**
+     * This vector is simply "Android.\n" which is too short.
+     */
+    private static final byte[] TooShort_Vector = new byte[] {
+        (byte) 0x41, (byte) 0x6E, (byte) 0x64, (byte) 0x72, (byte) 0x6F, (byte) 0x69,
+        (byte) 0x64, (byte) 0x2E, (byte) 0x0A,
+    };
+
+    /**
+     * This vector is simply "Android.\n" padded with zeros.
+     */
+    private static final byte[] TooShort_Vector_Zero_Padded = new byte[] {
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f,
+        (byte) 0x69, (byte) 0x64, (byte) 0x2e, (byte) 0x0a,
+    };
+
+    /**
+     * openssl rsautl -raw -sign -inkey rsa.key | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] RSA_Vector1_Encrypt_Private = new byte[] {
+        (byte) 0x35, (byte) 0x43, (byte) 0x38, (byte) 0x44, (byte) 0xAD, (byte) 0x3F,
+        (byte) 0x97, (byte) 0x02, (byte) 0xFB, (byte) 0x59, (byte) 0x1F, (byte) 0x4A,
+        (byte) 0x2B, (byte) 0xB9, (byte) 0x06, (byte) 0xEC, (byte) 0x66, (byte) 0xE6,
+        (byte) 0xD2, (byte) 0xC5, (byte) 0x8B, (byte) 0x7B, (byte) 0xE3, (byte) 0x18,
+        (byte) 0xBF, (byte) 0x07, (byte) 0xD6, (byte) 0x01, (byte) 0xF9, (byte) 0xD9,
+        (byte) 0x89, (byte) 0xC4, (byte) 0xDB, (byte) 0x00, (byte) 0x68, (byte) 0xFF,
+        (byte) 0x9B, (byte) 0x43, (byte) 0x90, (byte) 0xF2, (byte) 0xDB, (byte) 0x83,
+        (byte) 0xF4, (byte) 0x7E, (byte) 0xC6, (byte) 0x81, (byte) 0x01, (byte) 0x3A,
+        (byte) 0x0B, (byte) 0xE5, (byte) 0xED, (byte) 0x08, (byte) 0x73, (byte) 0x3E,
+        (byte) 0xE1, (byte) 0x3F, (byte) 0xDF, (byte) 0x1F, (byte) 0x07, (byte) 0x6D,
+        (byte) 0x22, (byte) 0x8D, (byte) 0xCC, (byte) 0x4E, (byte) 0xE3, (byte) 0x9A,
+        (byte) 0xBC, (byte) 0xCC, (byte) 0x8F, (byte) 0x9E, (byte) 0x9B, (byte) 0x02,
+        (byte) 0x48, (byte) 0x00, (byte) 0xAC, (byte) 0x9F, (byte) 0xA4, (byte) 0x8F,
+        (byte) 0x87, (byte) 0xA1, (byte) 0xA8, (byte) 0xE6, (byte) 0x9D, (byte) 0xCD,
+        (byte) 0x8B, (byte) 0x05, (byte) 0xE9, (byte) 0xD2, (byte) 0x05, (byte) 0x8D,
+        (byte) 0xC9, (byte) 0x95, (byte) 0x16, (byte) 0xD0, (byte) 0xCD, (byte) 0x43,
+        (byte) 0x25, (byte) 0x8A, (byte) 0x11, (byte) 0x46, (byte) 0xD7, (byte) 0x74,
+        (byte) 0x4C, (byte) 0xCF, (byte) 0x58, (byte) 0xF9, (byte) 0xA1, (byte) 0x30,
+        (byte) 0x84, (byte) 0x52, (byte) 0xC9, (byte) 0x01, (byte) 0x5F, (byte) 0x24,
+        (byte) 0x4C, (byte) 0xB1, (byte) 0x9F, (byte) 0x7D, (byte) 0x12, (byte) 0x38,
+        (byte) 0x27, (byte) 0x0F, (byte) 0x5E, (byte) 0xFF, (byte) 0xE0, (byte) 0x55,
+        (byte) 0x8B, (byte) 0xA3, (byte) 0xAD, (byte) 0x60, (byte) 0x35, (byte) 0x83,
+        (byte) 0x58, (byte) 0xAF, (byte) 0x99, (byte) 0xDE, (byte) 0x3F, (byte) 0x5D,
+        (byte) 0x80, (byte) 0x80, (byte) 0xFF, (byte) 0x9B, (byte) 0xDE, (byte) 0x5C,
+        (byte) 0xAB, (byte) 0x97, (byte) 0x43, (byte) 0x64, (byte) 0xD9, (byte) 0x9F,
+        (byte) 0xFB, (byte) 0x67, (byte) 0x65, (byte) 0xA5, (byte) 0x99, (byte) 0xE7,
+        (byte) 0xE6, (byte) 0xEB, (byte) 0x05, (byte) 0x95, (byte) 0xFC, (byte) 0x46,
+        (byte) 0x28, (byte) 0x4B, (byte) 0xD8, (byte) 0x8C, (byte) 0xF5, (byte) 0x0A,
+        (byte) 0xEB, (byte) 0x1F, (byte) 0x30, (byte) 0xEA, (byte) 0xE7, (byte) 0x67,
+        (byte) 0x11, (byte) 0x25, (byte) 0xF0, (byte) 0x44, (byte) 0x75, (byte) 0x74,
+        (byte) 0x94, (byte) 0x06, (byte) 0x78, (byte) 0xD0, (byte) 0x21, (byte) 0xF4,
+        (byte) 0x3F, (byte) 0xC8, (byte) 0xC4, (byte) 0x4A, (byte) 0x57, (byte) 0xBE,
+        (byte) 0x02, (byte) 0x3C, (byte) 0x93, (byte) 0xF6, (byte) 0x95, (byte) 0xFB,
+        (byte) 0xD1, (byte) 0x77, (byte) 0x8B, (byte) 0x43, (byte) 0xF0, (byte) 0xB9,
+        (byte) 0x7D, (byte) 0xE0, (byte) 0x32, (byte) 0xE1, (byte) 0x72, (byte) 0xB5,
+        (byte) 0x62, (byte) 0x3F, (byte) 0x86, (byte) 0xC3, (byte) 0xD4, (byte) 0x5F,
+        (byte) 0x5E, (byte) 0x54, (byte) 0x1B, (byte) 0x5B, (byte) 0xE6, (byte) 0x74,
+        (byte) 0xA1, (byte) 0x0B, (byte) 0xE5, (byte) 0x18, (byte) 0xD2, (byte) 0x4F,
+        (byte) 0x93, (byte) 0xF3, (byte) 0x09, (byte) 0x58, (byte) 0xCE, (byte) 0xF0,
+        (byte) 0xA3, (byte) 0x61, (byte) 0xE4, (byte) 0x6E, (byte) 0x46, (byte) 0x45,
+        (byte) 0x89, (byte) 0x50, (byte) 0xBD, (byte) 0x03, (byte) 0x3F, (byte) 0x38,
+        (byte) 0xDA, (byte) 0x5D, (byte) 0xD0, (byte) 0x1B, (byte) 0x1F, (byte) 0xB1,
+        (byte) 0xEE, (byte) 0x89, (byte) 0x59, (byte) 0xC5,
+    };
+
+    private static final byte[] RSA_Vector1_ZeroPadded_Encrypted = new byte[] {
+        (byte) 0x60, (byte) 0x4a, (byte) 0x12, (byte) 0xa3, (byte) 0xa7, (byte) 0x4a,
+        (byte) 0xa4, (byte) 0xbf, (byte) 0x6c, (byte) 0x36, (byte) 0xad, (byte) 0x66,
+        (byte) 0xdf, (byte) 0xce, (byte) 0xf1, (byte) 0xe4, (byte) 0x0f, (byte) 0xd4,
+        (byte) 0x54, (byte) 0x5f, (byte) 0x03, (byte) 0x15, (byte) 0x4b, (byte) 0x9e,
+        (byte) 0xeb, (byte) 0xfe, (byte) 0x9e, (byte) 0x24, (byte) 0xce, (byte) 0x8e,
+        (byte) 0xc3, (byte) 0x36, (byte) 0xa5, (byte) 0x76, (byte) 0xf6, (byte) 0x54,
+        (byte) 0xb7, (byte) 0x84, (byte) 0x48, (byte) 0x2f, (byte) 0xd4, (byte) 0x45,
+        (byte) 0x74, (byte) 0x48, (byte) 0x5f, (byte) 0x08, (byte) 0x4e, (byte) 0x9c,
+        (byte) 0x89, (byte) 0xcc, (byte) 0x34, (byte) 0x40, (byte) 0xb1, (byte) 0x5f,
+        (byte) 0xa7, (byte) 0x0e, (byte) 0x11, (byte) 0x4b, (byte) 0xb5, (byte) 0x94,
+        (byte) 0xbe, (byte) 0x14, (byte) 0xaa, (byte) 0xaa, (byte) 0xe0, (byte) 0x38,
+        (byte) 0x1c, (byte) 0xce, (byte) 0x40, (byte) 0x61, (byte) 0xfc, (byte) 0x08,
+        (byte) 0xcb, (byte) 0x14, (byte) 0x2b, (byte) 0xa6, (byte) 0x54, (byte) 0xdf,
+        (byte) 0x05, (byte) 0x5c, (byte) 0x9b, (byte) 0x4f, (byte) 0x14, (byte) 0x93,
+        (byte) 0xb0, (byte) 0x70, (byte) 0xd9, (byte) 0x32, (byte) 0xdc, (byte) 0x24,
+        (byte) 0xe0, (byte) 0xae, (byte) 0x48, (byte) 0xfc, (byte) 0x53, (byte) 0xee,
+        (byte) 0x7c, (byte) 0x9f, (byte) 0x69, (byte) 0x34, (byte) 0xf4, (byte) 0x76,
+        (byte) 0xee, (byte) 0x67, (byte) 0xb2, (byte) 0xa7, (byte) 0x33, (byte) 0x1c,
+        (byte) 0x47, (byte) 0xff, (byte) 0x5c, (byte) 0xf0, (byte) 0xb8, (byte) 0x04,
+        (byte) 0x2c, (byte) 0xfd, (byte) 0xe2, (byte) 0xb1, (byte) 0x4a, (byte) 0x0a,
+        (byte) 0x69, (byte) 0x1c, (byte) 0x80, (byte) 0x2b, (byte) 0xb4, (byte) 0x50,
+        (byte) 0x65, (byte) 0x5c, (byte) 0x76, (byte) 0x78, (byte) 0x9a, (byte) 0x0c,
+        (byte) 0x05, (byte) 0x62, (byte) 0xf0, (byte) 0xc4, (byte) 0x1c, (byte) 0x38,
+        (byte) 0x15, (byte) 0xd0, (byte) 0xe2, (byte) 0x5a, (byte) 0x3d, (byte) 0xb6,
+        (byte) 0xe0, (byte) 0x88, (byte) 0x85, (byte) 0xd1, (byte) 0x4f, (byte) 0x7e,
+        (byte) 0xfc, (byte) 0x77, (byte) 0x0d, (byte) 0x2a, (byte) 0x45, (byte) 0xd5,
+        (byte) 0xf8, (byte) 0x3c, (byte) 0x7b, (byte) 0x2d, (byte) 0x1b, (byte) 0x82,
+        (byte) 0xfe, (byte) 0x58, (byte) 0x22, (byte) 0x47, (byte) 0x06, (byte) 0x58,
+        (byte) 0x8b, (byte) 0x4f, (byte) 0xfb, (byte) 0x9b, (byte) 0x1c, (byte) 0x70,
+        (byte) 0x36, (byte) 0x12, (byte) 0x04, (byte) 0x17, (byte) 0x47, (byte) 0x8a,
+        (byte) 0x0a, (byte) 0xec, (byte) 0x12, (byte) 0x3b, (byte) 0xf8, (byte) 0xd2,
+        (byte) 0xdc, (byte) 0x3c, (byte) 0xc8, (byte) 0x46, (byte) 0xc6, (byte) 0x51,
+        (byte) 0x06, (byte) 0x06, (byte) 0xcb, (byte) 0x84, (byte) 0x67, (byte) 0xb5,
+        (byte) 0x68, (byte) 0xd9, (byte) 0x9c, (byte) 0xd4, (byte) 0x16, (byte) 0x5c,
+        (byte) 0xb4, (byte) 0xe2, (byte) 0x55, (byte) 0xe6, (byte) 0x3a, (byte) 0x73,
+        (byte) 0x01, (byte) 0x1d, (byte) 0x6f, (byte) 0x30, (byte) 0x31, (byte) 0x59,
+        (byte) 0x8b, (byte) 0x2f, (byte) 0x4c, (byte) 0xe7, (byte) 0x86, (byte) 0x4c,
+        (byte) 0x39, (byte) 0x4e, (byte) 0x67, (byte) 0x3b, (byte) 0x22, (byte) 0x9b,
+        (byte) 0x85, (byte) 0x5a, (byte) 0xc3, (byte) 0x29, (byte) 0xaf, (byte) 0x8c,
+        (byte) 0x7c, (byte) 0x59, (byte) 0x4a, (byte) 0x24, (byte) 0xfa, (byte) 0xba,
+        (byte) 0x55, (byte) 0x40, (byte) 0x13, (byte) 0x64, (byte) 0xd8, (byte) 0xcb,
+        (byte) 0x4b, (byte) 0x98, (byte) 0x3f, (byte) 0xae, (byte) 0x20, (byte) 0xfd,
+        (byte) 0x8a, (byte) 0x50, (byte) 0x73, (byte) 0xe4,
+    };
+    /*
+     * echo -n 'This is a test of OAEP' | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_Plaintext = new byte[] {
+            (byte) 0x54, (byte) 0x68, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x69,
+            (byte) 0x73, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x74, (byte) 0x65,
+            (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x6f, (byte) 0x66, (byte) 0x20,
+            (byte) 0x4f, (byte) 0x41, (byte) 0x45, (byte) 0x50
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey rsakey.pem \
+     * -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -pkeyopt rsa_mgf1_md:sha1 \
+     * | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA1_MGF1_SHA1 = new byte[] {
+            (byte) 0x53, (byte) 0x71, (byte) 0x84, (byte) 0x2e, (byte) 0x01, (byte) 0x74,
+            (byte) 0x82, (byte) 0xb3, (byte) 0x01, (byte) 0xac, (byte) 0x2b, (byte) 0xbd,
+            (byte) 0x40, (byte) 0xa7, (byte) 0x5b, (byte) 0x60, (byte) 0xf1, (byte) 0xde,
+            (byte) 0x54, (byte) 0x1d, (byte) 0x94, (byte) 0xc1, (byte) 0x10, (byte) 0x31,
+            (byte) 0x6f, (byte) 0xa3, (byte) 0xd8, (byte) 0x41, (byte) 0x2e, (byte) 0x82,
+            (byte) 0xad, (byte) 0x07, (byte) 0x6f, (byte) 0x25, (byte) 0x6c, (byte) 0xb5,
+            (byte) 0xef, (byte) 0xc6, (byte) 0xa6, (byte) 0xfb, (byte) 0xb1, (byte) 0x9d,
+            (byte) 0x75, (byte) 0x67, (byte) 0xb0, (byte) 0x97, (byte) 0x21, (byte) 0x3c,
+            (byte) 0x17, (byte) 0x04, (byte) 0xdc, (byte) 0x4e, (byte) 0x7e, (byte) 0x3f,
+            (byte) 0x5c, (byte) 0x13, (byte) 0x5e, (byte) 0x15, (byte) 0x0f, (byte) 0xe2,
+            (byte) 0xa7, (byte) 0x62, (byte) 0x6a, (byte) 0x08, (byte) 0xb1, (byte) 0xbc,
+            (byte) 0x2f, (byte) 0xcb, (byte) 0xb5, (byte) 0x96, (byte) 0x2d, (byte) 0xec,
+            (byte) 0x71, (byte) 0x4d, (byte) 0x59, (byte) 0x6e, (byte) 0x27, (byte) 0x85,
+            (byte) 0x87, (byte) 0x9b, (byte) 0xcc, (byte) 0x40, (byte) 0x32, (byte) 0x09,
+            (byte) 0x06, (byte) 0xe6, (byte) 0x7d, (byte) 0xdf, (byte) 0xeb, (byte) 0x2f,
+            (byte) 0xa8, (byte) 0x1c, (byte) 0x53, (byte) 0xdb, (byte) 0xa7, (byte) 0x48,
+            (byte) 0xf5, (byte) 0xbf, (byte) 0x2f, (byte) 0xbb, (byte) 0xee, (byte) 0xc7,
+            (byte) 0x55, (byte) 0x5e, (byte) 0xc4, (byte) 0x1c, (byte) 0x84, (byte) 0xed,
+            (byte) 0x97, (byte) 0x7e, (byte) 0xce, (byte) 0xa5, (byte) 0x69, (byte) 0x73,
+            (byte) 0xb3, (byte) 0xe0, (byte) 0x8c, (byte) 0x2a, (byte) 0xf2, (byte) 0xc7,
+            (byte) 0x65, (byte) 0xff, (byte) 0x10, (byte) 0xed, (byte) 0x25, (byte) 0xf0,
+            (byte) 0xf8, (byte) 0xda, (byte) 0x2f, (byte) 0x7f, (byte) 0xe0, (byte) 0x69,
+            (byte) 0xed, (byte) 0xb1, (byte) 0x0e, (byte) 0xcb, (byte) 0x43, (byte) 0xe4,
+            (byte) 0x31, (byte) 0xe6, (byte) 0x52, (byte) 0xfd, (byte) 0xa7, (byte) 0xe5,
+            (byte) 0x21, (byte) 0xd0, (byte) 0x67, (byte) 0x0a, (byte) 0xc1, (byte) 0xa1,
+            (byte) 0xb9, (byte) 0x04, (byte) 0xdb, (byte) 0x98, (byte) 0x4f, (byte) 0xf9,
+            (byte) 0x5c, (byte) 0x60, (byte) 0x4d, (byte) 0xac, (byte) 0x7a, (byte) 0x69,
+            (byte) 0xbd, (byte) 0x63, (byte) 0x0d, (byte) 0xb2, (byte) 0x01, (byte) 0x83,
+            (byte) 0xd7, (byte) 0x22, (byte) 0x5d, (byte) 0xed, (byte) 0xbd, (byte) 0x32,
+            (byte) 0x98, (byte) 0xd1, (byte) 0x4a, (byte) 0x2e, (byte) 0xb7, (byte) 0xb1,
+            (byte) 0x6d, (byte) 0x8a, (byte) 0x8f, (byte) 0xef, (byte) 0xc3, (byte) 0x89,
+            (byte) 0xdf, (byte) 0xa5, (byte) 0xac, (byte) 0xfb, (byte) 0x38, (byte) 0x61,
+            (byte) 0x32, (byte) 0xc5, (byte) 0x19, (byte) 0x83, (byte) 0x1f, (byte) 0x9c,
+            (byte) 0x45, (byte) 0x58, (byte) 0xdd, (byte) 0xa3, (byte) 0x57, (byte) 0xe4,
+            (byte) 0x91, (byte) 0xd2, (byte) 0x11, (byte) 0xf8, (byte) 0x96, (byte) 0x36,
+            (byte) 0x67, (byte) 0x99, (byte) 0x2b, (byte) 0x62, (byte) 0x21, (byte) 0xe3,
+            (byte) 0xa8, (byte) 0x5e, (byte) 0xa4, (byte) 0x2e, (byte) 0x0c, (byte) 0x29,
+            (byte) 0xf9, (byte) 0xcd, (byte) 0xfa, (byte) 0xbe, (byte) 0x3f, (byte) 0xd8,
+            (byte) 0xec, (byte) 0x6b, (byte) 0x32, (byte) 0xb3, (byte) 0x40, (byte) 0x4f,
+            (byte) 0x48, (byte) 0xe3, (byte) 0x14, (byte) 0x87, (byte) 0xa7, (byte) 0x5c,
+            (byte) 0xba, (byte) 0xdf, (byte) 0x0e, (byte) 0x64, (byte) 0xdc, (byte) 0xe2,
+            (byte) 0x51, (byte) 0xf4, (byte) 0x41, (byte) 0x25, (byte) 0x23, (byte) 0xc8,
+            (byte) 0x50, (byte) 0x1e, (byte) 0x9e, (byte) 0xb0
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey rsakey.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha1 | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA256_MGF1_SHA1 = new byte[] {
+            (byte) 0x25, (byte) 0x9f, (byte) 0xc3, (byte) 0x69, (byte) 0xbc, (byte) 0x3f,
+            (byte) 0xe7, (byte) 0x9e, (byte) 0x76, (byte) 0xef, (byte) 0x6c, (byte) 0xd2,
+            (byte) 0x2b, (byte) 0x7b, (byte) 0xf0, (byte) 0xeb, (byte) 0xc2, (byte) 0x28,
+            (byte) 0x40, (byte) 0x4e, (byte) 0x9b, (byte) 0x2a, (byte) 0x4e, (byte) 0xa4,
+            (byte) 0x79, (byte) 0x66, (byte) 0xf1, (byte) 0x10, (byte) 0x96, (byte) 0x8c,
+            (byte) 0x58, (byte) 0x92, (byte) 0xb7, (byte) 0x70, (byte) 0xed, (byte) 0x3a,
+            (byte) 0xe0, (byte) 0x99, (byte) 0xd1, (byte) 0x80, (byte) 0x4b, (byte) 0x53,
+            (byte) 0x70, (byte) 0x9b, (byte) 0x51, (byte) 0xbf, (byte) 0xc1, (byte) 0x3a,
+            (byte) 0x70, (byte) 0xc5, (byte) 0x79, (byte) 0x21, (byte) 0x6e, (byte) 0xb3,
+            (byte) 0xf7, (byte) 0xa9, (byte) 0xe6, (byte) 0xcb, (byte) 0x70, (byte) 0xe4,
+            (byte) 0xf3, (byte) 0x4f, (byte) 0x45, (byte) 0xcf, (byte) 0xb7, (byte) 0x2b,
+            (byte) 0x38, (byte) 0xfd, (byte) 0x5d, (byte) 0x9a, (byte) 0x53, (byte) 0xc5,
+            (byte) 0x05, (byte) 0x74, (byte) 0x8d, (byte) 0x1d, (byte) 0x6e, (byte) 0x83,
+            (byte) 0xaa, (byte) 0x71, (byte) 0xc5, (byte) 0xe1, (byte) 0xa1, (byte) 0xa6,
+            (byte) 0xf3, (byte) 0xee, (byte) 0x5f, (byte) 0x9e, (byte) 0x4f, (byte) 0xe8,
+            (byte) 0x15, (byte) 0xd5, (byte) 0xa9, (byte) 0x1b, (byte) 0xa6, (byte) 0x41,
+            (byte) 0x2b, (byte) 0x18, (byte) 0x13, (byte) 0x20, (byte) 0x9f, (byte) 0x6b,
+            (byte) 0xf1, (byte) 0xd8, (byte) 0xf4, (byte) 0x87, (byte) 0xfa, (byte) 0x80,
+            (byte) 0xec, (byte) 0x0e, (byte) 0xa4, (byte) 0x4b, (byte) 0x24, (byte) 0x03,
+            (byte) 0x14, (byte) 0x25, (byte) 0xf2, (byte) 0x20, (byte) 0xfc, (byte) 0x52,
+            (byte) 0xf9, (byte) 0xd6, (byte) 0x7a, (byte) 0x4a, (byte) 0x45, (byte) 0x33,
+            (byte) 0xec, (byte) 0xde, (byte) 0x3c, (byte) 0x5b, (byte) 0xf2, (byte) 0xdc,
+            (byte) 0x8e, (byte) 0xc6, (byte) 0xb3, (byte) 0x26, (byte) 0xd3, (byte) 0x68,
+            (byte) 0xa7, (byte) 0xd8, (byte) 0x3a, (byte) 0xde, (byte) 0xa9, (byte) 0x25,
+            (byte) 0x1d, (byte) 0x42, (byte) 0x75, (byte) 0x66, (byte) 0x16, (byte) 0x29,
+            (byte) 0xad, (byte) 0x09, (byte) 0x74, (byte) 0x41, (byte) 0xbb, (byte) 0x45,
+            (byte) 0x39, (byte) 0x04, (byte) 0x7a, (byte) 0x93, (byte) 0xad, (byte) 0x1c,
+            (byte) 0xa6, (byte) 0x38, (byte) 0xf4, (byte) 0xac, (byte) 0xca, (byte) 0x5a,
+            (byte) 0xab, (byte) 0x92, (byte) 0x76, (byte) 0x26, (byte) 0x3c, (byte) 0xeb,
+            (byte) 0xda, (byte) 0xfc, (byte) 0x25, (byte) 0x93, (byte) 0x23, (byte) 0x01,
+            (byte) 0xe2, (byte) 0xac, (byte) 0x5e, (byte) 0x4c, (byte) 0xb7, (byte) 0xbc,
+            (byte) 0x5b, (byte) 0xaa, (byte) 0x14, (byte) 0xe9, (byte) 0xbf, (byte) 0x2d,
+            (byte) 0x3a, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x4d, (byte) 0x0e,
+            (byte) 0x0a, (byte) 0x82, (byte) 0x3c, (byte) 0xd9, (byte) 0x32, (byte) 0xc1,
+            (byte) 0xc4, (byte) 0xa2, (byte) 0x46, (byte) 0x71, (byte) 0x10, (byte) 0x54,
+            (byte) 0x1a, (byte) 0xa6, (byte) 0xaa, (byte) 0x64, (byte) 0xe7, (byte) 0xc2,
+            (byte) 0xae, (byte) 0xbc, (byte) 0x3d, (byte) 0xa4, (byte) 0xa8, (byte) 0xd1,
+            (byte) 0xb7, (byte) 0x27, (byte) 0xef, (byte) 0x5f, (byte) 0xe7, (byte) 0xa7,
+            (byte) 0x5d, (byte) 0xa0, (byte) 0xcd, (byte) 0x57, (byte) 0xf1, (byte) 0xe0,
+            (byte) 0xd8, (byte) 0x42, (byte) 0x10, (byte) 0x77, (byte) 0xc3, (byte) 0xa7,
+            (byte) 0x1e, (byte) 0x0c, (byte) 0x37, (byte) 0x16, (byte) 0x11, (byte) 0x94,
+            (byte) 0x21, (byte) 0xf2, (byte) 0xca, (byte) 0x60, (byte) 0xce, (byte) 0xca,
+            (byte) 0x59, (byte) 0xf9, (byte) 0xe5, (byte) 0xe4
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha1 -pkeyopt rsa_oaep_label:010203FFA00A | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA256_MGF1_SHA1_LABEL = new byte[] {
+            (byte) 0x80, (byte) 0xb1, (byte) 0xf2, (byte) 0xc2, (byte) 0x03, (byte) 0xc5,
+            (byte) 0xdf, (byte) 0xbd, (byte) 0xed, (byte) 0xfe, (byte) 0xe6, (byte) 0xff,
+            (byte) 0xd3, (byte) 0x38, (byte) 0x1e, (byte) 0x6d, (byte) 0xae, (byte) 0x47,
+            (byte) 0xfe, (byte) 0x19, (byte) 0xf9, (byte) 0x8c, (byte) 0xf1, (byte) 0x4d,
+            (byte) 0x18, (byte) 0x2b, (byte) 0x7e, (byte) 0x8e, (byte) 0x47, (byte) 0x39,
+            (byte) 0xa8, (byte) 0x04, (byte) 0xc4, (byte) 0x7d, (byte) 0x56, (byte) 0x03,
+            (byte) 0x15, (byte) 0x92, (byte) 0x18, (byte) 0xde, (byte) 0x56, (byte) 0xb3,
+            (byte) 0x01, (byte) 0x93, (byte) 0x16, (byte) 0xe3, (byte) 0xfa, (byte) 0xaa,
+            (byte) 0xf3, (byte) 0x73, (byte) 0x39, (byte) 0x26, (byte) 0xfb, (byte) 0xb0,
+            (byte) 0x18, (byte) 0x20, (byte) 0xdb, (byte) 0xa1, (byte) 0xbf, (byte) 0x31,
+            (byte) 0x22, (byte) 0xc8, (byte) 0x1d, (byte) 0xdb, (byte) 0xa0, (byte) 0x5a,
+            (byte) 0x22, (byte) 0xcd, (byte) 0x09, (byte) 0xb3, (byte) 0xcb, (byte) 0xa2,
+            (byte) 0x46, (byte) 0x14, (byte) 0x35, (byte) 0x66, (byte) 0xe8, (byte) 0xb8,
+            (byte) 0x07, (byte) 0x23, (byte) 0xc5, (byte) 0xae, (byte) 0xe6, (byte) 0xf1,
+            (byte) 0x7a, (byte) 0x8f, (byte) 0x5c, (byte) 0x44, (byte) 0x34, (byte) 0xbf,
+            (byte) 0xd6, (byte) 0xf8, (byte) 0x0c, (byte) 0xc7, (byte) 0x8d, (byte) 0xcd,
+            (byte) 0x23, (byte) 0x84, (byte) 0xbe, (byte) 0x9b, (byte) 0xbf, (byte) 0x9a,
+            (byte) 0x70, (byte) 0x0f, (byte) 0x18, (byte) 0xc0, (byte) 0x6f, (byte) 0x23,
+            (byte) 0x67, (byte) 0xf8, (byte) 0xbb, (byte) 0xce, (byte) 0xc2, (byte) 0x47,
+            (byte) 0x82, (byte) 0xa0, (byte) 0xa5, (byte) 0x60, (byte) 0xcd, (byte) 0x25,
+            (byte) 0xa5, (byte) 0x4b, (byte) 0xe4, (byte) 0x06, (byte) 0x7f, (byte) 0x46,
+            (byte) 0x62, (byte) 0x86, (byte) 0x94, (byte) 0xbc, (byte) 0x7f, (byte) 0xb0,
+            (byte) 0x2e, (byte) 0xc1, (byte) 0x8c, (byte) 0x6c, (byte) 0x58, (byte) 0x05,
+            (byte) 0x6f, (byte) 0x35, (byte) 0x76, (byte) 0xd3, (byte) 0xdf, (byte) 0xc0,
+            (byte) 0xdd, (byte) 0x66, (byte) 0xbe, (byte) 0xa1, (byte) 0x7e, (byte) 0x52,
+            (byte) 0xed, (byte) 0x81, (byte) 0x0e, (byte) 0x2d, (byte) 0x5b, (byte) 0x2b,
+            (byte) 0xe3, (byte) 0x52, (byte) 0x0e, (byte) 0x56, (byte) 0x9b, (byte) 0x05,
+            (byte) 0x72, (byte) 0xa8, (byte) 0xc8, (byte) 0x57, (byte) 0x22, (byte) 0x67,
+            (byte) 0x0e, (byte) 0x5f, (byte) 0x01, (byte) 0xf2, (byte) 0x69, (byte) 0x66,
+            (byte) 0x6a, (byte) 0x47, (byte) 0x4f, (byte) 0x78, (byte) 0xb3, (byte) 0x1e,
+            (byte) 0x7d, (byte) 0xce, (byte) 0xb3, (byte) 0x35, (byte) 0xdf, (byte) 0x23,
+            (byte) 0xac, (byte) 0xf8, (byte) 0x88, (byte) 0xa1, (byte) 0xde, (byte) 0x38,
+            (byte) 0x96, (byte) 0xfd, (byte) 0xa2, (byte) 0x5d, (byte) 0x09, (byte) 0x52,
+            (byte) 0x11, (byte) 0x2b, (byte) 0x21, (byte) 0xf0, (byte) 0x0d, (byte) 0x4c,
+            (byte) 0x15, (byte) 0xc3, (byte) 0x88, (byte) 0x2b, (byte) 0xf6, (byte) 0x2b,
+            (byte) 0xe3, (byte) 0xfd, (byte) 0x52, (byte) 0xf0, (byte) 0x09, (byte) 0x5c,
+            (byte) 0x4f, (byte) 0x5b, (byte) 0x8b, (byte) 0x84, (byte) 0x71, (byte) 0x72,
+            (byte) 0x8d, (byte) 0xaa, (byte) 0x6c, (byte) 0x55, (byte) 0xba, (byte) 0xe7,
+            (byte) 0x9c, (byte) 0xba, (byte) 0xbf, (byte) 0xf4, (byte) 0x09, (byte) 0x0a,
+            (byte) 0x60, (byte) 0xec, (byte) 0x53, (byte) 0xa4, (byte) 0x01, (byte) 0xa5,
+            (byte) 0xf2, (byte) 0x58, (byte) 0xab, (byte) 0x95, (byte) 0x68, (byte) 0x79,
+            (byte) 0x0b, (byte) 0xc3, (byte) 0xc4, (byte) 0x00, (byte) 0x68, (byte) 0x19,
+            (byte) 0xca, (byte) 0x07, (byte) 0x0d, (byte) 0x32
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey rsakey.pem \
+     * -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha224 -pkeyopt rsa_mgf1_md:sha224 \
+     * | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA224_MGF1_SHA224 = new byte[] {
+            (byte) 0xae, (byte) 0xdd, (byte) 0xe6, (byte) 0xab, (byte) 0x00, (byte) 0xd6,
+            (byte) 0x1e, (byte) 0x7e, (byte) 0x85, (byte) 0x63, (byte) 0xab, (byte) 0x51,
+            (byte) 0x79, (byte) 0x92, (byte) 0xf1, (byte) 0xb9, (byte) 0x4f, (byte) 0x23,
+            (byte) 0xae, (byte) 0xf7, (byte) 0x1b, (byte) 0x5f, (byte) 0x10, (byte) 0x5b,
+            (byte) 0xa5, (byte) 0x15, (byte) 0x87, (byte) 0xa3, (byte) 0xbb, (byte) 0x26,
+            (byte) 0xfe, (byte) 0x7f, (byte) 0xc0, (byte) 0xa3, (byte) 0x67, (byte) 0x95,
+            (byte) 0xda, (byte) 0xc4, (byte) 0x6f, (byte) 0x6e, (byte) 0x08, (byte) 0x23,
+            (byte) 0x28, (byte) 0x0b, (byte) 0xdd, (byte) 0x29, (byte) 0x29, (byte) 0xdc,
+            (byte) 0xb0, (byte) 0x35, (byte) 0x16, (byte) 0x2e, (byte) 0x0f, (byte) 0xb9,
+            (byte) 0x1d, (byte) 0x90, (byte) 0x27, (byte) 0x68, (byte) 0xc7, (byte) 0x92,
+            (byte) 0x52, (byte) 0x8a, (byte) 0x1d, (byte) 0x48, (byte) 0x6a, (byte) 0x7d,
+            (byte) 0x0b, (byte) 0xf6, (byte) 0x35, (byte) 0xca, (byte) 0xe1, (byte) 0x57,
+            (byte) 0xdd, (byte) 0x36, (byte) 0x3b, (byte) 0x51, (byte) 0x45, (byte) 0x77,
+            (byte) 0x28, (byte) 0x4f, (byte) 0x98, (byte) 0xc0, (byte) 0xe0, (byte) 0xa7,
+            (byte) 0x51, (byte) 0x98, (byte) 0x84, (byte) 0x7a, (byte) 0x29, (byte) 0x05,
+            (byte) 0x9f, (byte) 0x60, (byte) 0x66, (byte) 0xf6, (byte) 0x83, (byte) 0xcd,
+            (byte) 0x03, (byte) 0x3e, (byte) 0x82, (byte) 0x0f, (byte) 0x57, (byte) 0x4b,
+            (byte) 0x27, (byte) 0x14, (byte) 0xf6, (byte) 0xc8, (byte) 0x5b, (byte) 0xed,
+            (byte) 0xc3, (byte) 0x77, (byte) 0x6f, (byte) 0xec, (byte) 0x0e, (byte) 0xae,
+            (byte) 0x59, (byte) 0xbe, (byte) 0x68, (byte) 0x76, (byte) 0x16, (byte) 0x17,
+            (byte) 0x77, (byte) 0xe2, (byte) 0xbd, (byte) 0xe0, (byte) 0x5a, (byte) 0x14,
+            (byte) 0xd9, (byte) 0xf4, (byte) 0x3f, (byte) 0x50, (byte) 0x31, (byte) 0xf0,
+            (byte) 0x0c, (byte) 0x82, (byte) 0x6c, (byte) 0xcc, (byte) 0x81, (byte) 0x84,
+            (byte) 0x3e, (byte) 0x63, (byte) 0x93, (byte) 0xe7, (byte) 0x12, (byte) 0x2d,
+            (byte) 0xc9, (byte) 0xa3, (byte) 0xe3, (byte) 0xce, (byte) 0xfd, (byte) 0xc7,
+            (byte) 0xe1, (byte) 0xef, (byte) 0xa4, (byte) 0x16, (byte) 0x5c, (byte) 0x60,
+            (byte) 0xb1, (byte) 0x80, (byte) 0x31, (byte) 0x15, (byte) 0x5c, (byte) 0x35,
+            (byte) 0x25, (byte) 0x0b, (byte) 0x89, (byte) 0xe4, (byte) 0x56, (byte) 0x74,
+            (byte) 0x8b, (byte) 0xaf, (byte) 0x8e, (byte) 0xe9, (byte) 0xe2, (byte) 0x37,
+            (byte) 0x17, (byte) 0xe6, (byte) 0x7b, (byte) 0x78, (byte) 0xd8, (byte) 0x2c,
+            (byte) 0x27, (byte) 0x52, (byte) 0x21, (byte) 0x96, (byte) 0xa0, (byte) 0x92,
+            (byte) 0x95, (byte) 0x64, (byte) 0xc3, (byte) 0x7f, (byte) 0x45, (byte) 0xfc,
+            (byte) 0x3d, (byte) 0x48, (byte) 0x4a, (byte) 0xd5, (byte) 0xa4, (byte) 0x0a,
+            (byte) 0x57, (byte) 0x07, (byte) 0x57, (byte) 0x95, (byte) 0x9f, (byte) 0x2f,
+            (byte) 0x75, (byte) 0x32, (byte) 0x2a, (byte) 0x4d, (byte) 0x64, (byte) 0xbd,
+            (byte) 0xb1, (byte) 0xe0, (byte) 0x46, (byte) 0x4f, (byte) 0xe8, (byte) 0x6c,
+            (byte) 0x4b, (byte) 0x77, (byte) 0xcc, (byte) 0x36, (byte) 0x87, (byte) 0x05,
+            (byte) 0x56, (byte) 0x9a, (byte) 0xe4, (byte) 0x2c, (byte) 0x43, (byte) 0xfd,
+            (byte) 0x34, (byte) 0x97, (byte) 0xf8, (byte) 0xd7, (byte) 0x91, (byte) 0xff,
+            (byte) 0x56, (byte) 0x86, (byte) 0x17, (byte) 0x49, (byte) 0x0a, (byte) 0x52,
+            (byte) 0xfb, (byte) 0xe5, (byte) 0x49, (byte) 0xdf, (byte) 0xc1, (byte) 0x28,
+            (byte) 0x9d, (byte) 0x85, (byte) 0x66, (byte) 0x9d, (byte) 0x1d, (byte) 0xa4,
+            (byte) 0x7e, (byte) 0x9a, (byte) 0x5b, (byte) 0x30
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt \
+     * -pkeyopt rsa_padding_mode:oaep -pkey rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 \
+     * | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA256_MGF1_SHA256 = new byte[] {
+            (byte) 0x6a, (byte) 0x2b, (byte) 0xb2, (byte) 0xa3, (byte) 0x26, (byte) 0xa6,
+            (byte) 0x7a, (byte) 0x4a, (byte) 0x1f, (byte) 0xe5, (byte) 0xc8, (byte) 0x94,
+            (byte) 0x11, (byte) 0x1a, (byte) 0x92, (byte) 0x07, (byte) 0x0a, (byte) 0xf4,
+            (byte) 0x07, (byte) 0x0b, (byte) 0xd6, (byte) 0x37, (byte) 0xa5, (byte) 0x5d,
+            (byte) 0x16, (byte) 0x0a, (byte) 0x7d, (byte) 0x13, (byte) 0x27, (byte) 0x32,
+            (byte) 0x5a, (byte) 0xc3, (byte) 0x0d, (byte) 0x7a, (byte) 0x54, (byte) 0xfe,
+            (byte) 0x02, (byte) 0x28, (byte) 0xc6, (byte) 0x8e, (byte) 0x32, (byte) 0x7b,
+            (byte) 0x0a, (byte) 0x52, (byte) 0xf8, (byte) 0xe6, (byte) 0xab, (byte) 0x16,
+            (byte) 0x77, (byte) 0x7c, (byte) 0x53, (byte) 0xcd, (byte) 0xb0, (byte) 0xb6,
+            (byte) 0x90, (byte) 0xce, (byte) 0x7b, (byte) 0xa5, (byte) 0xdb, (byte) 0xab,
+            (byte) 0xfd, (byte) 0xf5, (byte) 0xbb, (byte) 0x49, (byte) 0x63, (byte) 0xb7,
+            (byte) 0xa8, (byte) 0x3e, (byte) 0x53, (byte) 0xf1, (byte) 0x00, (byte) 0x4d,
+            (byte) 0x72, (byte) 0x15, (byte) 0x34, (byte) 0xa8, (byte) 0x5b, (byte) 0x00,
+            (byte) 0x01, (byte) 0x75, (byte) 0xdc, (byte) 0xb6, (byte) 0xd1, (byte) 0xdf,
+            (byte) 0xcb, (byte) 0x93, (byte) 0xf3, (byte) 0x31, (byte) 0x04, (byte) 0x7e,
+            (byte) 0x48, (byte) 0x3e, (byte) 0xc9, (byte) 0xaf, (byte) 0xd7, (byte) 0xbd,
+            (byte) 0x9e, (byte) 0x73, (byte) 0x01, (byte) 0x79, (byte) 0xf8, (byte) 0xdc,
+            (byte) 0x46, (byte) 0x31, (byte) 0x55, (byte) 0x83, (byte) 0x21, (byte) 0xd1,
+            (byte) 0x19, (byte) 0x0b, (byte) 0x57, (byte) 0xf1, (byte) 0x06, (byte) 0xb9,
+            (byte) 0x32, (byte) 0x0e, (byte) 0x9d, (byte) 0x38, (byte) 0x53, (byte) 0x94,
+            (byte) 0x96, (byte) 0xd4, (byte) 0x6d, (byte) 0x18, (byte) 0xe2, (byte) 0xe3,
+            (byte) 0xcd, (byte) 0xfa, (byte) 0xfe, (byte) 0xb3, (byte) 0xe3, (byte) 0x27,
+            (byte) 0xd7, (byte) 0x45, (byte) 0xe8, (byte) 0x46, (byte) 0x6b, (byte) 0x06,
+            (byte) 0x0f, (byte) 0x5e, (byte) 0x24, (byte) 0x02, (byte) 0xef, (byte) 0xa2,
+            (byte) 0x69, (byte) 0xe6, (byte) 0x15, (byte) 0xb3, (byte) 0x8f, (byte) 0x71,
+            (byte) 0x97, (byte) 0x39, (byte) 0xfb, (byte) 0x32, (byte) 0xe0, (byte) 0xe5,
+            (byte) 0xac, (byte) 0x46, (byte) 0xb4, (byte) 0xe7, (byte) 0x3d, (byte) 0x89,
+            (byte) 0xba, (byte) 0xd9, (byte) 0x4c, (byte) 0x25, (byte) 0x97, (byte) 0xef,
+            (byte) 0xe6, (byte) 0x17, (byte) 0x23, (byte) 0x4e, (byte) 0xc8, (byte) 0xdb,
+            (byte) 0x18, (byte) 0x9b, (byte) 0xba, (byte) 0xb5, (byte) 0x7e, (byte) 0x19,
+            (byte) 0x4d, (byte) 0x95, (byte) 0x7d, (byte) 0x60, (byte) 0x1b, (byte) 0xa7,
+            (byte) 0x06, (byte) 0x1e, (byte) 0x99, (byte) 0x4a, (byte) 0xf2, (byte) 0x82,
+            (byte) 0x71, (byte) 0x62, (byte) 0x41, (byte) 0xa4, (byte) 0xa7, (byte) 0xdb,
+            (byte) 0x88, (byte) 0xb0, (byte) 0x4a, (byte) 0xc7, (byte) 0x3b, (byte) 0xce,
+            (byte) 0x91, (byte) 0x4f, (byte) 0xc7, (byte) 0xca, (byte) 0x6f, (byte) 0x89,
+            (byte) 0xac, (byte) 0x1a, (byte) 0x36, (byte) 0x84, (byte) 0x0c, (byte) 0x97,
+            (byte) 0xa0, (byte) 0x1a, (byte) 0x08, (byte) 0x6f, (byte) 0x70, (byte) 0xf3,
+            (byte) 0x94, (byte) 0xa0, (byte) 0x0f, (byte) 0x44, (byte) 0xdd, (byte) 0x86,
+            (byte) 0x9d, (byte) 0x2c, (byte) 0xac, (byte) 0x43, (byte) 0xed, (byte) 0xb8,
+            (byte) 0xa1, (byte) 0x66, (byte) 0xf3, (byte) 0xd3, (byte) 0x5c, (byte) 0xe5,
+            (byte) 0xe2, (byte) 0x4c, (byte) 0x7e, (byte) 0xda, (byte) 0x20, (byte) 0xbd,
+            (byte) 0x5a, (byte) 0x75, (byte) 0x12, (byte) 0x31, (byte) 0x23, (byte) 0x02,
+            (byte) 0xb5, (byte) 0x1f, (byte) 0x38, (byte) 0x98
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt \
+     * -pkeyopt rsa_padding_mode:oaep -pkey rsa_oaep_md:sha384 -pkeyopt rsa_mgf1_md:sha384 \
+     * | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA384_MGF1_SHA384 = new byte[] {
+            (byte) 0xa1, (byte) 0xb3, (byte) 0x3b, (byte) 0x34, (byte) 0x69, (byte) 0x9e,
+            (byte) 0xd8, (byte) 0xa0, (byte) 0x37, (byte) 0x2c, (byte) 0xeb, (byte) 0xef,
+            (byte) 0xf2, (byte) 0xaf, (byte) 0xfa, (byte) 0x63, (byte) 0x5d, (byte) 0x88,
+            (byte) 0xac, (byte) 0x51, (byte) 0xd4, (byte) 0x7f, (byte) 0x85, (byte) 0xf0,
+            (byte) 0x5e, (byte) 0xb4, (byte) 0x81, (byte) 0x7c, (byte) 0x82, (byte) 0x4f,
+            (byte) 0x92, (byte) 0xf7, (byte) 0x77, (byte) 0x48, (byte) 0x4c, (byte) 0xb1,
+            (byte) 0x42, (byte) 0xb3, (byte) 0x0e, (byte) 0x94, (byte) 0xc8, (byte) 0x5a,
+            (byte) 0xae, (byte) 0xed, (byte) 0x8d, (byte) 0x51, (byte) 0x72, (byte) 0x6b,
+            (byte) 0xa9, (byte) 0xd4, (byte) 0x1e, (byte) 0xbe, (byte) 0x38, (byte) 0x2c,
+            (byte) 0xd0, (byte) 0x43, (byte) 0xae, (byte) 0xb4, (byte) 0x30, (byte) 0xa9,
+            (byte) 0x93, (byte) 0x47, (byte) 0xb5, (byte) 0x9d, (byte) 0x03, (byte) 0x92,
+            (byte) 0x25, (byte) 0x74, (byte) 0xed, (byte) 0xfa, (byte) 0xfe, (byte) 0xf1,
+            (byte) 0xba, (byte) 0x04, (byte) 0x3a, (byte) 0x4d, (byte) 0x6d, (byte) 0x9a,
+            (byte) 0x0d, (byte) 0x95, (byte) 0x02, (byte) 0xb0, (byte) 0xac, (byte) 0x77,
+            (byte) 0x11, (byte) 0x44, (byte) 0xeb, (byte) 0xd2, (byte) 0x02, (byte) 0x90,
+            (byte) 0xea, (byte) 0x2f, (byte) 0x68, (byte) 0x2a, (byte) 0x69, (byte) 0xcf,
+            (byte) 0x45, (byte) 0x34, (byte) 0xff, (byte) 0x00, (byte) 0xc6, (byte) 0x3c,
+            (byte) 0x0b, (byte) 0x2c, (byte) 0x5f, (byte) 0x8c, (byte) 0x2c, (byte) 0xbf,
+            (byte) 0xc2, (byte) 0x4b, (byte) 0x16, (byte) 0x07, (byte) 0x84, (byte) 0x74,
+            (byte) 0xf0, (byte) 0x7a, (byte) 0x01, (byte) 0x7e, (byte) 0x74, (byte) 0x01,
+            (byte) 0x88, (byte) 0xce, (byte) 0xda, (byte) 0xe4, (byte) 0x21, (byte) 0x89,
+            (byte) 0xfc, (byte) 0xac, (byte) 0x68, (byte) 0xdb, (byte) 0xfc, (byte) 0x5f,
+            (byte) 0x3f, (byte) 0x00, (byte) 0xd9, (byte) 0x32, (byte) 0x1d, (byte) 0xa5,
+            (byte) 0xec, (byte) 0x72, (byte) 0x46, (byte) 0x23, (byte) 0xe5, (byte) 0x7f,
+            (byte) 0x49, (byte) 0x0e, (byte) 0x3e, (byte) 0xf2, (byte) 0x2b, (byte) 0x16,
+            (byte) 0x52, (byte) 0x9f, (byte) 0x9d, (byte) 0x0c, (byte) 0xfe, (byte) 0xab,
+            (byte) 0xdd, (byte) 0x77, (byte) 0x77, (byte) 0x94, (byte) 0xa4, (byte) 0x92,
+            (byte) 0xa2, (byte) 0x41, (byte) 0x0d, (byte) 0x4b, (byte) 0x57, (byte) 0x80,
+            (byte) 0xd6, (byte) 0x74, (byte) 0x63, (byte) 0xd5, (byte) 0xbf, (byte) 0x5c,
+            (byte) 0xa0, (byte) 0xda, (byte) 0x3c, (byte) 0xe6, (byte) 0xbf, (byte) 0xa4,
+            (byte) 0xc3, (byte) 0xfb, (byte) 0x46, (byte) 0x3b, (byte) 0x73, (byte) 0x30,
+            (byte) 0x4b, (byte) 0x57, (byte) 0x27, (byte) 0x0c, (byte) 0x81, (byte) 0xde,
+            (byte) 0x8a, (byte) 0x01, (byte) 0xe5, (byte) 0x7e, (byte) 0xe0, (byte) 0x16,
+            (byte) 0x11, (byte) 0x24, (byte) 0x34, (byte) 0x22, (byte) 0x01, (byte) 0x9f,
+            (byte) 0xe6, (byte) 0xa9, (byte) 0xfb, (byte) 0xad, (byte) 0x55, (byte) 0x17,
+            (byte) 0x2a, (byte) 0x92, (byte) 0x87, (byte) 0xf3, (byte) 0x72, (byte) 0xc9,
+            (byte) 0x3d, (byte) 0xc9, (byte) 0x2e, (byte) 0x32, (byte) 0x8e, (byte) 0xbb,
+            (byte) 0xdc, (byte) 0x1b, (byte) 0xa7, (byte) 0x7b, (byte) 0x73, (byte) 0xd7,
+            (byte) 0xf4, (byte) 0xad, (byte) 0xa9, (byte) 0x3a, (byte) 0xf7, (byte) 0xa8,
+            (byte) 0x82, (byte) 0x92, (byte) 0x40, (byte) 0xd4, (byte) 0x51, (byte) 0x87,
+            (byte) 0xe1, (byte) 0xb7, (byte) 0x4f, (byte) 0x91, (byte) 0x75, (byte) 0x5b,
+            (byte) 0x03, (byte) 0x9d, (byte) 0xa1, (byte) 0xd4, (byte) 0x00, (byte) 0x05,
+            (byte) 0x79, (byte) 0x42, (byte) 0x93, (byte) 0x76
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt \
+     * -pkeyopt rsa_padding_mode:oaep -pkey rsa_oaep_md:sha512 -pkeyopt rsa_mgf1_md:sha512 \
+     * | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA512_MGF1_SHA512 = new byte[] {
+            (byte) 0x75, (byte) 0x0f, (byte) 0xf9, (byte) 0x21, (byte) 0xca, (byte) 0xcc,
+            (byte) 0x0e, (byte) 0x13, (byte) 0x9e, (byte) 0x38, (byte) 0xa4, (byte) 0xa7,
+            (byte) 0xee, (byte) 0x61, (byte) 0x6d, (byte) 0x56, (byte) 0xea, (byte) 0x36,
+            (byte) 0xeb, (byte) 0xec, (byte) 0xfa, (byte) 0x1a, (byte) 0xeb, (byte) 0x0c,
+            (byte) 0xb2, (byte) 0x58, (byte) 0x9d, (byte) 0xde, (byte) 0x47, (byte) 0x27,
+            (byte) 0x2d, (byte) 0xbd, (byte) 0x8b, (byte) 0xa7, (byte) 0xf1, (byte) 0x8b,
+            (byte) 0xba, (byte) 0x4c, (byte) 0xab, (byte) 0x39, (byte) 0x6a, (byte) 0x82,
+            (byte) 0x0d, (byte) 0xaf, (byte) 0x4c, (byte) 0xde, (byte) 0xdb, (byte) 0x5e,
+            (byte) 0xdb, (byte) 0x08, (byte) 0x98, (byte) 0x06, (byte) 0xc5, (byte) 0x99,
+            (byte) 0xb6, (byte) 0x6d, (byte) 0xbc, (byte) 0x5b, (byte) 0xf9, (byte) 0xe4,
+            (byte) 0x97, (byte) 0x0b, (byte) 0xba, (byte) 0xe3, (byte) 0x17, (byte) 0xa9,
+            (byte) 0x3c, (byte) 0x4b, (byte) 0x21, (byte) 0xd8, (byte) 0x29, (byte) 0xf8,
+            (byte) 0xa7, (byte) 0x1c, (byte) 0x15, (byte) 0xd7, (byte) 0xf6, (byte) 0xfc,
+            (byte) 0x53, (byte) 0x64, (byte) 0x97, (byte) 0x9e, (byte) 0x22, (byte) 0xb1,
+            (byte) 0x93, (byte) 0x26, (byte) 0x80, (byte) 0xdc, (byte) 0xaa, (byte) 0x1b,
+            (byte) 0xae, (byte) 0x69, (byte) 0x0f, (byte) 0x74, (byte) 0x3d, (byte) 0x61,
+            (byte) 0x80, (byte) 0x68, (byte) 0xb8, (byte) 0xaf, (byte) 0x63, (byte) 0x72,
+            (byte) 0x37, (byte) 0x4f, (byte) 0xf3, (byte) 0x29, (byte) 0x4a, (byte) 0x75,
+            (byte) 0x4f, (byte) 0x29, (byte) 0x40, (byte) 0x01, (byte) 0xd3, (byte) 0xc6,
+            (byte) 0x56, (byte) 0x1a, (byte) 0xaf, (byte) 0xc3, (byte) 0xb3, (byte) 0xd2,
+            (byte) 0xb9, (byte) 0x91, (byte) 0x35, (byte) 0x1b, (byte) 0x89, (byte) 0x4c,
+            (byte) 0x61, (byte) 0xa2, (byte) 0x8e, (byte) 0x6f, (byte) 0x12, (byte) 0x4a,
+            (byte) 0x10, (byte) 0xc2, (byte) 0xcc, (byte) 0xab, (byte) 0x51, (byte) 0xec,
+            (byte) 0x1b, (byte) 0xb5, (byte) 0xfe, (byte) 0x20, (byte) 0x16, (byte) 0xb2,
+            (byte) 0xc5, (byte) 0x0f, (byte) 0xe1, (byte) 0x6a, (byte) 0xb4, (byte) 0x6c,
+            (byte) 0x27, (byte) 0xd9, (byte) 0x42, (byte) 0xb9, (byte) 0xb6, (byte) 0x55,
+            (byte) 0xa8, (byte) 0xbc, (byte) 0x1c, (byte) 0x32, (byte) 0x54, (byte) 0x84,
+            (byte) 0xec, (byte) 0x1e, (byte) 0x95, (byte) 0xd8, (byte) 0xae, (byte) 0xca,
+            (byte) 0xc1, (byte) 0xad, (byte) 0x4c, (byte) 0x65, (byte) 0xd6, (byte) 0xc2,
+            (byte) 0x19, (byte) 0x66, (byte) 0xad, (byte) 0x9f, (byte) 0x55, (byte) 0x15,
+            (byte) 0xe1, (byte) 0x5d, (byte) 0x8f, (byte) 0xab, (byte) 0x18, (byte) 0x68,
+            (byte) 0x42, (byte) 0x7c, (byte) 0x48, (byte) 0xb7, (byte) 0x2c, (byte) 0xfd,
+            (byte) 0x1a, (byte) 0x07, (byte) 0xa1, (byte) 0x6a, (byte) 0xfb, (byte) 0x81,
+            (byte) 0xc6, (byte) 0x93, (byte) 0xbf, (byte) 0xa3, (byte) 0x5d, (byte) 0xfd,
+            (byte) 0xce, (byte) 0xf3, (byte) 0x17, (byte) 0x26, (byte) 0xf0, (byte) 0xda,
+            (byte) 0x0e, (byte) 0xd1, (byte) 0x86, (byte) 0x9d, (byte) 0x61, (byte) 0xd1,
+            (byte) 0x8a, (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0x1c, (byte) 0xd4,
+            (byte) 0x99, (byte) 0x53, (byte) 0x30, (byte) 0x5a, (byte) 0x01, (byte) 0xf4,
+            (byte) 0xa0, (byte) 0xca, (byte) 0x94, (byte) 0x72, (byte) 0x3d, (byte) 0xe3,
+            (byte) 0x50, (byte) 0x95, (byte) 0xcb, (byte) 0xa9, (byte) 0x37, (byte) 0xeb,
+            (byte) 0x66, (byte) 0x21, (byte) 0x20, (byte) 0x2e, (byte) 0xf2, (byte) 0xfd,
+            (byte) 0xfa, (byte) 0x54, (byte) 0xbf, (byte) 0x17, (byte) 0x23, (byte) 0xbb,
+            (byte) 0x9e, (byte) 0x77, (byte) 0xe0, (byte) 0xaa
+    };
+
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha512 -pkeyopt rsa_mgf1_md:sha512 -pkeyopt rsa_oaep_label:010203FFA00A | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA512_MGF1_SHA512_LABEL = new byte[] {
+            (byte) 0x31, (byte) 0x3b, (byte) 0x23, (byte) 0xcf, (byte) 0x40, (byte) 0xfe,
+            (byte) 0x15, (byte) 0x94, (byte) 0xd6, (byte) 0x81, (byte) 0x21, (byte) 0x69,
+            (byte) 0x8e, (byte) 0x58, (byte) 0xd5, (byte) 0x0f, (byte) 0xa8, (byte) 0x72,
+            (byte) 0x94, (byte) 0x13, (byte) 0xfe, (byte) 0xf9, (byte) 0xa1, (byte) 0x47,
+            (byte) 0x49, (byte) 0x91, (byte) 0xcb, (byte) 0x66, (byte) 0xe6, (byte) 0x5d,
+            (byte) 0x02, (byte) 0xad, (byte) 0xd4, (byte) 0x2f, (byte) 0x4f, (byte) 0xab,
+            (byte) 0xb7, (byte) 0x9e, (byte) 0xc0, (byte) 0xf0, (byte) 0x3d, (byte) 0x66,
+            (byte) 0x0e, (byte) 0x20, (byte) 0x82, (byte) 0x7f, (byte) 0x22, (byte) 0x8f,
+            (byte) 0x81, (byte) 0xba, (byte) 0x47, (byte) 0xc7, (byte) 0xaf, (byte) 0xb6,
+            (byte) 0x0e, (byte) 0x78, (byte) 0xe3, (byte) 0x30, (byte) 0xd7, (byte) 0x6c,
+            (byte) 0x81, (byte) 0xc2, (byte) 0x05, (byte) 0x7e, (byte) 0xe9, (byte) 0xac,
+            (byte) 0x8d, (byte) 0x45, (byte) 0x25, (byte) 0xe8, (byte) 0x26, (byte) 0x39,
+            (byte) 0x88, (byte) 0x64, (byte) 0x2e, (byte) 0xc6, (byte) 0xed, (byte) 0xd4,
+            (byte) 0xad, (byte) 0x94, (byte) 0xc8, (byte) 0x4e, (byte) 0x4a, (byte) 0x71,
+            (byte) 0x1e, (byte) 0x11, (byte) 0x14, (byte) 0x03, (byte) 0x56, (byte) 0x02,
+            (byte) 0x28, (byte) 0x32, (byte) 0x8f, (byte) 0xe2, (byte) 0x16, (byte) 0x4a,
+            (byte) 0x62, (byte) 0xa6, (byte) 0x9a, (byte) 0x8d, (byte) 0xf8, (byte) 0x33,
+            (byte) 0x35, (byte) 0xa2, (byte) 0xc7, (byte) 0x70, (byte) 0xcc, (byte) 0x26,
+            (byte) 0x1e, (byte) 0x4d, (byte) 0x9c, (byte) 0x4e, (byte) 0x2b, (byte) 0xe8,
+            (byte) 0xfd, (byte) 0x07, (byte) 0x33, (byte) 0x15, (byte) 0x53, (byte) 0x11,
+            (byte) 0x5c, (byte) 0x6f, (byte) 0x5d, (byte) 0x23, (byte) 0x7b, (byte) 0x3f,
+            (byte) 0x73, (byte) 0xff, (byte) 0xf4, (byte) 0xbe, (byte) 0x1f, (byte) 0xe6,
+            (byte) 0x5a, (byte) 0xb8, (byte) 0x2b, (byte) 0xd2, (byte) 0xbe, (byte) 0xa0,
+            (byte) 0x91, (byte) 0x5d, (byte) 0xca, (byte) 0x89, (byte) 0xb3, (byte) 0xce,
+            (byte) 0x0a, (byte) 0x2b, (byte) 0xce, (byte) 0xb9, (byte) 0xbe, (byte) 0x5d,
+            (byte) 0xb2, (byte) 0xc2, (byte) 0xd6, (byte) 0xa9, (byte) 0xbc, (byte) 0x37,
+            (byte) 0xed, (byte) 0x9a, (byte) 0xba, (byte) 0x35, (byte) 0xf8, (byte) 0x6e,
+            (byte) 0x63, (byte) 0x76, (byte) 0xd1, (byte) 0x12, (byte) 0xf5, (byte) 0x89,
+            (byte) 0xf0, (byte) 0x13, (byte) 0x86, (byte) 0xe7, (byte) 0x1b, (byte) 0x94,
+            (byte) 0xcb, (byte) 0xc8, (byte) 0x5c, (byte) 0x4c, (byte) 0x1b, (byte) 0x8a,
+            (byte) 0x2d, (byte) 0x6b, (byte) 0x24, (byte) 0x1a, (byte) 0x38, (byte) 0x14,
+            (byte) 0x77, (byte) 0x49, (byte) 0xe5, (byte) 0x08, (byte) 0x25, (byte) 0xe4,
+            (byte) 0xa6, (byte) 0xcf, (byte) 0x62, (byte) 0xfd, (byte) 0x66, (byte) 0x28,
+            (byte) 0xf0, (byte) 0x3a, (byte) 0x9c, (byte) 0x31, (byte) 0xef, (byte) 0x48,
+            (byte) 0x2a, (byte) 0xd3, (byte) 0x3e, (byte) 0x29, (byte) 0xfa, (byte) 0x18,
+            (byte) 0x8f, (byte) 0xd6, (byte) 0xaa, (byte) 0x1d, (byte) 0x10, (byte) 0xcd,
+            (byte) 0x35, (byte) 0x25, (byte) 0x92, (byte) 0x48, (byte) 0xa0, (byte) 0x2c,
+            (byte) 0xc1, (byte) 0x31, (byte) 0xeb, (byte) 0x47, (byte) 0x5b, (byte) 0x22,
+            (byte) 0x52, (byte) 0x7c, (byte) 0xf5, (byte) 0xec, (byte) 0x76, (byte) 0x90,
+            (byte) 0x94, (byte) 0x58, (byte) 0xd9, (byte) 0xd6, (byte) 0xe0, (byte) 0x0a,
+            (byte) 0x3f, (byte) 0x09, (byte) 0x98, (byte) 0x03, (byte) 0xc5, (byte) 0x07,
+            (byte) 0x8f, (byte) 0x89, (byte) 0x1e, (byte) 0x62, (byte) 0x2c, (byte) 0xea,
+            (byte) 0x17, (byte) 0x0a, (byte) 0x2e, (byte) 0x68
+    };
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually decrypting with private keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+        byte[] encrypted = c.doFinal(RSA_2048_Vector1);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+
+        c.init(Cipher.DECRYPT_MODE, privKey);
+        encrypted = c.doFinal(RSA_2048_Vector1);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually decrypting with private keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+        c.update(RSA_2048_Vector1);
+        byte[] encrypted = c.doFinal();
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+
+        c.init(Cipher.DECRYPT_MODE, privKey);
+        c.update(RSA_2048_Vector1);
+        encrypted = c.doFinal();
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually decrypting with private keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+        int i;
+        for (i = 0; i < RSA_2048_Vector1.length / 2; i++) {
+            c.update(RSA_2048_Vector1, i, 1);
+        }
+        byte[] encrypted = c.doFinal(RSA_2048_Vector1, i, RSA_2048_Vector1.length - i);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+
+        c.init(Cipher.DECRYPT_MODE, privKey);
+        for (i = 0; i < RSA_2048_Vector1.length / 2; i++) {
+            c.update(RSA_2048_Vector1, i, 1);
+        }
+        encrypted = c.doFinal(RSA_2048_Vector1, i, RSA_2048_Vector1.length - i);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually decrypting with private keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+        byte[] encrypted = new byte[RSA_Vector1_Encrypt_Private.length];
+        final int encryptLen = c
+                .doFinal(RSA_2048_Vector1, 0, RSA_2048_Vector1.length, encrypted, 0);
+        assertEquals("Encrypted size should match expected", RSA_Vector1_Encrypt_Private.length,
+                encryptLen);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+
+        c.init(Cipher.DECRYPT_MODE, privKey);
+        final int decryptLen = c
+                .doFinal(RSA_2048_Vector1, 0, RSA_2048_Vector1.length, encrypted, 0);
+        assertEquals("Encrypted size should match expected", RSA_Vector1_Encrypt_Private.length,
+                decryptLen);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+        byte[] encrypted = c.doFinal(RSA_Vector1_Encrypt_Private);
+        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
+
+        c.init(Cipher.DECRYPT_MODE, pubKey);
+        encrypted = c.doFinal(RSA_Vector1_Encrypt_Private);
+        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+        byte[] encrypted = new byte[RSA_2048_Vector1.length];
+        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);
+        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
+
+        c.init(Cipher.DECRYPT_MODE, pubKey);
+        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);
+        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+        c.update(RSA_Vector1_Encrypt_Private);
+        byte[] encrypted = c.doFinal();
+        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
+
+        c.init(Cipher.DECRYPT_MODE, pubKey);
+        c.update(RSA_Vector1_Encrypt_Private);
+        encrypted = c.doFinal();
+        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+        int i;
+        for (i = 0; i < RSA_Vector1_Encrypt_Private.length / 2; i++) {
+            c.update(RSA_Vector1_Encrypt_Private, i, 1);
+        }
+        byte[] encrypted = c.doFinal(RSA_Vector1_Encrypt_Private, i, RSA_2048_Vector1.length - i);
+        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
+
+        c.init(Cipher.DECRYPT_MODE, pubKey);
+        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);
+        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+        byte[] encrypted = c.doFinal(TooShort_Vector);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_ZeroPadded_Encrypted, encrypted));
+
+        c.init(Cipher.DECRYPT_MODE, pubKey);
+        encrypted = c.doFinal(TooShort_Vector);
+        assertTrue("Encrypted should match expected",
+                Arrays.equals(RSA_Vector1_ZeroPadded_Encrypted, encrypted));
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+        byte[] encrypted = c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
+        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE,
+                                       TooShort_Vector_Zero_Padded, encrypted);
+
+        c.init(Cipher.DECRYPT_MODE, privKey);
+        encrypted = c.doFinal(RSA_Vector1_ZeroPadded_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));
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+        c.update(RSA_Vector1_ZeroPadded_Encrypted);
+
+        try {
+            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);
+        }
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+
+        byte[] output = new byte[RSA_2048_Vector1.length];
+        c.update(RSA_Vector1_ZeroPadded_Encrypted, 0, RSA_Vector1_ZeroPadded_Encrypted.length,
+                output);
+
+        try {
+            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);
+        }
+    }
+
+    @Test
+    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 {
+        final PrivateKey privKey = (PrivateKey) getDecryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+
+        /*
+         * You're actually encrypting with public keys, but there is no
+         * distinction made here. It's all keyed off of what kind of key you're
+         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
+         */
+        c.init(Cipher.ENCRYPT_MODE, privKey);
+
+        byte[] tooBig_Vector = new byte[RSA_Vector1_ZeroPadded_Encrypted.length * 2];
+        System.arraycopy(RSA_Vector1_ZeroPadded_Encrypted, 0, tooBig_Vector, 0,
+                RSA_Vector1_ZeroPadded_Encrypted.length);
+        System.arraycopy(RSA_Vector1_ZeroPadded_Encrypted, 0, tooBig_Vector,
+                RSA_Vector1_ZeroPadded_Encrypted.length, RSA_Vector1_ZeroPadded_Encrypted.length);
+
+        try {
+            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);
+        }
+    }
+
+    @Test
+    public void testRSA_ECB_NoPadding_GetBlockSize_Success() throws Exception {
+        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 (provider.equals("SunJCE")) {
+            assertEquals(0, c.getBlockSize());
+        } else {
+            try {
+                c.getBlockSize();
+                fail();
+            } catch (IllegalStateException expected) {
+            }
+        }
+
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+        assertEquals(getExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, provider), c.getBlockSize());
+    }
+
+    @Test
+    public void testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure() throws Exception {
+        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");
+        } catch (IllegalStateException success) {
+        }
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+        c.init(Cipher.ENCRYPT_MODE, pubKey);
+
+        final int modulusInBytes = RSA_2048_modulus.bitLength() / 8;
+        assertEquals(modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length));
+        assertEquals(modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length * 2));
+        assertEquals(modulusInBytes, c.getOutputSize(0));
+    }
+
+    @Test
+    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 {
+        final PublicKey pubKey = (PublicKey) getEncryptKey("RSA");
+
+        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);
+
+        assertNull("ECB mode has no IV and should be null", c.getIV());
+    }
+
+    @Test
+    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 {
+        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+        assertNull("Parameters should be null", c.getParameters());
+    }
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 16 | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec DES_112_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0x6b, (byte) 0xb3, (byte) 0x85, (byte) 0x1c, (byte) 0x3d, (byte) 0x50,
+            (byte) 0xd4, (byte) 0x95, (byte) 0x39, (byte) 0x48, (byte) 0x77, (byte) 0x30,
+            (byte) 0x1a, (byte) 0xd7, (byte) 0x86, (byte) 0x57,
+    }, "DESede");
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 24 | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec DES_168_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0xfe, (byte) 0xd4, (byte) 0xd7, (byte) 0xc9, (byte) 0x8a, (byte) 0x13,
+            (byte) 0x6a, (byte) 0xa8, (byte) 0x5a, (byte) 0xb8, (byte) 0x19, (byte) 0xb8,
+            (byte) 0xcf, (byte) 0x3c, (byte) 0x5f, (byte) 0xe0, (byte) 0xa2, (byte) 0xf7,
+            (byte) 0x7b, (byte) 0x65, (byte) 0x43, (byte) 0xc0, (byte) 0xc4, (byte) 0xe1,
+    }, "DESede");
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 5 | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec ARC4_40BIT_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0x9c, (byte) 0xc8, (byte) 0xb9, (byte) 0x94, (byte) 0x98,
+    }, "ARC4");
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 24 | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec ARC4_128BIT_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0xbc, (byte) 0x0a, (byte) 0x3c, (byte) 0xca, (byte) 0xb5, (byte) 0x42,
+            (byte) 0xfa, (byte) 0x5d, (byte) 0x86, (byte) 0x5b, (byte) 0x44, (byte) 0x87,
+            (byte) 0x83, (byte) 0xd8, (byte) 0xcb, (byte) 0xd4,
+    }, "ARC4");
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 16
+     * echo '3d4f8970b1f27537f40a39298a41555f' | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec AES_128_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2,
+            (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29,
+            (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f,
+    }, "AES");
+
+    /*
+     * Test key generation:
+     * openssl rand -hex 24
+     * echo '5a7a3d7e40b64ed996f7afa15f97fd595e27db6af428e342' | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec AES_192_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0x5a, (byte) 0x7a, (byte) 0x3d, (byte) 0x7e, (byte) 0x40, (byte) 0xb6,
+            (byte) 0x4e, (byte) 0xd9, (byte) 0x96, (byte) 0xf7, (byte) 0xaf, (byte) 0xa1,
+            (byte) 0x5f, (byte) 0x97, (byte) 0xfd, (byte) 0x59, (byte) 0x5e, (byte) 0x27,
+            (byte) 0xdb, (byte) 0x6a, (byte) 0xf4, (byte) 0x28, (byte) 0xe3, (byte) 0x42,
+    }, "AES");
+
+    /*
+     * Test key generation:
+     * openssl rand -hex 32
+     * echo 'ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935' | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final SecretKeySpec AES_256_KEY = new SecretKeySpec(new byte[] {
+            (byte) 0xec, (byte) 0x53, (byte) 0xc6, (byte) 0xd5, (byte) 0x1d, (byte) 0x2c,
+            (byte) 0x49, (byte) 0x73, (byte) 0x58, (byte) 0x5f, (byte) 0xb0, (byte) 0xb8,
+            (byte) 0xe5, (byte) 0x1c, (byte) 0xd2, (byte) 0xe3, (byte) 0x99, (byte) 0x15,
+            (byte) 0xff, (byte) 0x07, (byte) 0xa1, (byte) 0x83, (byte) 0x78, (byte) 0x72,
+            (byte) 0x71, (byte) 0x5d, (byte) 0x61, (byte) 0x21, (byte) 0xbf, (byte) 0x86,
+            (byte) 0x19, (byte) 0x35,
+    }, "AES");
+
+    /*
+     * Test vector generation:
+     * echo -n 'Testing rocks!' | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] DES_Plaintext1 = new byte[] {
+            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x69, (byte) 0x6E,
+            (byte) 0x67, (byte) 0x20, (byte) 0x72, (byte) 0x6F, (byte) 0x63, (byte) 0x6B,
+            (byte) 0x73, (byte) 0x21
+    };
+
+
+    /*
+     * Test vector generation: take DES_Plaintext1 and PKCS #5 pad it manually (it's not hard).
+     */
+    private static final byte[] DES_Plaintext1_PKCS5_Padded = new byte[] {
+            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x69, (byte) 0x6E,
+            (byte) 0x67, (byte) 0x20, (byte) 0x72, (byte) 0x6F, (byte) 0x63, (byte) 0x6B,
+            (byte) 0x73, (byte) 0x21, (byte) 0x02, (byte) 0x02,
+    };
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 8 | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final byte[] DES_IV1 = new byte[] {
+            (byte) 0x5c, (byte) 0x47, (byte) 0x5e, (byte) 0x57, (byte) 0x0c, (byte) 0x46,
+            (byte) 0xcb, (byte) 0x47,
+    };
+
+    /*
+     * Test vector generation:
+     * openssl enc -des-ede-cbc -K 6bb3851c3d50d495394877301ad78657 -iv 5c475e570c46cb47 -in blah
+     * | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[]
+            DES_Plaintext1_Encrypted_With_DES_112_KEY_And_DESEDE_CBC_PKCS5PADDING_With_DES_IV1 =
+                    new byte[] {
+            (byte) 0x09, (byte) 0xA5, (byte) 0x5D, (byte) 0x94, (byte) 0x94, (byte) 0xAA,
+            (byte) 0x3F, (byte) 0xC8, (byte) 0xB7, (byte) 0x73, (byte) 0x94, (byte) 0x0E,
+            (byte) 0xFC, (byte) 0xF4, (byte) 0xA5, (byte) 0x28,
+    };
+
+
+    /*
+     * Test vector generation:
+     * openssl enc -des-ede3-cbc -K fed4d7c98a136aa85ab819b8cf3c5fe0a2f77b6543c0c4e1
+     *     -iv 5c475e570c46cb47 -in blah | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[]
+            DES_Plaintext1_Encrypted_With_DES_168_KEY_And_DESEDE_CBC_PKCS5PADDING_With_DES_IV1 =
+                    new byte[] {
+            (byte) 0xC9, (byte) 0xF1, (byte) 0x83, (byte) 0x1F, (byte) 0x24, (byte) 0x83,
+            (byte) 0x2C, (byte) 0x7B, (byte) 0x66, (byte) 0x66, (byte) 0x99, (byte) 0x98,
+            (byte) 0x27, (byte) 0xB0, (byte) 0xED, (byte) 0x47
+    };
+
+
+    /*
+     * Test vector generation:
+     * echo -n 'Plaintext for arc4' | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] ARC4_Plaintext1 = new byte[] {
+            (byte) 0x50, (byte) 0x6C, (byte) 0x61, (byte) 0x69, (byte) 0x6E, (byte) 0x74,
+            (byte) 0x65, (byte) 0x78, (byte) 0x74, (byte) 0x20, (byte) 0x66, (byte) 0x6F,
+            (byte) 0x72, (byte) 0x20, (byte) 0x61, (byte) 0x72, (byte) 0x63, (byte) 0x34
+    };
+
+    /*
+     * Test vector generation:
+     *  echo -n 'Plaintext for arc4' | openssl enc -rc4-40 -K 9cc8b99498 | recode ../x1 \
+     *     | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] ARC4_Plaintext1_Encrypted_With_ARC4_40Bit_Key = new byte[] {
+            (byte) 0x63, (byte) 0xF7, (byte) 0x11, (byte) 0x90, (byte) 0x63, (byte) 0xEF,
+            (byte) 0x5E, (byte) 0xB3, (byte) 0x93, (byte) 0xB3, (byte) 0x46, (byte) 0x3F,
+            (byte) 0x1B, (byte) 0x02, (byte) 0x53, (byte) 0x9B, (byte) 0xD9, (byte) 0xE0
+    };
+
+    /*
+     * Test vector generation:
+     *  echo -n 'Plaintext for arc4' | openssl enc -rc4 -K bc0a3ccab542fa5d865b448783d8cbd4 \
+     *     | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] ARC4_Plaintext1_Encrypted_With_ARC4_128Bit_Key = new byte[] {
+            (byte) 0x25, (byte) 0x14, (byte) 0xA9, (byte) 0x72, (byte) 0x4D, (byte) 0xA9,
+            (byte) 0xF6, (byte) 0xA7, (byte) 0x2F, (byte) 0xB7, (byte) 0x0D, (byte) 0x60,
+            (byte) 0x09, (byte) 0xBE, (byte) 0x41, (byte) 0x9B, (byte) 0x32, (byte) 0x2B
+    };
+
+    /*
+     * Test vector creation:
+     * echo -n 'Hello, world!' | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext = new byte[] {
+            (byte) 0x48, (byte) 0x65, (byte) 0x6C, (byte) 0x6C, (byte) 0x6F, (byte) 0x2C,
+            (byte) 0x20, (byte) 0x77, (byte) 0x6F, (byte) 0x72, (byte) 0x6C, (byte) 0x64,
+            (byte) 0x21,
+    };
+
+    /*
+     * Test vector creation:
+     * openssl enc -aes-128-ecb -K 3d4f8970b1f27537f40a39298a41555f -in blah|openssl enc -aes-128-ecb -K 3d4f8970b1f27537f40a39298a41555f -nopad -d|recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded = new byte[] {
+            (byte) 0x48, (byte) 0x65, (byte) 0x6C, (byte) 0x6C, (byte) 0x6F, (byte) 0x2C,
+            (byte) 0x20, (byte) 0x77, (byte) 0x6F, (byte) 0x72, (byte) 0x6C, (byte) 0x64,
+            (byte) 0x21, (byte) 0x03, (byte) 0x03, (byte) 0x03
+    };
+
+    /*
+     * Test vector generation:
+     * openssl enc -aes-128-ecb -K 3d4f8970b1f27537f40a39298a41555f -in blah|recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted = new byte[] {
+            (byte) 0x65, (byte) 0x3E, (byte) 0x86, (byte) 0xFB, (byte) 0x05, (byte) 0x5A,
+            (byte) 0x52, (byte) 0xEA, (byte) 0xDD, (byte) 0x08, (byte) 0xE7, (byte) 0x48,
+            (byte) 0x33, (byte) 0x01, (byte) 0xFC, (byte) 0x5A,
+    };
+
+    /*
+     * Taken from BoringSSL test vectors.
+     */
+    private static final SecretKeySpec AES_128_GCM_TestVector_1_Key = new SecretKeySpec(new byte[] {
+            (byte) 0xca, (byte) 0xbd, (byte) 0xcf, (byte) 0x54, (byte) 0x1a, (byte) 0xeb,
+            (byte) 0xf9, (byte) 0x17, (byte) 0xba, (byte) 0xc0, (byte) 0x19, (byte) 0xf1,
+            (byte) 0x39, (byte) 0x25, (byte) 0xd2, (byte) 0x67,
+    }, "AES");
+
+    /*
+     * Taken from BoringSSL test vectors.
+     */
+    private static final byte[] AES_128_GCM_TestVector_1_IV = new byte[] {
+            (byte) 0x2c, (byte) 0x34, (byte) 0xc0, (byte) 0x0c, (byte) 0x42, (byte) 0xda,
+            (byte) 0xe3, (byte) 0x82, (byte) 0x27, (byte) 0x9d, (byte) 0x79, (byte) 0x74,
+    };
+
+    /*
+     * Taken from BoringSSL test vectors.
+     */
+    private static final byte[] AES_128_GCM_TestVector_1_AAD = new byte[] {
+            (byte) 0xdd, (byte) 0x10, (byte) 0xe3, (byte) 0x71, (byte) 0xb2, (byte) 0x2e,
+            (byte) 0x15, (byte) 0x67, (byte) 0x1c, (byte) 0x31, (byte) 0xaf, (byte) 0xee,
+            (byte) 0x55, (byte) 0x2b, (byte) 0xf1, (byte) 0xde, (byte) 0xa0, (byte) 0x7c,
+            (byte) 0xbb, (byte) 0xf6, (byte) 0x85, (byte) 0xe2, (byte) 0xca, (byte) 0xa0,
+            (byte) 0xe0, (byte) 0x36, (byte) 0x37, (byte) 0x16, (byte) 0xa2, (byte) 0x76,
+            (byte) 0xe1, (byte) 0x20, (byte) 0xc6, (byte) 0xc0, (byte) 0xeb, (byte) 0x4a,
+            (byte) 0xcb, (byte) 0x1a, (byte) 0x4d, (byte) 0x1b, (byte) 0xa7, (byte) 0x3f,
+            (byte) 0xde, (byte) 0x66, (byte) 0x15, (byte) 0xf7, (byte) 0x08, (byte) 0xaa,
+            (byte) 0xa4, (byte) 0x6b, (byte) 0xc7, (byte) 0x6c, (byte) 0x7f, (byte) 0xf3,
+            (byte) 0x45, (byte) 0xa4, (byte) 0xf7, (byte) 0x6b, (byte) 0xda, (byte) 0x11,
+            (byte) 0x7f, (byte) 0xe5, (byte) 0x6f, (byte) 0x0d, (byte) 0xc9, (byte) 0xb9,
+            (byte) 0x39, (byte) 0x04, (byte) 0x0d, (byte) 0xdd,
+    };
+
+    /*
+     * Taken from BoringSSL test vectors.
+     */
+    private static final byte[] AES_128_GCM_TestVector_1_Plaintext = new byte[] {
+            (byte) 0x88, (byte) 0xcc, (byte) 0x1e, (byte) 0x07, (byte) 0xdf, (byte) 0xde,
+            (byte) 0x8e, (byte) 0x08, (byte) 0x08, (byte) 0x2e, (byte) 0x67, (byte) 0x66,
+            (byte) 0xe0, (byte) 0xa8, (byte) 0x81, (byte) 0x03, (byte) 0x38, (byte) 0x47,
+            (byte) 0x42, (byte) 0xaf, (byte) 0x37, (byte) 0x8d, (byte) 0x7b, (byte) 0x6b,
+            (byte) 0x8a, (byte) 0x87, (byte) 0xfc, (byte) 0xe0, (byte) 0x36, (byte) 0xaf,
+            (byte) 0x74, (byte) 0x41, (byte) 0xc1, (byte) 0x39, (byte) 0x61, (byte) 0xc2,
+            (byte) 0x5a, (byte) 0xfe, (byte) 0xa7, (byte) 0xf6, (byte) 0xe5, (byte) 0x61,
+            (byte) 0x93, (byte) 0xf5, (byte) 0x4b, (byte) 0xee, (byte) 0x00, (byte) 0x11,
+            (byte) 0xcb, (byte) 0x78, (byte) 0x64, (byte) 0x2c, (byte) 0x3a, (byte) 0xb9,
+            (byte) 0xe6, (byte) 0xd5, (byte) 0xb2, (byte) 0xe3, (byte) 0x58, (byte) 0x33,
+            (byte) 0xec, (byte) 0x16, (byte) 0xcd, (byte) 0x35, (byte) 0x55, (byte) 0x15,
+            (byte) 0xaf, (byte) 0x1a, (byte) 0x19, (byte) 0x0f,
+    };
+
+    /*
+     * Taken from BoringSSL test vectors.
+     */
+    private static final byte[] AES_128_GCM_TestVector_1_Encrypted = new byte[] {
+            (byte) 0x04, (byte) 0x94, (byte) 0x53, (byte) 0xba, (byte) 0xf1, (byte) 0x57,
+            (byte) 0x87, (byte) 0x87, (byte) 0xd6, (byte) 0x8e, (byte) 0xd5, (byte) 0x47,
+            (byte) 0x87, (byte) 0x26, (byte) 0xc0, (byte) 0xb8, (byte) 0xa6, (byte) 0x36,
+            (byte) 0x33, (byte) 0x7a, (byte) 0x0b, (byte) 0x8a, (byte) 0x82, (byte) 0xb8,
+            (byte) 0x68, (byte) 0x36, (byte) 0xf9, (byte) 0x1c, (byte) 0xde, (byte) 0x25,
+            (byte) 0xe6, (byte) 0xe4, (byte) 0x4c, (byte) 0x34, (byte) 0x59, (byte) 0x40,
+            (byte) 0xe8, (byte) 0x19, (byte) 0xa0, (byte) 0xc5, (byte) 0x05, (byte) 0x75,
+            (byte) 0x1e, (byte) 0x60, (byte) 0x3c, (byte) 0xb8, (byte) 0xf8, (byte) 0xc4,
+            (byte) 0xfe, (byte) 0x98, (byte) 0x71, (byte) 0x91, (byte) 0x85, (byte) 0x56,
+            (byte) 0x27, (byte) 0x94, (byte) 0xa1, (byte) 0x85, (byte) 0xe5, (byte) 0xde,
+            (byte) 0xc4, (byte) 0x15, (byte) 0xc8, (byte) 0x1f, (byte) 0x2f, (byte) 0x16,
+            (byte) 0x2c, (byte) 0xdc, (byte) 0xd6, (byte) 0x50, (byte) 0xdc, (byte) 0xe7,
+            (byte) 0x19, (byte) 0x87, (byte) 0x28, (byte) 0xbf, (byte) 0xc1, (byte) 0xb5,
+            (byte) 0xf9, (byte) 0x49, (byte) 0xb9, (byte) 0xb5, (byte) 0x37, (byte) 0x41,
+            (byte) 0x99, (byte) 0xc6,
+    };
+
+    /*
+     * Test key generation:
+     * openssl rand -hex 16
+     * echo '787bdeecf05556eac5d3d865e435f6d9' | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final byte[] AES_192_CTR_NoPadding_TestVector_1_IV = new byte[] {
+            (byte) 0x78, (byte) 0x7b, (byte) 0xde, (byte) 0xec, (byte) 0xf0, (byte) 0x55,
+            (byte) 0x56, (byte) 0xea, (byte) 0xc5, (byte) 0xd3, (byte) 0xd8, (byte) 0x65,
+            (byte) 0xe4, (byte) 0x35, (byte) 0xf6, (byte) 0xd9,
+
+    };
+
+    /*
+     * Test vector generation:
+     * echo -n 'AES-192 is a silly option' | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_192_CTR_NoPadding_TestVector_1_Plaintext = new byte[] {
+            (byte) 0x41, (byte) 0x45, (byte) 0x53, (byte) 0x2D, (byte) 0x31, (byte) 0x39,
+            (byte) 0x32, (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x61,
+            (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x6C, (byte) 0x6C, (byte) 0x79,
+            (byte) 0x20, (byte) 0x6F, (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6F,
+            (byte) 0x6E
+    };
+
+    /*
+     * Test vector generation:
+     * echo -n 'AES-192 is a silly option' | openssl enc -aes-192-ctr -K 5a7a3d7e40b64ed996f7afa15f97fd595e27db6af428e342 -iv 787bdeecf05556eac5d3d865e435f6d9 | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_192_CTR_NoPadding_TestVector_1_Ciphertext = new byte[] {
+            (byte) 0xE9, (byte) 0xC6, (byte) 0xA0, (byte) 0x40, (byte) 0xC2, (byte) 0x6A,
+            (byte) 0xB5, (byte) 0x20, (byte) 0xFE, (byte) 0x9E, (byte) 0x65, (byte) 0xB7,
+            (byte) 0x7C, (byte) 0x5E, (byte) 0xFE, (byte) 0x1F, (byte) 0xF1, (byte) 0x6F,
+            (byte) 0x20, (byte) 0xAC, (byte) 0x37, (byte) 0xE9, (byte) 0x75, (byte) 0xE3,
+            (byte) 0x52
+    };
+
+    /*
+     * Test key generation: openssl rand -hex 16 echo
+     * 'ceaa31952dfd3d0f5af4b2042ba06094' | sed 's/\(..\)/(byte) 0x\1, /g'
+     */
+    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_IV = new byte[] {
+            (byte) 0xce, (byte) 0xaa, (byte) 0x31, (byte) 0x95, (byte) 0x2d, (byte) 0xfd,
+            (byte) 0x3d, (byte) 0x0f, (byte) 0x5a, (byte) 0xf4, (byte) 0xb2, (byte) 0x04,
+            (byte) 0x2b, (byte) 0xa0, (byte) 0x60, (byte) 0x94,
+    };
+
+    /*
+     * Test vector generation:
+     * echo -n 'I only regret that I have but one test to write.' | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext = new byte[] {
+            (byte) 0x49, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x6C, (byte) 0x79,
+            (byte) 0x20, (byte) 0x72, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x65,
+            (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x61, (byte) 0x74,
+            (byte) 0x20, (byte) 0x49, (byte) 0x20, (byte) 0x68, (byte) 0x61, (byte) 0x76,
+            (byte) 0x65, (byte) 0x20, (byte) 0x62, (byte) 0x75, (byte) 0x74, (byte) 0x20,
+            (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x20, (byte) 0x74, (byte) 0x65,
+            (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x6F, (byte) 0x20,
+            (byte) 0x77, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x65, (byte) 0x2E
+    };
+
+    /*
+     * Test vector generation:
+     * echo -n 'I only regret that I have but one test to write.' | openssl enc -aes-256-cbc -K ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935 -iv ceaa31952dfd3d0f5af4b2042ba06094 | openssl enc -aes-256-cbc -K ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935 -iv ceaa31952dfd3d0f5af4b2042ba06094 -d -nopad | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded = new byte[] {
+            (byte) 0x49, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x6C, (byte) 0x79,
+            (byte) 0x20, (byte) 0x72, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x65,
+            (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x61, (byte) 0x74,
+            (byte) 0x20, (byte) 0x49, (byte) 0x20, (byte) 0x68, (byte) 0x61, (byte) 0x76,
+            (byte) 0x65, (byte) 0x20, (byte) 0x62, (byte) 0x75, (byte) 0x74, (byte) 0x20,
+            (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x20, (byte) 0x74, (byte) 0x65,
+            (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x6F, (byte) 0x20,
+            (byte) 0x77, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x65, (byte) 0x2E,
+            (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10,
+            (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10,
+            (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10
+    };
+
+    /*
+     * Test vector generation:
+     * echo -n 'I only regret that I have but one test to write.' | openssl enc -aes-256-cbc -K ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935 -iv ceaa31952dfd3d0f5af4b2042ba06094 | recode ../x1 | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext = new byte[] {
+            (byte) 0x90, (byte) 0x65, (byte) 0xDD, (byte) 0xAF, (byte) 0x7A, (byte) 0xCE,
+            (byte) 0xAE, (byte) 0xBF, (byte) 0xE8, (byte) 0xF6, (byte) 0x9E, (byte) 0xDB,
+            (byte) 0xEA, (byte) 0x65, (byte) 0x28, (byte) 0xC4, (byte) 0x9A, (byte) 0x28,
+            (byte) 0xEA, (byte) 0xA3, (byte) 0x95, (byte) 0x2E, (byte) 0xFF, (byte) 0xF1,
+            (byte) 0xA0, (byte) 0xCA, (byte) 0xC2, (byte) 0xA4, (byte) 0x65, (byte) 0xCD,
+            (byte) 0xBF, (byte) 0xCE, (byte) 0x9E, (byte) 0xF1, (byte) 0x57, (byte) 0xF6,
+            (byte) 0x32, (byte) 0x2E, (byte) 0x8F, (byte) 0x93, (byte) 0x2E, (byte) 0xAE,
+            (byte) 0x41, (byte) 0x33, (byte) 0x54, (byte) 0xD0, (byte) 0xEF, (byte) 0x8C,
+            (byte) 0x52, (byte) 0x14, (byte) 0xAC, (byte) 0x2D, (byte) 0xD5, (byte) 0xA4,
+            (byte) 0xF9, (byte) 0x20, (byte) 0x77, (byte) 0x25, (byte) 0x91, (byte) 0x3F,
+            (byte) 0xD1, (byte) 0xB9, (byte) 0x00, (byte) 0x3E
+    };
+
+    private static class CipherTestParam {
+        public final String transformation;
+
+        public final AlgorithmParameterSpec spec;
+
+        public final Key encryptKey;
+
+        public final Key decryptKey;
+
+        public final byte[] aad;
+
+        public final byte[] plaintext;
+
+        public final byte[] ciphertext;
+
+        public final byte[] plaintextPadded;
+
+        public final boolean isStreamCipher;
+
+        public CipherTestParam(String transformation, AlgorithmParameterSpec spec, Key encryptKey,
+                Key decryptKey, byte[] aad, byte[] plaintext, byte[] plaintextPadded,
+                byte[] ciphertext, boolean isStreamCipher) {
+            this.transformation = transformation.toUpperCase(Locale.ROOT);
+            this.spec = spec;
+            this.encryptKey = encryptKey;
+            this.decryptKey = decryptKey;
+            this.aad = aad;
+            this.plaintext = plaintext;
+            this.plaintextPadded = plaintextPadded;
+            this.ciphertext = ciphertext;
+            this.isStreamCipher = isStreamCipher;
+        }
+
+        public CipherTestParam(String transformation, AlgorithmParameterSpec spec, Key key,
+                byte[] aad, byte[] plaintext, byte[] plaintextPadded, byte[] ciphertext,
+                boolean isStreamCipher) {
+            this(transformation, spec, key, key, aad, plaintext, plaintextPadded, ciphertext,
+                    isStreamCipher);
+        }
+
+        public CipherTestParam(String transformation, AlgorithmParameterSpec spec, Key key,
+                byte[] aad, byte[] plaintext, byte[] plaintextPadded, byte[] ciphertext) {
+            this(transformation, spec, key, aad, plaintext, plaintextPadded, ciphertext,
+                    false /* isStreamCipher */);
+        }
+
+        public boolean compatibleWith(String provider) {
+            // SunJCE doesn't support PKCS7Padding
+            if (provider.equals("SunJCE") && transformation.endsWith("/PKCS7PADDING")) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private static class OAEPCipherTestParam extends CipherTestParam {
+        public OAEPCipherTestParam(String transformation, OAEPParameterSpec spec,
+                PublicKey encryptKey, PrivateKey decryptKey, byte[] plaintext, byte[] ciphertext) {
+            super(transformation, spec, encryptKey, decryptKey, null, plaintext, plaintext, ciphertext,
+                    false);
+        }
+
+        @Override
+        public boolean compatibleWith(String provider) {
+            // OAEP transformations have two digests, the "main" digest and the MGF-1 digest.
+            // BC and Conscrypt set the MGF-1 digest to the same as the main digest when it's
+            // not specified, whereas Sun's provider sets it to SHA-1.  Thus, the results from
+            // the different providers won't match when there isn't an explicit MGF-1 digest set
+            // and the main digest isn't SHA-1.  See b/22405492.
+            if (provider.equals("SunJCE")
+                    && (spec == null)
+                    && !transformation.toUpperCase(Locale.US).equals("RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING")) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private static List<CipherTestParam> DES_CIPHER_TEST_PARAMS = new ArrayList<CipherTestParam>();
+    static {
+        DES_CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                "DESede/CBC/PKCS5Padding",
+                new IvParameterSpec(DES_IV1),
+                DES_112_KEY,
+                null,
+                DES_Plaintext1,
+                DES_Plaintext1_PKCS5_Padded,
+                DES_Plaintext1_Encrypted_With_DES_112_KEY_And_DESEDE_CBC_PKCS5PADDING_With_DES_IV1
+                ) {
+                    @Override
+                    public boolean compatibleWith(String provider) {
+                        // SunJCE doesn't support extending 112-bit keys to 168-bit keys
+                        return !provider.equals("SunJCE");
+                    }
+                });
+        DES_CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                "DESede/CBC/PKCS5Padding",
+                new IvParameterSpec(DES_IV1),
+                DES_168_KEY,
+                null,
+                DES_Plaintext1,
+                DES_Plaintext1_PKCS5_Padded,
+                DES_Plaintext1_Encrypted_With_DES_168_KEY_And_DESEDE_CBC_PKCS5PADDING_With_DES_IV1
+                ));
+    }
+
+    private static List<CipherTestParam> ARC4_CIPHER_TEST_PARAMS = new ArrayList<CipherTestParam>();
+    static {
+        ARC4_CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                "ARC4",
+                null,
+                ARC4_40BIT_KEY,
+                null, // aad
+                ARC4_Plaintext1,
+                null, // padded
+                ARC4_Plaintext1_Encrypted_With_ARC4_40Bit_Key,
+                true /*isStreamCipher */
+        ));
+        ARC4_CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                "ARC4",
+                null,
+                ARC4_128BIT_KEY,
+                null, // aad
+                ARC4_Plaintext1,
+                null, // padded
+                ARC4_Plaintext1_Encrypted_With_ARC4_128Bit_Key,
+                true /*isStreamCipher */
+        ));
+    }
+
+    private static List<CipherTestParam> CIPHER_TEST_PARAMS = new ArrayList<CipherTestParam>();
+    static {
+        CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                "AES/ECB/PKCS5Padding",
+                null,
+                AES_128_KEY,
+                null,
+                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext,
+                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
+                AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted));
+        // PKCS#5 is assumed to be equivalent to PKCS#7 -- same test vectors are thus used for both.
+        CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                "AES/ECB/PKCS7Padding",
+                null,
+                AES_128_KEY,
+                null,
+                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/GCM/NOPADDING",
+                new GCMParameterSpec(
+                        (AES_128_GCM_TestVector_1_Encrypted.length -
+                                AES_128_GCM_TestVector_1_Plaintext.length) * 8,
+                        AES_128_GCM_TestVector_1_IV),
+                AES_128_GCM_TestVector_1_Key,
+                AES_128_GCM_TestVector_1_AAD,
+                AES_128_GCM_TestVector_1_Plaintext,
+                AES_128_GCM_TestVector_1_Plaintext,
+                AES_128_GCM_TestVector_1_Encrypted));
+        if (IS_UNLIMITED) {
+            CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                    "AES/CTR/NoPadding",
+                    new IvParameterSpec(AES_192_CTR_NoPadding_TestVector_1_IV),
+                    AES_192_KEY,
+                    null,
+                    AES_192_CTR_NoPadding_TestVector_1_Plaintext,
+                    AES_192_CTR_NoPadding_TestVector_1_Plaintext,
+                    AES_192_CTR_NoPadding_TestVector_1_Ciphertext));
+            CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                    "AES/CBC/PKCS5Padding",
+                    new IvParameterSpec(AES_256_CBC_PKCS5Padding_TestVector_1_IV),
+                    AES_256_KEY,
+                    null,
+                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
+                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
+                    AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
+            CIPHER_TEST_PARAMS.add(new CipherTestParam(
+                    "AES/CBC/PKCS7Padding",
+                    new IvParameterSpec(AES_256_CBC_PKCS5Padding_TestVector_1_IV),
+                    AES_256_KEY,
+                    null,
+                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
+                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
+                    AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
+        }
+    }
+
+    private static final List<CipherTestParam> RSA_OAEP_CIPHER_TEST_PARAMS = new ArrayList<CipherTestParam>();
+    static {
+        addRsaOaepTest("SHA-1", MGF1ParameterSpec.SHA1, RSA_Vector2_OAEP_SHA1_MGF1_SHA1);
+        addRsaOaepTest("SHA-256", MGF1ParameterSpec.SHA1, RSA_Vector2_OAEP_SHA256_MGF1_SHA1);
+        addRsaOaepTest("SHA-224", MGF1ParameterSpec.SHA224, RSA_Vector2_OAEP_SHA224_MGF1_SHA224);
+        addRsaOaepTest("SHA-256", MGF1ParameterSpec.SHA256, RSA_Vector2_OAEP_SHA256_MGF1_SHA256);
+        addRsaOaepTest("SHA-384", MGF1ParameterSpec.SHA384, RSA_Vector2_OAEP_SHA384_MGF1_SHA384);
+        addRsaOaepTest("SHA-512", MGF1ParameterSpec.SHA512, RSA_Vector2_OAEP_SHA512_MGF1_SHA512);
+        addRsaOaepTest("SHA-256", MGF1ParameterSpec.SHA1, RSA_Vector2_OAEP_SHA256_MGF1_SHA1_LABEL,
+                new byte[] { 0x01, 0x02, 0x03, (byte) 0xFF, (byte) 0xA0, 0x0A });
+        addRsaOaepTest("SHA-512", MGF1ParameterSpec.SHA512, RSA_Vector2_OAEP_SHA512_MGF1_SHA512_LABEL,
+                new byte[] { 0x01, 0x02, 0x03, (byte) 0xFF, (byte) 0xA0, 0x0A });
+    }
+
+    private static void addRsaOaepTest(String digest, MGF1ParameterSpec mgf1Spec, byte[] vector) {
+        addRsaOaepTest(digest, mgf1Spec, vector, null);
+    }
+
+    private static void addRsaOaepTest(String digest, MGF1ParameterSpec mgf1Spec, byte[] vector, byte[] label) {
+        final PSource pSource;
+        if (label == null) {
+            pSource = PSource.PSpecified.DEFAULT;
+        } else {
+            pSource = new PSource.PSpecified(label);
+        }
+
+        if (mgf1Spec.getDigestAlgorithm().equals(digest) && label == null) {
+            RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
+                    "RSA/ECB/OAEPWith" + digest + "AndMGF1Padding",
+                    null,
+                    (PublicKey) getEncryptKey("RSA"),
+                    (PrivateKey) getDecryptKey("RSA"),
+                    RSA_Vector2_Plaintext,
+                    vector));
+        }
+
+        RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
+                "RSA/ECB/OAEPWith" + digest + "AndMGF1Padding",
+                new OAEPParameterSpec(digest, "MGF1", mgf1Spec, pSource),
+                (PublicKey) getEncryptKey("RSA"),
+                (PrivateKey) getDecryptKey("RSA"),
+                RSA_Vector2_Plaintext,
+                vector));
+
+        RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
+                "RSA/ECB/OAEPPadding",
+                new OAEPParameterSpec(digest, "MGF1", mgf1Spec, pSource),
+                (PublicKey) getEncryptKey("RSA"),
+                (PrivateKey) getDecryptKey("RSA"),
+                RSA_Vector2_Plaintext,
+                vector));
+    }
+
+    @Test
+    public void testCipher_Success() throws Exception {
+        for (String provider : AES_PROVIDERS) {
+            testCipher_Success(provider);
+        }
+
+        testCipher_Success_ForAllSupportingProviders_AtLeastOneProviderRequired(
+                DES_CIPHER_TEST_PARAMS);
+        testCipher_Success_ForAllSupportingProviders_AtLeastOneProviderRequired(
+                ARC4_CIPHER_TEST_PARAMS);
+        testCipher_Success_ForAllSupportingProviders_AtLeastOneProviderRequired(
+                RSA_OAEP_CIPHER_TEST_PARAMS);
+    }
+
+    /**
+     * For each test vector in the list, tests that the transformation is supported by at least one
+     * provider and that all implementations of the transformation pass the Known Answer Test (KAT)
+     * as well as other functional tests.
+     */
+    private void testCipher_Success_ForAllSupportingProviders_AtLeastOneProviderRequired(
+            List<CipherTestParam> testVectors) throws Exception {
+        ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
+        PrintStream out = new PrintStream(errBuffer);
+        for (CipherTestParam testVector : testVectors) {
+            ArrayList<Provider> providers = new ArrayList<Provider>();
+
+            Provider[] providerArray = Security.getProviders("Cipher." + testVector.transformation);
+            if (providerArray != null) {
+                Collections.addAll(providers, providerArray);
+            }
+
+            if (testVector.transformation.indexOf('/') > 0) {
+                Provider[] baseTransformProviderArray = Security.getProviders("Cipher."
+                        + testVector.transformation.substring(
+                                  0, testVector.transformation.indexOf('/')));
+                if (baseTransformProviderArray != null) {
+                    Collections.addAll(providers, baseTransformProviderArray);
+                }
+            }
+
+            if (providers.isEmpty()) {
+                out.append("No providers offer " + testVector.transformation + "\n");
+                continue;
+            }
+
+            for (Provider provider : providers) {
+                // Do not test AndroidKeyStore's Signature. It needs an AndroidKeyStore-specific key.
+                // It's OKish not to test AndroidKeyStore's Signature here because it's tested
+                // by cts/tests/test/keystore.
+                if (provider.getName().startsWith("AndroidKeyStore")) {
+                    continue;
+                }
+
+                try {
+                    checkCipher(testVector, provider.getName());
+                } catch (Throwable e) {
+                    logTestFailure(out, provider.getName(), testVector, e);
+                }
+            }
+        }
+        out.flush();
+        if (errBuffer.size() > 0) {
+            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
+        }
+    }
+
+    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, provider);
+            } catch (Throwable e) {
+                logTestFailure(out, provider, p, e);
+            }
+        }
+        out.flush();
+        if (errBuffer.size() > 0) {
+            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
+        }
+    }
+
+    private void logTestFailure(PrintStream logStream, String provider, CipherTestParam params,
+            Throwable e) {
+        logStream.append("Error encountered checking " + params.transformation);
+
+        if (params.encryptKey instanceof SecretKey) {
+            logStream.append(", keySize=" + (params.encryptKey.getEncoded().length * 8));
+        }
+
+        if (params.spec instanceof OAEPParameterSpec) {
+            OAEPParameterSpec oaepSpec = (OAEPParameterSpec) params.spec;
+            logStream.append(", OAEPSpec{digest=" + oaepSpec.getDigestAlgorithm() + ", mgfAlg="
+                    + oaepSpec.getMGFAlgorithm());
+            if (oaepSpec.getMGFParameters() instanceof MGF1ParameterSpec) {
+                MGF1ParameterSpec mgf1Spec = (MGF1ParameterSpec) oaepSpec.getMGFParameters();
+                logStream.append(", mgf1Hash=" + mgf1Spec.getDigestAlgorithm());
+            }
+            logStream.append(", pSource=");
+            PSource pSource = oaepSpec.getPSource();
+            logStream.append(pSource.getAlgorithm());
+            if (pSource.getAlgorithm().equals("PSpecified")) {
+                logStream.append(":{");
+                logStream.append(Arrays.toString(((PSource.PSpecified) pSource).getValue()));
+                logStream.append('}');
+            }
+            logStream.append('}');
+        }
+
+        logStream.append(" with provider " + provider + "\n");
+        e.printStackTrace(logStream);
+    }
+
+    private void checkCipher(CipherTestParam p, String provider) throws Exception {
+        if (!p.compatibleWith(provider)) {
+            return;
+        }
+        Cipher c = Cipher.getInstance(p.transformation, provider);
+
+        c.init(Cipher.ENCRYPT_MODE, p.encryptKey, p.spec);
+
+        // This doesn't quite work on OAEPPadding unless it's the default case,
+        // because its size depends on the message digest algorithms used.
+        if (!p.transformation.endsWith("OAEPPADDING")) {
+            assertEquals(p.transformation + " getBlockSize() ENCRYPT_MODE",
+                    getExpectedBlockSize(p.transformation, Cipher.ENCRYPT_MODE, provider),
+                    c.getBlockSize());
+        }
+        assertTrue(p.transformation + " getOutputSize(0) ENCRYPT_MODE",
+                getExpectedOutputSize(p.transformation, Cipher.ENCRYPT_MODE, provider) <= c
+                        .getOutputSize(0));
+
+        if (p.aad != null) {
+            c.updateAAD(p.aad);
+        }
+        final byte[] actualCiphertext = c.doFinal(p.plaintext);
+        if (!isRandomizedEncryption(p.transformation)) {
+            assertEquals(p.transformation + " " + provider, Arrays.toString(p.ciphertext),
+                    Arrays.toString(actualCiphertext));
+        }
+
+        c = Cipher.getInstance(p.transformation, provider);
+        c.init(Cipher.ENCRYPT_MODE, p.encryptKey, p.spec);
+        if (!(p instanceof OAEPCipherTestParam) || p.spec != null) {
+            assertCorrectAlgorithmParameters(provider, p.transformation, p.spec, c.getParameters());
+        }
+
+        byte[] emptyCipherText = c.doFinal();
+        assertNotNull(emptyCipherText);
+
+        c.init(Cipher.DECRYPT_MODE, p.decryptKey, p.spec);
+
+        assertEquals(p.transformation + " getBlockSize() DECRYPT_MODE",
+                getExpectedBlockSize(p.transformation, Cipher.DECRYPT_MODE, provider),
+                c.getBlockSize());
+
+        // This doesn't quite work on OAEPPadding unless it's the default case,
+        // because its size depends on the message digest algorithms used.
+        if (!p.transformation.endsWith("OAEPPADDING")) {
+            assertTrue(p.transformation + " getOutputSize(0) DECRYPT_MODE",
+                    getExpectedOutputSize(p.transformation, Cipher.DECRYPT_MODE, provider) <= c
+                            .getOutputSize(0));
+        }
+
+        if (!isAEAD(p.transformation)) {
+            try {
+                c.updateAAD(new byte[8]);
+                fail("Cipher should not support AAD");
+            } catch (UnsupportedOperationException expected) {
+            } catch (IllegalStateException expected) {
+            }
+        }
+
+        try {
+            byte[] emptyPlainText = c.doFinal(emptyCipherText);
+            assertEquals(Arrays.toString(new byte[0]), Arrays.toString(emptyPlainText));
+        } catch (AEADBadTagException maybe) {
+            if (!"AndroidOpenSSL".equals(provider) || !isAEAD(p.transformation)) {
+                throw maybe;
+            }
+        } catch (BadPaddingException maybe) {
+            // BC's OAEP has a bug where it doesn't support decrypt of a zero-length plaintext
+            if (!("BC".equals(provider) && p.transformation.contains("OAEP"))) {
+                throw maybe;
+            }
+        }
+
+        // decrypt an empty ciphertext; not valid for RSA
+        if (!p.transformation.contains("OAEP")) {
+            if ((!isAEAD(p.transformation)
+                    && (StandardNames.IS_RI || provider.equals("AndroidOpenSSL") ||
+                            (provider.equals("BC") && p.transformation.contains("/CTR/"))))
+                    || p.transformation.equals("ARC4")) {
+                assertEquals(Arrays.toString(new byte[0]),
+                             Arrays.toString(c.doFinal()));
+
+                c.update(new byte[0]);
+                assertEquals(Arrays.toString(new byte[0]),
+                             Arrays.toString(c.doFinal()));
+            } else if (provider.equals("BC") || isAEAD(p.transformation)) {
+                try {
+                    c.doFinal();
+                    fail(p.transformation + " " + provider);
+                } catch (IllegalBlockSizeException maybe) {
+                    if (isAEAD(p.transformation)) {
+                        throw maybe;
+                    }
+                } catch (AEADBadTagException maybe) {
+                    if (!isAEAD(p.transformation)) {
+                        throw maybe;
+                    }
+                }
+                try {
+                    c.update(new byte[0]);
+                    c.doFinal();
+                    fail(p.transformation + " " + provider);
+                } catch (IllegalBlockSizeException maybe) {
+                    if (isAEAD(p.transformation)) {
+                        throw maybe;
+                    }
+                } catch (AEADBadTagException maybe) {
+                    if (!isAEAD(p.transformation)) {
+                        throw maybe;
+                    }
+                }
+            } else {
+                throw new AssertionError("Define your behavior here for " + provider);
+            }
+        }
+
+        // Cipher might be in unspecified state from failures above.
+        c.init(Cipher.DECRYPT_MODE, p.decryptKey, p.spec);
+
+        // .doFinal(input)
+        {
+            if (p.aad != null) {
+                c.updateAAD(p.aad);
+            }
+            final byte[] actualPlaintext = c.doFinal(p.ciphertext);
+            assertEquals(Arrays.toString(p.plaintext), Arrays.toString(actualPlaintext));
+        }
+
+        // .doFinal(input, offset, len, output)
+        {
+            final byte[] largerThanCiphertext = new byte[p.ciphertext.length + 5];
+            System.arraycopy(p.ciphertext, 0, largerThanCiphertext, 5, p.ciphertext.length);
+
+            if (p.aad != null) {
+                final byte[] largerThanAad = new byte[p.aad.length + 100];
+                System.arraycopy(p.aad, 0, largerThanAad, 50, p.aad.length);
+                assertTrue(p.aad.length > 1);
+                c.updateAAD(largerThanAad, 50, 1);
+                c.updateAAD(largerThanAad, 51, p.aad.length - 1);
+            }
+
+            final byte[] actualPlaintext = new byte[c.getOutputSize(p.ciphertext.length)];
+            assertEquals(p.plaintext.length,
+                    c.doFinal(largerThanCiphertext, 5, p.ciphertext.length, actualPlaintext));
+            assertEquals(Arrays.toString(p.plaintext),
+                    Arrays.toString(Arrays.copyOfRange(actualPlaintext, 0, p.plaintext.length)));
+        }
+
+        // .doFinal(input, offset, len, output, offset)
+        {
+            final byte[] largerThanCiphertext = new byte[p.ciphertext.length + 10];
+            System.arraycopy(p.ciphertext, 0, largerThanCiphertext, 5, p.ciphertext.length);
+
+            if (p.aad != null) {
+                final byte[] largerThanAad = new byte[p.aad.length + 2];
+                System.arraycopy(p.aad, 0, largerThanAad, 2, p.aad.length);
+                c.updateAAD(largerThanAad, 2, p.aad.length);
+            }
+
+            final byte[] actualPlaintext = new byte[c.getOutputSize(p.ciphertext.length) + 2];
+            assertEquals(p.plaintext.length,
+                    c.doFinal(largerThanCiphertext, 5, p.ciphertext.length, actualPlaintext, 1));
+            assertEquals(Arrays.toString(p.plaintext),
+                    Arrays.toString(Arrays.copyOfRange(actualPlaintext, 1, p.plaintext.length + 1)));
+        }
+
+        if (!p.isStreamCipher && !p.transformation.endsWith("NOPADDING")
+                && !isRandomizedEncryption(p.transformation)) {
+            Cipher cNoPad = Cipher.getInstance(
+                    getCipherTransformationWithNoPadding(p.transformation), provider);
+            cNoPad.init(Cipher.DECRYPT_MODE, p.decryptKey, p.spec);
+
+            if (p.aad != null) {
+                c.updateAAD(p.aad);
+            }
+            final byte[] actualPlaintextPadded = cNoPad.doFinal(p.ciphertext);
+            assertEquals(provider + ":" + cNoPad.getAlgorithm(),
+                    Arrays.toString(p.plaintextPadded), Arrays.toString(actualPlaintextPadded));
+        }
+
+        // Test wrapping a key. Every cipher should be able to wrap.
+        {
+            // Generate a small SecretKey for AES.
+            KeyGenerator kg = KeyGenerator.getInstance("AES");
+            kg.init(128);
+            SecretKey sk = kg.generateKey();
+
+            // Wrap it
+            c = Cipher.getInstance(p.transformation, provider);
+            c.init(Cipher.WRAP_MODE, p.encryptKey, p.spec);
+            byte[] cipherText = c.wrap(sk);
+
+            // Unwrap it
+            c.init(Cipher.UNWRAP_MODE, p.decryptKey, p.spec);
+            Key decryptedKey = c.unwrap(cipherText, sk.getAlgorithm(), Cipher.SECRET_KEY);
+
+            assertEquals(
+                    "sk.getAlgorithm()=" + sk.getAlgorithm() + " decryptedKey.getAlgorithm()="
+                            + decryptedKey.getAlgorithm() + " encryptKey.getEncoded()="
+                            + Arrays.toString(sk.getEncoded()) + " decryptedKey.getEncoded()="
+                            + Arrays.toString(decryptedKey.getEncoded()), sk, decryptedKey);
+        }
+    }
+
+    /**
+     * Gets the Cipher transformation with the same algorithm and mode as the provided one but
+     * which uses no padding.
+     */
+    private static String getCipherTransformationWithNoPadding(String transformation) {
+        // The transformation is assumed to be in the Algorithm/Mode/Padding format.
+        int paddingModeDelimiterIndex = transformation.lastIndexOf('/');
+        if (paddingModeDelimiterIndex == -1) {
+            fail("No padding mode delimiter: " + transformation);
+        }
+        String paddingMode = transformation.substring(paddingModeDelimiterIndex + 1);
+        if (!paddingMode.toLowerCase().endsWith("padding")) {
+            fail("No padding mode specified:" + transformation);
+        }
+        return transformation.substring(0, paddingModeDelimiterIndex) + "/NoPadding";
+    }
+
+    @Test
+    public void testCipher_updateAAD_BeforeInit_Failure() throws Exception {
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
+
+        try {
+            c.updateAAD((byte[]) null);
+            fail("should not be able to call updateAAD before Cipher is initialized");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD((ByteBuffer) null);
+            fail("should not be able to call updateAAD before Cipher is initialized");
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            c.updateAAD(new byte[8]);
+            fail("should not be able to call updateAAD before Cipher is initialized");
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            c.updateAAD(null, 0, 8);
+            fail("should not be able to call updateAAD before Cipher is initialized");
+        } catch (IllegalStateException expected) {
+        }
+
+        ByteBuffer bb = ByteBuffer.allocate(8);
+        try {
+            c.updateAAD(bb);
+            fail("should not be able to call updateAAD before Cipher is initialized");
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    @Test
+    public void testCipher_updateAAD_AfterInit_Failure() throws Exception {
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
+        c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[128 / 8], "AES"));
+
+        try {
+            c.updateAAD((byte[]) null);
+            fail("should not be able to call updateAAD with null input");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD((ByteBuffer) null);
+            fail("should not be able to call updateAAD with null input");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD(null, 0, 8);
+            fail("should not be able to call updateAAD with null input");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD(new byte[8], -1, 7);
+            fail("should not be able to call updateAAD with invalid offset");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD(new byte[8], 0, -1);
+            fail("should not be able to call updateAAD with negative length");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD(new byte[8], 0, 8 + 1);
+            fail("should not be able to call updateAAD with too large length");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            c.updateAAD(new byte[8]);
+            fail("should not be able to call updateAAD on non-AEAD cipher");
+        } catch (UnsupportedOperationException expected) {
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    @Test
+    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, provider);
+            } catch (Exception e) {
+                logTestFailure(out, provider, p, e);
+            }
+        }
+        out.flush();
+        if (errBuffer.size() > 0) {
+            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
+        }
+    }
+
+    @Test
+    public void testCipher_DoFinal_wrapMode_Failure() throws Exception {
+        checkCipher_DoFinal_invalidMode_Failure(Cipher.WRAP_MODE);
+    }
+
+    @Test
+    public void testCipher_DoFinal_unwrapMode_Failure() throws Exception {
+        checkCipher_DoFinal_invalidMode_Failure(Cipher.UNWRAP_MODE);
+    }
+
+    /**
+     * Helper for testing that Cipher.doFinal() throws IllegalStateException when
+     * initialized in modes other than DECRYPT or ENCRYPT.
+     */
+    private static void checkCipher_DoFinal_invalidMode_Failure(int opmode) throws Exception {
+        String msg = String.format(Locale.US,
+                "doFinal() should throw IllegalStateException [mode=%d]", opmode);
+        int bs = createAesCipher(opmode).getBlockSize();
+        assertEquals(16, bs); // check test is set up correctly
+        try {
+            createAesCipher(opmode).doFinal();
+            fail(msg);
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            createAesCipher(opmode).doFinal(new byte[0]);
+            fail(msg);
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            createAesCipher(opmode).doFinal(new byte[2 * bs], 0, bs);
+            fail(msg);
+        } catch (IllegalStateException expected) {
+        }
+
+        try {
+            createAesCipher(opmode).doFinal(new byte[2 * bs], 0, bs, new byte[2 * bs], 0);
+            fail(msg);
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    @Test
+    public void testCipher_Update_wrapMode_Failure() throws Exception {
+        checkCipher_Update_invalidMode_Failure(Cipher.WRAP_MODE);
+    }
+
+    @Test
+    public void testCipher_Update_unwrapMode_Failure() throws Exception {
+        checkCipher_Update_invalidMode_Failure(Cipher.UNWRAP_MODE);
+    }
+
+    /**
+     * Helper for testing that Cipher.update() throws IllegalStateException when
+     * initialized in modes other than DECRYPT or ENCRYPT.
+     */
+    private static void checkCipher_Update_invalidMode_Failure(final int opmode) throws Exception {
+        String msg = "update() should throw IllegalStateException [mode=" + opmode + "]";
+        final int bs = createAesCipher(opmode).getBlockSize();
+        assertEquals(16, bs); // check test is set up correctly
+        assertIllegalStateException(msg, new Runnable() {
+            @Override
+            public void run() {
+                createAesCipher(opmode).update(new byte[0]);
+            }
+        });
+        assertIllegalStateException(msg, new Runnable() {
+            @Override
+            public void run() {
+                createAesCipher(opmode).update(new byte[2 * bs]);
+            }
+        });
+        assertIllegalStateException(msg, new Runnable() {
+            @Override
+            public void run() {
+                createAesCipher(opmode).update(
+                        new byte[2 * bs] /* input */, bs /* inputOffset */, 0 /* inputLen */);
+            }
+        });
+        try {
+            createAesCipher(opmode).update(new byte[2*bs] /* input */, 0 /* inputOffset */,
+                    2 * bs /* inputLen */, new byte[2 * bs] /* output */, 0 /* outputOffset */);
+            fail(msg);
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    @Test
+    public void testCipher_Update_WithZeroLengthInput_ReturnsNull() throws Exception {
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
+        c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
+        assertNull(c.update(new byte[0]));
+        assertNull(c.update(new byte[c.getBlockSize() * 2], 0, 0));
+
+        // Try with non-zero offset just in case the implementation mixes up offset and inputLen
+        assertNull(c.update(new byte[c.getBlockSize() * 2], 16, 0));
+    }
+
+    @Test
+    public void testCipher_Wrap_decryptMode_Failure() throws Exception {
+        checkCipher_Wrap_invalidMode_Failure(Cipher.DECRYPT_MODE);
+    }
+
+    @Test
+    public void testCipher_Wrap_encryptMode_Failure() throws Exception {
+        checkCipher_Wrap_invalidMode_Failure(Cipher.ENCRYPT_MODE);
+    }
+
+    @Test
+    public void testCipher_Wrap_unwrapMode_Failure() throws Exception {
+        checkCipher_Wrap_invalidMode_Failure(Cipher.UNWRAP_MODE);
+    }
+
+    /**
+     * Helper for testing that Cipher.wrap() throws IllegalStateException when
+     * initialized in modes other than WRAP.
+     */
+    private static void checkCipher_Wrap_invalidMode_Failure(int opmode) throws Exception {
+        KeyGenerator kg = KeyGenerator.getInstance("AES");
+        kg.init(128);
+        SecretKey key = kg.generateKey();
+        Cipher cipher = createAesCipher(opmode);
+        try {
+            cipher.wrap(key);
+            fail("wrap() should throw IllegalStateException [mode=" + opmode + "]");
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    @Test
+    public void testCipher_Unwrap_decryptMode_Failure() throws Exception {
+        checkCipher_Unwrap_invalidMode_Failure(Cipher.DECRYPT_MODE);
+    }
+
+    @Test
+    public void testCipher_Unwrap_encryptMode_Failure() throws Exception {
+        checkCipher_Unwrap_invalidMode_Failure(Cipher.ENCRYPT_MODE);
+    }
+
+    @Test
+    public void testCipher_Unwrap_wrapMode_Failure() throws Exception {
+        checkCipher_Unwrap_invalidMode_Failure(Cipher.WRAP_MODE);
+    }
+
+    /**
+     * Helper for testing that Cipher.unwrap() throws IllegalStateException when
+     * initialized in modes other than UNWRAP.
+     */
+    private static void checkCipher_Unwrap_invalidMode_Failure(int opmode) throws Exception {
+        KeyGenerator kg = KeyGenerator.getInstance("AES");
+        kg.init(128);
+        SecretKey key = kg.generateKey();
+        Cipher cipher = createAesCipher(opmode);
+        byte[] wrappedKey = createAesCipher(Cipher.WRAP_MODE).wrap(key);
+        try {
+            cipher.unwrap(wrappedKey, key.getAlgorithm(), Cipher.PRIVATE_KEY);
+            fail("unwrap() should throw IllegalStateException [mode=" + opmode + "]");
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    private void checkCipher_ShortBlock_Failure(CipherTestParam p, String provider) throws Exception {
+        // Do not try to test ciphers with no padding already.
+        String noPaddingTransform = getCipherTransformationWithNoPadding(p.transformation);
+        if (p.transformation.equals(noPaddingTransform)) {
+            return;
+        }
+
+        Cipher c = Cipher.getInstance(
+                getCipherTransformationWithNoPadding(p.transformation), provider);
+        if (c.getBlockSize() == 0) {
+            return;
+        }
+
+        if (!p.transformation.endsWith("NOPADDING")) {
+            c.init(Cipher.ENCRYPT_MODE, p.encryptKey);
+            try {
+                c.doFinal(new byte[] { 0x01, 0x02, 0x03 });
+                fail("Should throw IllegalBlockSizeException on wrong-sized block; transform="
+                        + p.transformation + " provider=" + provider);
+            } catch (IllegalBlockSizeException expected) {
+            }
+        }
+    }
+
+    // Test that when reading GCM parameters encoded using ASN1, a value for the tag size
+    // not present indicates a value of 12.
+    // https://b/29876633
+    @Test
+    public void test_DefaultGCMTagSizeAlgorithmParameterSpec() throws Exception {
+        Assume.assumeNotNull(Security.getProvider("BC"));
+        final String AES = "AES";
+        final String AES_GCM = "AES/GCM/NoPadding";
+        byte[] input = new byte[16];
+        byte[] key = new byte[16];
+        Cipher cipher = Cipher.getInstance(AES_GCM, "BC");
+        AlgorithmParameters param = AlgorithmParameters.getInstance("GCM");
+        param.init(new byte[] {
+            (byte) 48,    // DER encoding : tag_Sequence
+            (byte) 14,    // DER encoding : total length
+            (byte) 4,     // DER encoding : tag_OctetString
+            (byte) 12,    // DER encoding : counter length
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+            (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 });
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, AES), param);
+        byte[] ciphertext = cipher.update(input);
+        assertEquals(16, ciphertext.length);
+        byte[] tag = cipher.doFinal();
+        assertEquals(12, tag.length);
+    }
+
+    @Test
+    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 {
+        Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding", provider);
+        c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
+
+        final byte[] fragmentOutput = c.update(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext);
+        if (fragmentOutput != null) {
+            assertEquals(0, fragmentOutput.length);
+        }
+
+        // Provide null buffer.
+        {
+            try {
+                c.doFinal(null, 0);
+                fail("Should throw NullPointerException on null output buffer");
+            } catch (NullPointerException expected) {
+            } catch (IllegalArgumentException expected) {
+            }
+        }
+
+        // Provide short buffer.
+        {
+            final byte[] output = new byte[c.getBlockSize() - 1];
+            try {
+                c.doFinal(output, 0);
+                fail("Should throw ShortBufferException on short output buffer");
+            } catch (ShortBufferException expected) {
+            }
+        }
+
+        // Start 1 byte into output buffer.
+        {
+            final byte[] output = new byte[c.getBlockSize()];
+            try {
+                c.doFinal(output, 1);
+                fail("Should throw ShortBufferException on short output buffer");
+            } catch (ShortBufferException expected) {
+            }
+        }
+
+        // Should keep data for real output buffer
+        {
+            final byte[] output = new byte[c.getBlockSize()];
+            assertEquals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted.length, c.doFinal(output, 0));
+            assertTrue(Arrays.equals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted, output));
+        }
+    }
+
+    @Test
+    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 {
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
+        assertEquals(provider, c.getProvider().getName());
+        c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
+
+        for (int i = 0; i < AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1; i++) {
+            final byte[] outputFragment = c.update(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded, i, 1);
+            if (outputFragment != null) {
+                assertEquals(0, outputFragment.length);
+            }
+        }
+
+        final byte[] output = c.doFinal(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
+                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1, 1);
+        assertNotNull(provider, output);
+        assertEquals(provider, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length,
+                output.length);
+
+        assertTrue(provider, Arrays.equals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted, output));
+    }
+
+    private static final byte[] AES_IV_ZEROES = new byte[] {
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+    };
+
+    @Test
+    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 {
+        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
+
+        AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
+        try {
+            c.init(Cipher.ENCRYPT_MODE, AES_128_KEY, spec);
+            fail("Should not accept an IV in ECB mode; provider=" + provider);
+        } catch (InvalidAlgorithmParameterException expected) {
+        }
+    }
+
+    @Test
+    public void testRC4_MultipleKeySizes() throws Exception {
+        final int SMALLEST_KEY_SIZE = 40;
+        final int LARGEST_KEY_SIZE = 1024;
+
+        /* Make an array of keys for our tests */
+        SecretKey[] keys = new SecretKey[LARGEST_KEY_SIZE - SMALLEST_KEY_SIZE];
+        {
+            KeyGenerator kg = KeyGenerator.getInstance("ARC4");
+            for (int keysize = SMALLEST_KEY_SIZE; keysize < LARGEST_KEY_SIZE; keysize++) {
+                final int index = keysize - SMALLEST_KEY_SIZE;
+                kg.init(keysize);
+                keys[index] = kg.generateKey();
+            }
+        }
+
+        /*
+         * Use this to compare the output of the first provider against
+         * subsequent providers.
+         */
+        String[] expected = new String[LARGEST_KEY_SIZE - SMALLEST_KEY_SIZE];
+
+        /* Find all providers that provide ARC4. We must have at least one! */
+        Map<String, String> filter = new HashMap<String, String>();
+        filter.put("Cipher.ARC4", "");
+        Provider[] providers = Security.getProviders(filter);
+        assertTrue("There must be security providers of Cipher.ARC4", providers.length > 0);
+
+        /* Keep track of this for later error messages */
+        String firstProvider = providers[0].getName();
+
+        for (Provider p : providers) {
+            Cipher c = Cipher.getInstance("ARC4", p);
+
+            for (int keysize = SMALLEST_KEY_SIZE; keysize < LARGEST_KEY_SIZE; keysize++) {
+                final int index = keysize - SMALLEST_KEY_SIZE;
+                final SecretKey sk = keys[index];
+
+                /*
+                 * Test that encryption works. Donig this in a loop also has the
+                 * benefit of testing that re-initialization works for this
+                 * cipher.
+                 */
+                c.init(Cipher.ENCRYPT_MODE, sk);
+                byte[] cipherText = c.doFinal(ORIGINAL_PLAIN_TEXT);
+                assertNotNull(cipherText);
+
+                /*
+                 * Compare providers against eachother to make sure they're all
+                 * in agreement. This helps when you add a brand new provider.
+                 */
+                if (expected[index] == null) {
+                    expected[index] = Arrays.toString(cipherText);
+                } else {
+                    assertEquals(firstProvider + " should output the same as " + p.getName()
+                            + " for key size " + keysize, expected[index],
+                            Arrays.toString(cipherText));
+                }
+
+                c.init(Cipher.DECRYPT_MODE, sk);
+                byte[] actualPlaintext = c.doFinal(cipherText);
+                assertEquals("Key size: " + keysize, Arrays.toString(ORIGINAL_PLAIN_TEXT),
+                        Arrays.toString(actualPlaintext));
+            }
+        }
+    }
+
+    @Test
+    public void testAES_keyConstrained() throws Exception {
+        Provider[] providers = Security.getProviders();
+        for (Provider p : providers) {
+            for (Provider.Service s : p.getServices()) {
+                if (s.getType().equals("Cipher")) {
+                    if (s.getAlgorithm().startsWith("AES_128/")) {
+                        Cipher c = Cipher.getInstance(s.getAlgorithm(), p);
+                        assertTrue(s.getAlgorithm(), checkAES_keyConstraint(c, 128));
+                        assertFalse(s.getAlgorithm(), checkAES_keyConstraint(c, 192));
+                        assertFalse(s.getAlgorithm(), checkAES_keyConstraint(c, 256));
+                    } else if (s.getAlgorithm().startsWith("AES_256/")) {
+                        Cipher c = Cipher.getInstance(s.getAlgorithm(), p);
+                        assertFalse(s.getAlgorithm(), checkAES_keyConstraint(c, 128));
+                        assertFalse(s.getAlgorithm(), checkAES_keyConstraint(c, 192));
+                        assertTrue(s.getAlgorithm(), checkAES_keyConstraint(c, 256));
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean checkAES_keyConstraint(Cipher c, int keySize) throws Exception {
+        KeyGenerator kg = KeyGenerator.getInstance(getBaseAlgorithm(c.getAlgorithm()));
+        kg.init(keySize);
+        SecretKey key = kg.generateKey();
+        try {
+            c.init(Cipher.ENCRYPT_MODE, key);
+            return true;
+        } catch (InvalidKeyException e) {
+            return false;
+        }
+    }
+
+    /*
+     * When in decrypt mode and using padding, the buffer shouldn't necessarily have room for an
+     * extra block when using padding.
+     * http://b/19186852
+     */
+    @Test
+    public void testDecryptBufferMultipleBlockSize_mustNotThrowException() throws Exception {
+        String testString = "Hello, World!";
+        byte[] testKey = "0123456789012345".getBytes(StandardCharsets.US_ASCII);
+        String testedCipher = "AES/ECB/PKCS7Padding";
+
+        Cipher encCipher = Cipher.getInstance(testedCipher);
+        encCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(testKey, "AES"));
+        byte[] plainBuffer = testString.getBytes(StandardCharsets.US_ASCII);
+        byte[] encryptedBuffer = new byte[16];
+        int encryptedLength = encCipher.doFinal(
+                plainBuffer, 0, plainBuffer.length, encryptedBuffer);
+        assertEquals(16, encryptedLength);
+
+        Cipher cipher = Cipher.getInstance(testedCipher);
+        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(testKey, "AES"));
+        // Must not throw exception.
+        int unencryptedBytes = cipher.doFinal(
+                encryptedBuffer, 0, encryptedBuffer.length, encryptedBuffer);
+        assertEquals(testString,
+                new String(encryptedBuffer, 0, unencryptedBytes, StandardCharsets.US_ASCII));
+    }
+
+    /**
+     * When using padding in decrypt mode, ensure that empty buffers decode to empty strings
+     * (no padding needed for the empty buffer).
+     * http://b/19186852
+     */
+    @Test
+    public void testDecryptBufferZeroSize_mustDecodeToEmptyString() throws Exception {
+        String[] androidOpenSSLCiphers = { "AES/CBC/PKCS5PADDING", "AES/CBC/PKCS7PADDING",
+                "AES/ECB/PKCS5PADDING", "AES/ECB/PKCS7PADDING", "DESEDE/CBC/PKCS5PADDING",
+                "DESEDE/CBC/PKCS7PADDING" };
+        for (String c : androidOpenSSLCiphers) {
+            Cipher cipher = Cipher.getInstance(c);
+            assertTrue(Conscrypt.isConscrypt(cipher.getProvider()));
+            if (c.contains("/CBC/")) {
+                cipher.init(Cipher.DECRYPT_MODE,
+                        new SecretKeySpec("0123456789012345".getBytes(StandardCharsets.US_ASCII),
+                                c.startsWith("AES/") ? "AES" : "DESEDE"),
+                        new IvParameterSpec(("01234567" + (c.startsWith("AES/") ? "89012345" : ""))
+                                                    .getBytes(StandardCharsets.US_ASCII)));
+            } else {
+                cipher.init(Cipher.DECRYPT_MODE,
+                        new SecretKeySpec("0123456789012345".getBytes(StandardCharsets.US_ASCII),
+                                c.startsWith("AES/") ? "AES" : "DESEDE"));
+            }
+
+            byte[] buffer = new byte[0];
+            int bytesProduced = cipher.doFinal(buffer, 0, buffer.length, buffer);
+            assertEquals("", new String(buffer, 0, bytesProduced, StandardCharsets.US_ASCII));
+        }
+    }
+
+    /**
+     * Check that RSA with OAEPPadding is supported.
+     * http://b/22208820
+     */
+    @Test
+    public void test_RSA_OAEPPadding() throws Exception {
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+        keyGen.initialize(1024, SecureRandom.getInstance("SHA1PRNG"));
+        Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding");
+        cipher.init(Cipher.ENCRYPT_MODE, keyGen.generateKeyPair().getPublic());
+        cipher.doFinal(new byte[] {1,2,3,4});
+    }
+
+    /**
+     * Check that initializing with a GCM AlgorithmParameters produces the same result
+     * as initializing with a GCMParameterSpec.
+     */
+    @Test
+    public void test_AESGCMNoPadding_init_algParams() throws Exception {
+        SecretKeySpec key = new SecretKeySpec(new byte[16], "AES");
+        GCMParameterSpec spec = new GCMParameterSpec(96, new byte[12]);
+        AlgorithmParameters params = AlgorithmParameters.getInstance("GCM");
+        params.init(spec);
+        Cipher c1 = Cipher.getInstance("AES/GCM/NoPadding");
+        Cipher c2 = Cipher.getInstance("AES/GCM/NoPadding");
+
+        c1.init(Cipher.ENCRYPT_MODE, key, spec);
+        c2.init(Cipher.ENCRYPT_MODE, key, params);
+        // Cipher can adjust the provider based on the reponses to the init call, make sure
+        // we got the same provider for both
+        assertEquals(c1.getProvider(), c2.getProvider());
+        c1.updateAAD(new byte[] {
+                0x01, 0x02, 0x03, 0x04, 0x05,
+        });
+        c2.updateAAD(new byte[] {
+                0x01, 0x02, 0x03, 0x04, 0x05,
+        });
+
+        assertEquals(Arrays.toString(c1.doFinal()), Arrays.toString(c2.doFinal()));
+    }
+
+    /**
+     * http://b/27224566
+     * http://b/27994930
+     * Check that a PBKDF2WITHHMACSHA1 secret key factory works well with a
+     * PBEWITHSHAAND128BITAES-CBC-BC cipher. The former is PKCS5 and the latter is PKCS12, and so
+     * mixing them is not recommended. However, until 1.52 BouncyCastle was accepting this mixture,
+     * assuming the IV was a 0 vector. Some apps still use this functionality. This
+     * compatibility is likely to be removed in later versions of Android.
+     * TODO(27995180): consider whether we keep this compatibility. Consider whether we only allow
+     * if an IV is passed in the parameters.
+     */
+    @Test
+    public void test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_noIV() throws Exception {
+        Assume.assumeNotNull(Security.getProvider("BC"));
+        byte[] plaintext = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+                17, 18, 19 };
+        byte[] ciphertext = new byte[] {  92, -65, -128, 16, -102, -115, -44, 52, 16, 124, -34,
+                -45, 58, -70, -17, 127, 119, -67, 87, 91, 63, -13, -40, 9, 97, -17, -71, 97, 10,
+                -61, -19, -73 };
+        SecretKeyFactory skf =
+                SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA1");
+        PBEKeySpec pbeks = new PBEKeySpec("password".toCharArray(),
+                "salt".getBytes(TestUtils.UTF_8),
+                100, 128);
+        SecretKey secretKey = skf.generateSecret(pbeks);
+
+        Cipher cipher =
+                Cipher.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
+        PBEParameterSpec paramSpec = new PBEParameterSpec("salt".getBytes(TestUtils.UTF_8), 100);
+        cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
+        assertEquals(Arrays.toString(ciphertext), Arrays.toString(cipher.doFinal(plaintext)));
+
+        secretKey = skf.generateSecret(pbeks);
+        cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
+        assertEquals(Arrays.toString(plaintext), Arrays.toString(cipher.doFinal(ciphertext)));
+    }
+
+    /**
+     * http://b/27224566
+     * http://b/27994930
+     * Check that a PBKDF2WITHHMACSHA1 secret key factory works well with a
+     * PBEWITHSHAAND128BITAES-CBC-BC cipher. The former is PKCS5 and the latter is PKCS12, and so
+     * mixing them is not recommended. However, until 1.52 BouncyCastle was accepting this mixture,
+     * assuming the IV was a 0 vector. Some apps still use this functionality. This
+     * compatibility is likely to be removed in later versions of Android.
+     * TODO(27995180): consider whether we keep this compatibility. Consider whether we only allow
+     * if an IV is passed in the parameters.
+     */
+    @Test
+    public void test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_withIV() throws Exception {
+        Assume.assumeNotNull(Security.getProvider("BC"));
+        byte[] plaintext = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,  12, 13, 14, 15, 16,
+                17, 18, 19 };
+        byte[] ciphertext = { 68, -87, 71, -6, 32, -77, 124, 3, 35, -26, 96, -16, 100, -17, 52, -32,
+                110, 26, -117, 112, -25, -113, -58, -30, 19, -46, -21, 59, -126, -8, -70, -89 };
+        byte[] iv = new byte[] { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+        SecretKeyFactory skf =
+                SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA1");
+        PBEKeySpec pbeks = new PBEKeySpec("password".toCharArray(),
+                "salt".getBytes(TestUtils.UTF_8),
+                100, 128);
+        SecretKey secretKey = skf.generateSecret(pbeks);
+        Cipher cipher =
+                Cipher.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
+        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
+        assertEquals(Arrays.toString(ciphertext), Arrays.toString(cipher.doFinal(plaintext)));
+
+        secretKey = skf.generateSecret(pbeks);
+        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
+        assertEquals(Arrays.toString(plaintext), Arrays.toString(cipher.doFinal(ciphertext)));
+    }
+
+    private static Cipher createAesCipher(int opmode) {
+        try {
+            final Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
+            c.init(opmode, AES_128_KEY);
+            return c;
+        } catch (Exception e) {
+            fail("Unexpected Exception: " + e.getMessage());
+            return null; // unreachable
+        }
+    }
+
+    /**
+     * Asserts that running the given runnable results in an IllegalStateException
+     */
+    private static void assertIllegalStateException(String failureMessage, Runnable runnable) {
+        try {
+            runnable.run();
+            fail(failureMessage);
+        } catch (IllegalStateException expected) {
+            // expected
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java
new file mode 100644
index 0000000..7a0d8f0
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java
@@ -0,0 +1,551 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.TestUtils;
+import dalvik.system.VMRuntime;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import javax.crypto.KeyAgreement;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import junit.framework.AssertionFailedError;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+
+/**
+ * Tests for all registered Elliptic Curve Diffie-Hellman {@link KeyAgreement} providers.
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class ECDHKeyAgreementTest {
+
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    // Two key pairs and the resulting shared secret for the Known Answer Test
+    private static final byte[] KAT_PUBLIC_KEY1_X509 = TestUtils.decodeHex(
+            "3059301306072a8648ce3d020106082a8648ce3d030107034200049fc2f71f85446b1371244491d83"
+            + "9cf97b5d27cedbb04d2c0058b59709df3a216e6b4ca1b2d622588c5a0e6968144a8965e816a600c"
+            + "05305a1da3df2bf02b41d1");
+    private static final byte[] KAT_PRIVATE_KEY1_PKCS8 = TestUtils.decodeHex(
+            "308193020100301306072a8648ce3d020106082a8648ce3d030107047930770201010420e1e683003"
+            + "c8b963a92742e5f955ce7fddc81d0c3ae9b149d6af86a0cacb2271ca00a06082a8648ce3d030107"
+            + "a144034200049fc2f71f85446b1371244491d839cf97b5d27cedbb04d2c0058b59709df3a216e6b"
+            + "4ca1b2d622588c5a0e6968144a8965e816a600c05305a1da3df2bf02b41d1");
+
+    private static final byte[] KAT_PUBLIC_KEY2_X509 = TestUtils.decodeHex(
+            "3059301306072a8648ce3d020106082a8648ce3d03010703420004358efb6d91e5bbcae21774af3f6"
+            + "d85d0848630e7e61dbeb5ac9e47036ed0f8d38c7a1d1bb249f92861c7c9153fff33f45ab5b171eb"
+            + "e8cad741125e6bb4fc6b07");
+    private static final byte[] KAT_PRIVATE_KEY2_PKCS8 = TestUtils.decodeHex(
+            "308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104202b1810a69"
+            + "e12b74d50bf0343168f705f0104f76299855268aa526fdb31e6eec0a00a06082a8648ce3d030107"
+            + "a14403420004358efb6d91e5bbcae21774af3f6d85d0848630e7e61dbeb5ac9e47036ed0f8d38c7"
+            + "a1d1bb249f92861c7c9153fff33f45ab5b171ebe8cad741125e6bb4fc6b07");
+
+    private static final byte[] KAT_SECRET =
+            TestUtils.decodeHex("4faa0594c0e773eb26c8df2163af2443e88aab9578b9e1f324bc61e42d222783");
+
+    private static final ECPublicKey KAT_PUBLIC_KEY1;
+    private static final ECPrivateKey KAT_PRIVATE_KEY1;
+    private static final ECPublicKey KAT_PUBLIC_KEY2;
+    private static final ECPrivateKey KAT_PRIVATE_KEY2;
+    static {
+        try {
+            KAT_PUBLIC_KEY1 = getPublicKey(KAT_PUBLIC_KEY1_X509);
+            KAT_PRIVATE_KEY1 = getPrivateKey(KAT_PRIVATE_KEY1_PKCS8);
+            KAT_PUBLIC_KEY2 = getPublicKey(KAT_PUBLIC_KEY2_X509);
+            KAT_PRIVATE_KEY2 = getPrivateKey(KAT_PRIVATE_KEY2_PKCS8);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to decode KAT key pairs using default provider", e);
+        }
+    }
+
+    @BeforeClass
+    public static void setUp() {
+        TestUtils.assumeAllowsUnsignedCrypto();
+    }
+
+    /**
+     * Performs a known-answer test of the shared secret for all permutations of {@code Providers}
+     * of: first key pair, second key pair, and the {@code KeyAgreement}. This is to check that
+     * the {@code KeyAgreement} instances work with keys of all registered providers.
+     */
+    @Test
+    public void testKnownAnswer() throws Exception {
+        for (Provider keyFactoryProvider1 : getKeyFactoryProviders()) {
+            ECPrivateKey privateKey1 = getPrivateKey(KAT_PRIVATE_KEY1_PKCS8, keyFactoryProvider1);
+            ECPublicKey publicKey1 = getPublicKey(KAT_PUBLIC_KEY1_X509, keyFactoryProvider1);
+            for (Provider keyFactoryProvider2 : getKeyFactoryProviders()) {
+                ECPrivateKey privateKey2 =
+                        getPrivateKey(KAT_PRIVATE_KEY2_PKCS8, keyFactoryProvider2);
+                ECPublicKey publicKey2 =
+                        getPublicKey(KAT_PUBLIC_KEY2_X509, keyFactoryProvider2);
+                for (Provider keyAgreementProvider : getKeyAgreementProviders()) {
+                    try {
+                        testKnownAnswer(publicKey1, privateKey1, publicKey2, privateKey2,
+                                keyAgreementProvider);
+                    } catch (Throwable e) {
+                        throw new RuntimeException(getClass().getSimpleName() + ".testKnownAnswer("
+                                + keyFactoryProvider1.getName()
+                                + ", " + keyFactoryProvider2.getName()
+                                + ", " + keyAgreementProvider.getName() + ")",
+                                e);
+                    }
+                }
+            }
+        }
+    }
+
+    void testKnownAnswer(
+            ECPublicKey publicKey1, ECPrivateKey privateKey1,
+            ECPublicKey publicKey2, ECPrivateKey privateKey2,
+            Provider keyAgreementProvider) throws Exception {
+        assertTrue(Arrays.equals(
+                KAT_SECRET, generateSecret(keyAgreementProvider, privateKey1, publicKey2)));
+        assertTrue(Arrays.equals(
+                KAT_SECRET, generateSecret(keyAgreementProvider, privateKey2, publicKey1)));
+    }
+
+    @Test
+    public void testGetAlgorithm() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGetAlgorithm(Provider provider) throws Exception {
+        assertEquals("ECDH", getKeyAgreement(provider).getAlgorithm());
+    }
+
+    @Test
+    public void testGetProvider() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGetProvider(Provider provider) throws Exception {
+        assertSame(provider, getKeyAgreement(provider).getProvider());
+    }
+
+    @Test
+    public void testInit_withNullPrivateKey() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testInit_withNullPrivateKey(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        try {
+            keyAgreement.init(null);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    @Test
+    public void testInit_withUnsupportedPrivateKeyType() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testInit_withUnsupportedPrivateKeyType(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        try {
+            keyAgreement.init(KAT_PUBLIC_KEY1);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    @Test
+    public void testInit_withUnsupportedAlgorithmParameterSpec() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testInit_withUnsupportedAlgorithmParameterSpec(Provider provider) throws Exception {
+        try {
+            getKeyAgreement(provider).init(KAT_PRIVATE_KEY1, new ECGenParameterSpec("prime256v1"));
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+    }
+
+    @Test
+    public void testDoPhase_whenNotInitialized() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_whenNotInitialized(Provider provider) throws Exception {
+        try {
+            getKeyAgreement(provider).doPhase(KAT_PUBLIC_KEY1, true);
+            fail();
+        } catch (IllegalStateException expected) {}
+    }
+
+    @Test
+    public void testDoPhaseReturnsNull() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhaseReturnsNull(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        assertNull(keyAgreement.doPhase(KAT_PUBLIC_KEY2, true));
+    }
+
+    @Test
+    public void testDoPhase_withPhaseWhichIsNotLast() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_withPhaseWhichIsNotLast(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        try {
+            keyAgreement.doPhase(KAT_PUBLIC_KEY2, false);
+            fail();
+        } catch (IllegalStateException expected) {}
+    }
+
+    @Test
+    public void testDoPhase_withNullKey() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_withNullKey(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        try {
+            keyAgreement.doPhase(null, true);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    @Test
+    public void testDoPhase_withInvalidKeyType() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_withInvalidKeyType(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        try {
+            keyAgreement.doPhase(KAT_PRIVATE_KEY1, true);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    @Test
+    public void testGenerateSecret_withNullOutputBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withNullOutputBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+        try {
+            keyAgreement.generateSecret(null, 0);
+            fail();
+        } catch (NullPointerException expected) {}
+    }
+
+    @Test
+    public void testGenerateSecret_withBufferOfTheRightSize() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withBufferOfTheRightSize(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+
+        byte[] buffer = new byte[KAT_SECRET.length];
+        int secretLengthBytes = keyAgreement.generateSecret(buffer, 0);
+        assertEquals(KAT_SECRET.length, secretLengthBytes);
+        assertTrue(Arrays.equals(KAT_SECRET, buffer));
+    }
+
+    @Test
+    public void testGenerateSecret_withLargerThatNeededBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withLargerThatNeededBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+
+        // Place the shared secret in the middle of the larger buffer and check that only that
+        // part of the buffer is affected.
+        byte[] buffer = new byte[KAT_SECRET.length + 2];
+        buffer[0] = (byte) 0x85; // arbitrary canary value
+        buffer[buffer.length - 1] = (byte) 0x3b; // arbitrary canary value
+        int secretLengthBytes = keyAgreement.generateSecret(buffer, 1);
+        assertEquals(KAT_SECRET.length, secretLengthBytes);
+        assertEquals((byte) 0x85, buffer[0]);
+        assertEquals((byte) 0x3b, buffer[buffer.length - 1]);
+        byte[] secret = new byte[KAT_SECRET.length];
+        System.arraycopy(buffer, 1, secret, 0, secret.length);
+        assertTrue(Arrays.equals(KAT_SECRET, secret));
+    }
+
+    @Test
+    public void testGenerateSecret_withSmallerThanNeededBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withSmallerThanNeededBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+        try {
+            // Although the buffer is big enough (1024 bytes) the shared secret should be placed
+            // at offset 1020 thus leaving only 4 bytes for the secret, which is not enough.
+            keyAgreement.generateSecret(new byte[1024], 1020);
+            fail();
+        } catch (ShortBufferException expected) {}
+    }
+
+    @Test
+    public void testGenerateSecret_withoutBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withoutBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY2);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY1, true);
+
+        byte[] secret = keyAgreement.generateSecret();
+        assertTrue(Arrays.equals(KAT_SECRET, secret));
+    }
+
+    @Test
+    public void testGenerateSecret_withAlgorithm() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withAlgorithm(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY2);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY1, true);
+
+        try {
+            SecretKey key = keyAgreement.generateSecret("AES");
+            assertEquals("AES", key.getAlgorithm());
+            // The check below will need to change if it's a hardware-backed key.
+            // We'll have to encrypt a known plaintext and check that the ciphertext is as
+            // expected.
+            assertTrue(Arrays.equals(KAT_SECRET, key.getEncoded()));
+        } catch (NoSuchAlgorithmException e) {
+            // This provider doesn't support AES, that's fine as long as it's not Conscrypt
+            assertFalse(Conscrypt.isConscrypt(provider));
+        }
+    }
+
+    @Test
+    public void testDoPhase_IncompatibleCurves_Failure() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_IncompatibleCurves_Failure(Provider provider) throws Exception {
+        // The SunEC provider tries to pass a sun-only AlgorithmParameterSpec to the default
+        // AlgorithmParameters:EC when its KeyPairGenerator is initialized.  Since Conscrypt
+        // is the highest-ranked provider when running our tests, its implementation of
+        // AlgorithmParameters:EC is returned, and it doesn't understand the special
+        // AlgorithmParameterSpec, so the KeyPairGenerator can't be initialized.
+        if (provider.getName().equalsIgnoreCase("SunEC")) {
+            return;
+        }
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", provider);
+        ECGenParameterSpec ecSpec256 = new ECGenParameterSpec("secp256r1");
+        keyGen.initialize(ecSpec256);
+        KeyPair keyPairA = keyGen.generateKeyPair();
+
+        ECGenParameterSpec ecSpec224 = new ECGenParameterSpec("secp224r1");
+        keyGen.initialize(ecSpec224);
+        KeyPair keyPairB = keyGen.generateKeyPair();
+
+        assertFalse(((ECKey) keyPairA.getPublic())
+                            .getParams()
+                            .equals(((ECKey) keyPairB.getPublic()).getParams()));
+
+        KeyAgreement kaA = KeyAgreement.getInstance("ECDH", provider);
+        kaA.init(keyPairA.getPrivate());
+        try {
+            kaA.doPhase(keyPairB.getPublic(), true);
+            kaA.generateSecret();
+            fail("Generated secrets with mixed keys");
+        } catch (InvalidKeyException expected) {
+        }
+    }
+
+    private void invokeCallingMethodForEachKeyAgreementProvider() throws Exception {
+        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+        String callingMethodName = null;
+        for (int i = 0; i < stackTrace.length; i++) {
+            if ("invokeCallingMethodForEachKeyAgreementProvider".equals(
+                    stackTrace[i].getMethodName())) {
+                callingMethodName = stackTrace[i + 1].getMethodName();
+            }
+        }
+        if (callingMethodName == null) {
+            throw new RuntimeException("Failed to deduce calling method name from stack trace");
+        }
+
+        String invokedMethodName = callingMethodName;
+        Method method;
+        try {
+            method = getClass().getDeclaredMethod(invokedMethodName, Provider.class);
+        } catch (NoSuchMethodError e) {
+            throw new AssertionFailedError("Failed to find per-Provider test method "
+                    + getClass().getSimpleName() + "." + invokedMethodName + "(Provider)");
+        }
+
+        for (Provider provider : getKeyAgreementProviders()) {
+            try {
+                method.invoke(this, provider);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(getClass().getSimpleName() + "." + invokedMethodName
+                        + "(provider: " + provider.getName() + ") failed",
+                        e.getCause());
+            }
+        }
+    }
+
+    private static Provider[] getKeyAgreementProviders() {
+        Provider[] providers = Security.getProviders("KeyAgreement.ECDH");
+        if (providers == null) {
+            return new Provider[0];
+        }
+        // Sort providers by name to guarantee deterministic order in which providers are used in
+        // the tests.
+        return sortByName(providers);
+    }
+
+    private static Provider[] getKeyFactoryProviders() {
+        Provider[] providers = Security.getProviders("KeyFactory.EC");
+        if (providers == null) {
+            return new Provider[0];
+        }
+
+        // Do not test AndroidKeyStore's KeyFactory. It only handles Android Keystore-backed keys.
+        // It's OKish not to test AndroidKeyStore's KeyFactory here because it's tested by
+        // cts/tests/test/keystore.
+        List<Provider> filteredProvidersList = new ArrayList<Provider>(providers.length);
+        for (Provider provider : providers) {
+            if ("AndroidKeyStore".equals(provider.getName())) {
+                continue;
+            }
+            filteredProvidersList.add(provider);
+        }
+        providers = filteredProvidersList.toArray(new Provider[filteredProvidersList.size()]);
+
+        // Sort providers by name to guarantee deterministic order in which providers are used in
+        // the tests.
+        return sortByName(providers);
+    }
+
+    private static ECPrivateKey getPrivateKey(byte[] pkcs8EncodedKey, Provider provider)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
+        return (ECPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey));
+    }
+
+    private static ECPublicKey getPublicKey(byte[] x509EncodedKey, Provider provider)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
+        return (ECPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedKey));
+    }
+
+    private static ECPrivateKey getPrivateKey(byte[] pkcs8EncodedKey)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC");
+        return (ECPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey));
+    }
+
+    private static ECPublicKey getPublicKey(byte[] x509EncodedKey)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC");
+        return (ECPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedKey));
+    }
+
+    private static KeyAgreement getKeyAgreement(Provider provider) throws NoSuchAlgorithmException {
+        return KeyAgreement.getInstance("ECDH", provider);
+    }
+
+    private static byte[] generateSecret(
+            Provider keyAgreementProvider, PrivateKey privateKey, PublicKey publicKey)
+            throws GeneralSecurityException {
+        KeyAgreement keyAgreement = getKeyAgreement(keyAgreementProvider);
+        keyAgreement.init(privateKey);
+        keyAgreement.doPhase(publicKey, true);
+        return keyAgreement.generateSecret();
+    }
+
+    private static Provider[] sortByName(Provider[] providers) {
+        Arrays.sort(providers, new Comparator<Provider>() {
+            @Override
+            public int compare(Provider lhs, Provider rhs) {
+                return lhs.getName().compareTo(rhs.getName());
+            }
+        });
+        return providers;
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/KeyGeneratorTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/KeyGeneratorTest.java
new file mode 100644
index 0000000..4028ce9
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/crypto/KeyGeneratorTest.java
@@ -0,0 +1,194 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import dalvik.system.VMRuntime;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import sun.security.jca.Providers;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyGeneratorTest {
+    
+    // BEGIN Android-Added: Allow access to deprecated BC algorithms.
+    // Allow access to deprecated BC algorithms in this test, so we can ensure they
+    // continue to work
+    @BeforeClass
+    public static void enableDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    @AfterClass
+    public static void restoreDeprecatedAlgorithms() {
+        Providers.setMaximumAllowableApiLevelForBcDeprecation(
+                Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION);
+    }
+    // END Android-Added: Allow access to deprecated BC algorithms.
+
+    private static boolean isUnsupported(KeyGenerator kg) {
+        // Don't bother testing "Sun..." KeyGenerators or BC outside of Android
+        return kg.getProvider().getName().startsWith("Sun")
+                || (StandardNames.IS_RI && kg.getProvider().getName().equals("BC"));
+    }
+
+    @BeforeClass
+    public static void setUp() {
+        TestUtils.assumeAllowsUnsignedCrypto();
+    }
+
+    @Test
+    public void test_getInstance() throws Exception {
+        ServiceTester
+                .test("KeyGenerator")
+                // Do not test AndroidKeyStore's KeyGenerator. It cannot be initialized without
+                // providing AndroidKeyStore-specific algorithm parameters.
+                // It's OKish not to test AndroidKeyStore's KeyGenerator here because it's tested
+                // by cts/tests/test/keystore.
+                .skipProvider("AndroidKeyStore")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider provider, String algorithm) throws Exception {
+                        // KeyGenerator.getInstance(String)
+                        KeyGenerator kg1 = KeyGenerator.getInstance(algorithm);
+                        assertEquals(algorithm, kg1.getAlgorithm());
+                        test_KeyGenerator(kg1);
+
+                        // KeyGenerator.getInstance(String, Provider)
+                        KeyGenerator kg2 = KeyGenerator.getInstance(algorithm, provider);
+                        assertEquals(algorithm, kg2.getAlgorithm());
+                        assertEquals(provider, kg2.getProvider());
+                        test_KeyGenerator(kg2);
+
+                        // KeyGenerator.getInstance(String, String)
+                        KeyGenerator kg3 = KeyGenerator.getInstance(algorithm, provider.getName());
+                        assertEquals(algorithm, kg3.getAlgorithm());
+                        assertEquals(provider, kg3.getProvider());
+                        test_KeyGenerator(kg3);
+                    }
+                });
+    }
+
+    private static final Map<String, List<Integer>> KEY_SIZES
+            = new HashMap<String, List<Integer>>();
+    private static void putKeySize(String algorithm, int keySize) {
+        algorithm = algorithm.toUpperCase();
+        List<Integer> keySizes = KEY_SIZES.get(algorithm);
+        if (keySizes == null) {
+            keySizes = new ArrayList<Integer>();
+            KEY_SIZES.put(algorithm, keySizes);
+        }
+        keySizes.add(keySize);
+    }
+    private static List<Integer> getKeySizes(String algorithm) throws Exception {
+        algorithm = algorithm.toUpperCase();
+        List<Integer> keySizes = KEY_SIZES.get(algorithm);
+        if (keySizes == null) {
+            throw new Exception("Unknown key sizes for KeyGenerator." + algorithm);
+        }
+        return keySizes;
+    }
+    static {
+        putKeySize("AES", 128);
+        putKeySize("AES", 192);
+        putKeySize("AES", 256);
+        putKeySize("ARC4", 1024);
+        putKeySize("ARC4", 40);
+        putKeySize("ARC4", 41);
+        putKeySize("ARCFOUR", 1024);
+        putKeySize("ARCFOUR", 40);
+        putKeySize("ARCFOUR", 41);
+        putKeySize("Blowfish", 32);
+        putKeySize("Blowfish", 32+8);
+        putKeySize("Blowfish", 448);
+        putKeySize("ChaCha20", 256);
+        putKeySize("DES", 56);
+        putKeySize("DESede", 112);
+        putKeySize("DESede", 168);
+        putKeySize("RC2", 40);
+        putKeySize("RC2", 41);
+        putKeySize("RC2", 1024);
+        putKeySize("RC4", 40);
+        putKeySize("RC4", 41);
+        putKeySize("RC4", 1024);
+        putKeySize("HmacMD5", 1);
+        putKeySize("HmacMD5", 1025);
+        putKeySize("HmacSHA1", 1);
+        putKeySize("HmacSHA1", 1025);
+        putKeySize("HmacSHA224", 40);
+        putKeySize("HmacSHA224", 1025);
+        putKeySize("HmacSHA256", 40);
+        putKeySize("HmacSHA256", 1025);
+        putKeySize("HmacSHA384", 40);
+        putKeySize("HmacSHA384", 1025);
+        putKeySize("HmacSHA512", 40);
+        putKeySize("HmacSHA512", 1025);
+    }
+
+    private void test_KeyGenerator(KeyGenerator kg) throws Exception {
+        if (isUnsupported(kg)) {
+            return;
+        }
+
+        kg.init((SecureRandom) null);
+        test_SecretKey(kg, kg.generateKey());
+
+        kg.init(new SecureRandom());
+        test_SecretKey(kg, kg.generateKey());
+
+        String algorithm = kg.getAlgorithm();
+        List<Integer> keySizes = getKeySizes(algorithm);
+        for (int keySize : keySizes) {
+            kg.init(keySize);
+            test_SecretKey(kg, kg.generateKey());
+
+            kg.init(keySize, (SecureRandom) null);
+            test_SecretKey(kg, kg.generateKey());
+
+            kg.init(keySize, new SecureRandom());
+            test_SecretKey(kg, kg.generateKey());
+        }
+    }
+
+    private void test_SecretKey(KeyGenerator kg, SecretKey sk) throws Exception {
+        assertNotNull(sk);
+        assertEquals(kg.getAlgorithm().toUpperCase(), sk.getAlgorithm().toUpperCase());
+        assertNotNull(sk.getEncoded());
+        assertNotNull(sk.getFormat());
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/HttpsURLConnectionTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/HttpsURLConnectionTest.java
new file mode 100644
index 0000000..78425dc
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/HttpsURLConnectionTest.java
@@ -0,0 +1,168 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class HttpsURLConnectionTest {
+    /**
+     * HTTPS URL which cannot be resolved and is thus safe to use in tests where network traffic
+     * should be avoided.
+     */
+    private static final String UNRESOLVABLE_HTTPS_URL = "https:///";
+
+    @Test
+    public void testDefaultHostnameVerifierNotNull() {
+        assertNotNull(HttpsURLConnection.getDefaultHostnameVerifier());
+    }
+
+    @Test
+    public void testDefaultHostnameVerifierUsedForNewConnectionsByDefault() throws IOException {
+        HostnameVerifier originalHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+        HttpsURLConnection connection =
+                (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+        try {
+            assertSame(originalHostnameVerifier, connection.getHostnameVerifier());
+        } finally {
+            connection.disconnect();
+        }
+
+        HostnameVerifier anotherVerifier = new FakeHostnameVerifier();
+        try {
+            HttpsURLConnection.setDefaultHostnameVerifier(anotherVerifier);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(anotherVerifier, connection.getHostnameVerifier());
+            } finally {
+                connection.disconnect();
+            }
+
+            HttpsURLConnection.setDefaultHostnameVerifier(originalHostnameVerifier);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(originalHostnameVerifier, connection.getHostnameVerifier());
+            } finally {
+                connection.disconnect();
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(originalHostnameVerifier);
+        }
+    }
+
+    @Test
+    public void testDefaultSSLSocketFactoryNotNull() {
+        assertNotNull(HttpsURLConnection.getDefaultSSLSocketFactory());
+    }
+
+    @Test
+    public void testDefaultSSLSocketFactoryUsedForNewConnectionsByDefault() throws IOException {
+        SSLSocketFactory originalFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
+        HttpsURLConnection connection =
+                (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+        try {
+            assertSame(originalFactory, connection.getSSLSocketFactory());
+        } finally {
+            connection.disconnect();
+        }
+
+        SSLSocketFactory anotherFactory = new FakeSSLSocketFactory();
+        try {
+            HttpsURLConnection.setDefaultSSLSocketFactory(anotherFactory);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(anotherFactory, connection.getSSLSocketFactory());
+            } finally {
+                connection.disconnect();
+            }
+
+            HttpsURLConnection.setDefaultSSLSocketFactory(originalFactory);
+            connection = (HttpsURLConnection) new URL(UNRESOLVABLE_HTTPS_URL).openConnection();
+            try {
+                assertSame(originalFactory, connection.getSSLSocketFactory());
+            } finally {
+                connection.disconnect();
+            }
+        } finally {
+            HttpsURLConnection.setDefaultSSLSocketFactory(originalFactory);
+        }
+    }
+
+    private static final class FakeHostnameVerifier implements HostnameVerifier {
+        @Override
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    }
+
+    private static final class FakeSSLSocketFactory extends SSLSocketFactory {
+        FakeSSLSocketFactory() {}
+
+        @Override
+        public String[] getDefaultCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(Socket s, String host, int port, boolean autoClose) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(
+                InetAddress address, int port, InetAddress localAddress, int localPort) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(InetAddress host, int port) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Socket createSocket(String host, int port) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/KeyManagerFactoryTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/KeyManagerFactoryTest.java
new file mode 100644
index 0000000..d2424c7
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/KeyManagerFactoryTest.java
@@ -0,0 +1,521 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.KeyManagerFactoryImpl;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStore.PasswordProtection;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.KeyStoreBuilderParameters;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyManagerFactoryTest {
+    private TestKeyStore testKeyStore;
+
+    @Before
+    public void setUp() throws Exception {
+        // note the rare usage of DSA keys here in addition to RSA
+        String[] keyAlgorithms = StandardNames.IS_RI
+                ? new String[] { "RSA", "DSA", "EC", "EC_RSA" }
+                : new String[] { "RSA", "DH_RSA", "DSA", "DH_DSA", "EC", "EC_RSA" };
+        testKeyStore = new TestKeyStore.Builder()
+                               .keyAlgorithms(keyAlgorithms)
+                               .aliasPrefix("rsa-dsa-ec-dh")
+                               .build();
+    }
+
+    private TestKeyStore getTestKeyStore() throws Exception {
+        return testKeyStore;
+    }
+
+    @Test
+    public void test_KeyManagerFactory_getDefaultAlgorithm() throws Exception {
+        String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+        assertEquals(StandardNames.KEY_MANAGER_FACTORY_DEFAULT, algorithm);
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
+        test_KeyManagerFactory(kmf);
+    }
+
+    private static class UselessManagerFactoryParameters implements ManagerFactoryParameters {}
+
+    private static boolean supportsManagerFactoryParameters(String algorithm) {
+        // Only the "New" one supports ManagerFactoryParameters
+        return algorithm.equals("NewSunX509");
+    }
+
+    private static String[] keyTypes(String algorithm) {
+        // Although the "New" one supports ManagerFactoryParameters,
+        // it can't handle nulls in the key types array.
+        return (algorithm.equals("NewSunX509") ? KEY_TYPES_WITH_EMPTY
+                                               : KEY_TYPES_WITH_EMPTY_AND_NULL);
+    }
+
+    private void test_KeyManagerFactory(KeyManagerFactory kmf) throws Exception {
+        assertNotNull(kmf);
+        assertNotNull(kmf.getAlgorithm());
+        assertNotNull(kmf.getProvider());
+
+        // before init
+        try {
+            kmf.getKeyManagers();
+            fail();
+        } catch (IllegalStateException expected) {
+            // Ignore
+        }
+
+        // init with null ManagerFactoryParameters
+        try {
+            kmf.init(null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignore
+        }
+
+        // init with useless ManagerFactoryParameters
+        try {
+            kmf.init(new UselessManagerFactoryParameters());
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignore
+        }
+
+        // init with KeyStoreBuilderParameters ManagerFactoryParameters
+        PasswordProtection pp = new PasswordProtection(getTestKeyStore().storePassword);
+        KeyStore.Builder builder = KeyStore.Builder.newInstance(getTestKeyStore().keyStore, pp);
+        KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(builder);
+        if (supportsManagerFactoryParameters(kmf.getAlgorithm())) {
+            kmf.init(ksbp);
+            test_KeyManagerFactory_getKeyManagers(kmf, false);
+        } else {
+            try {
+                kmf.init(ksbp);
+                fail();
+            } catch (InvalidAlgorithmParameterException expected) {
+                // Ignore
+            }
+        }
+
+        // init with null for default behavior
+        kmf.init(null, null);
+        test_KeyManagerFactory_getKeyManagers(kmf, true);
+
+        // init with specific key store and password
+        kmf.init(getTestKeyStore().keyStore, getTestKeyStore().storePassword);
+        test_KeyManagerFactory_getKeyManagers(kmf, false);
+    }
+
+    private void test_KeyManagerFactory_getKeyManagers(KeyManagerFactory kmf, boolean empty)
+            throws Exception {
+        KeyManager[] keyManagers = kmf.getKeyManagers();
+        assertNotNull(keyManagers);
+        assertTrue(keyManagers.length > 0);
+        for (KeyManager keyManager : keyManagers) {
+            assertNotNull(keyManager);
+            if (keyManager instanceof X509KeyManager) {
+                test_X509KeyManager((X509KeyManager) keyManager, empty, kmf.getAlgorithm());
+            }
+        }
+    }
+
+    private static final String[] KEY_TYPES_ONLY =
+            StandardNames.KEY_TYPES.toArray(new String[StandardNames.KEY_TYPES.size()]);
+    private static final String[] KEY_TYPES_WITH_EMPTY = new String[KEY_TYPES_ONLY.length + 1];
+    private static final String[] KEY_TYPES_WITH_EMPTY_AND_NULL =
+            new String[KEY_TYPES_ONLY.length + 2];
+    static {
+        System.arraycopy(KEY_TYPES_ONLY, 0, KEY_TYPES_WITH_EMPTY, 0, KEY_TYPES_ONLY.length);
+        KEY_TYPES_WITH_EMPTY[KEY_TYPES_WITH_EMPTY.length - 1] = "";
+
+        System.arraycopy(KEY_TYPES_WITH_EMPTY, 0, KEY_TYPES_WITH_EMPTY_AND_NULL, 0,
+                KEY_TYPES_WITH_EMPTY.length);
+        // extra null at end requires no initialization
+    }
+
+    private void test_X509KeyManager(X509KeyManager km, boolean empty, String algorithm)
+            throws Exception {
+        String[] keyTypes = keyTypes(algorithm);
+        for (String keyType : keyTypes) {
+            String[] aliases = km.getClientAliases(keyType, null);
+            if (empty || keyType == null || keyType.isEmpty()) {
+                assertNull(keyType, aliases);
+                continue;
+            }
+            assertNotNull(keyType, aliases);
+            for (String alias : aliases) {
+                test_X509KeyManager_alias(km, alias, keyType, false, empty);
+            }
+        }
+        for (String keyType : keyTypes) {
+            String[] aliases = km.getServerAliases(keyType, null);
+            if (empty || keyType == null || keyType.isEmpty()) {
+                assertNull(keyType, aliases);
+                continue;
+            }
+            assertNotNull(keyType, aliases);
+            for (String alias : aliases) {
+                test_X509KeyManager_alias(km, alias, keyType, false, empty);
+            }
+        }
+
+        String[][] rotatedTypes = rotate(nonEmpty(keyTypes));
+        for (String[] keyList : rotatedTypes) {
+            String alias = km.chooseClientAlias(keyList, null, null);
+            test_X509KeyManager_alias(km, alias, null, true, empty);
+        }
+
+        for (String keyType : keyTypes) {
+            String[] array = new String[] {keyType};
+            String alias = km.chooseClientAlias(array, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+        for (String keyType : keyTypes) {
+            String alias = km.chooseServerAlias(keyType, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+        if (km instanceof X509ExtendedKeyManager) {
+            test_X509ExtendedKeyManager((X509ExtendedKeyManager) km, empty, algorithm);
+        }
+    }
+
+    private void test_X509ExtendedKeyManager(
+            X509ExtendedKeyManager km, boolean empty, String algorithm) throws Exception {
+        String[] keyTypes = keyTypes(algorithm);
+        String[][] rotatedTypes = rotate(nonEmpty(keyTypes));
+        for (String[] keyList : rotatedTypes) {
+            String alias = km.chooseEngineClientAlias(keyList, null, null);
+            test_X509KeyManager_alias(km, alias, null, true, empty);
+        }
+
+        for (String keyType : keyTypes) {
+            String[] array = new String[] {keyType};
+            String alias = km.chooseEngineClientAlias(array, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+        for (String keyType : keyTypes) {
+            String alias = km.chooseEngineServerAlias(keyType, null, null);
+            test_X509KeyManager_alias(km, alias, keyType, false, empty);
+        }
+    }
+
+    // Filters null or empty values from a String array and returns a new array with the results.
+    private static String[] nonEmpty(String[] input) {
+        String[] nonEmpty = new String[input.length];
+        int size = 0;
+        for (String keyType : input) {
+            if (keyType != null && !keyType.isEmpty()) {
+                nonEmpty[size++] = keyType;
+            }
+        }
+        return Arrays.copyOfRange(nonEmpty, 0, size);
+    }
+
+    // Generates an array of arrays of all the rotational permutations of its input.
+    private static String[][] rotate(String[] input) {
+        int size = input.length;
+        String[][] result = new String[size][size];
+        for (int i = 0; i < size; i++) {
+            for (int j = 0; j < size; j++) {
+                result[i][j] = input[(i + j) % size];
+            }
+        }
+        return result;
+    }
+
+    private void test_X509KeyManager_alias(X509KeyManager km, String alias, String keyType,
+            boolean many, boolean empty) throws Exception {
+        if (empty || (!many && (keyType == null || keyType.isEmpty()))) {
+            assertNull(keyType, alias);
+            assertNull(keyType, km.getCertificateChain(alias));
+            assertNull(keyType, km.getPrivateKey(alias));
+            return;
+        }
+        assertNotNull(alias);
+        X509Certificate[] certificateChain = km.getCertificateChain(alias);
+        PrivateKey privateKey = km.getPrivateKey(alias);
+
+        String keyAlgName = privateKey.getAlgorithm();
+
+        X509Certificate certificate = certificateChain[0];
+        assertEquals(keyType, keyAlgName, certificate.getPublicKey().getAlgorithm());
+
+        String sigAlgName = certificate.getSigAlgName();
+
+        PrivateKeyEntry privateKeyEntry = getTestKeyStore().getPrivateKey(keyAlgName, sigAlgName);
+
+        assertEquals(keyType, Arrays.asList(privateKeyEntry.getCertificateChain()),
+                Arrays.<Certificate>asList(certificateChain));
+        assertEquals(keyType, privateKeyEntry.getPrivateKey(), privateKey);
+
+        if (keyType != null) {
+            assertEquals(TestKeyStore.keyAlgorithm(keyType), keyAlgName);
+
+            // Skip this when we're given only "DH" or "EC" instead of "DH_DSA",
+            // "EC_RSA", etc. since we don't know what the expected
+            // algorithm was.
+            if (!keyType.equals("DH") && !keyType.equals("EC")) {
+                assertTrue("SigAlg: " + sigAlgName + ", KeyType: " + keyType,
+                        sigAlgName.contains(TestKeyStore.signatureAlgorithm(keyType)));
+            }
+        }
+    }
+
+    @Test
+    public void test_KeyManagerFactory_getInstance() throws Exception {
+        ServiceTester.test("KeyManagerFactory").run(new ServiceTester.Test() {
+            @Override
+            public void test(Provider provider, String algorithm) throws Exception {
+                KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
+                assertEquals(algorithm, kmf.getAlgorithm());
+                test_KeyManagerFactory(kmf);
+
+                kmf = KeyManagerFactory.getInstance(algorithm, provider);
+                assertEquals(algorithm, kmf.getAlgorithm());
+                assertEquals(provider, kmf.getProvider());
+                test_KeyManagerFactory(kmf);
+
+                kmf = KeyManagerFactory.getInstance(algorithm, provider.getName());
+                assertEquals(algorithm, kmf.getAlgorithm());
+                assertEquals(provider, kmf.getProvider());
+                test_KeyManagerFactory(kmf);
+            }
+        });
+    }
+
+    // The Conscrypt provider on OpenJDK doesn't provide the KeyManagerFactory, but we want
+    // to test it on OpenJDK anyway
+    @Test
+    public void test_KeyManagerFactory_Conscrypt() throws Exception {
+        KeyManagerFactory kmf = new KeyManagerFactory(new KeyManagerFactoryImpl(),
+                TestUtils.getConscryptProvider(), KeyManagerFactory.getDefaultAlgorithm()) {};
+        test_KeyManagerFactory(kmf);
+
+        // Test that using a KeyStore that doesn't implement getEntry(), like Android Keystore
+        // doesn't, still produces a functional KeyManager.
+        kmf.init(new NoGetEntryKeyStore(getTestKeyStore().keyStore),
+                getTestKeyStore().storePassword);
+        test_KeyManagerFactory_getKeyManagers(kmf, false);
+    }
+
+    private static class NoGetEntryKeyStore extends KeyStore {
+        public NoGetEntryKeyStore(KeyStore keyStore) throws Exception {
+            super(new NoGetEntryKeyStoreSpi(keyStore), keyStore.getProvider(), keyStore.getType());
+            load(null, null);
+        }
+    }
+
+    // Android Keystore's KeyStore doesn't support getEntry(), so we replicate that here
+    // for testing by throwing UnsupportedOperationException and passing everything else through
+    // to a working implementation.
+    private static class NoGetEntryKeyStoreSpi extends KeyStoreSpi {
+        private final KeyStore keyStore;
+
+        public NoGetEntryKeyStoreSpi(KeyStore keyStore) {
+            this.keyStore = keyStore;
+        }
+
+        @Override
+        public KeyStore.Entry engineGetEntry(String alias, KeyStore.ProtectionParameter protParam) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Key engineGetKey(String s, char[] chars)
+                throws NoSuchAlgorithmException, UnrecoverableKeyException {
+            try {
+                return keyStore.getKey(s, chars);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public Certificate[] engineGetCertificateChain(String s) {
+            try {
+                return keyStore.getCertificateChain(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public Certificate engineGetCertificate(String s) {
+            try {
+                return keyStore.getCertificate(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public Date engineGetCreationDate(String s) {
+            try {
+                return keyStore.getCreationDate(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public void engineSetKeyEntry(String s, Key key, char[] chars, Certificate[] certificates)
+                throws KeyStoreException {
+            try {
+                keyStore.setKeyEntry(s, key, chars, certificates);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public void engineSetKeyEntry(String s, byte[] bytes, Certificate[] certificates)
+                throws KeyStoreException {
+            try {
+                keyStore.setKeyEntry(s, bytes, certificates);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public void engineSetCertificateEntry(String s, Certificate certificate)
+                throws KeyStoreException {
+            try {
+                keyStore.setCertificateEntry(s, certificate);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public void engineDeleteEntry(String s) throws KeyStoreException {
+            try {
+                keyStore.deleteEntry(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public Enumeration<String> engineAliases() {
+            try {
+                return keyStore.aliases();
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public boolean engineContainsAlias(String s) {
+            try {
+                return keyStore.containsAlias(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public int engineSize() {
+            try {
+                return keyStore.size();
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public boolean engineIsKeyEntry(String s) {
+            try {
+                return keyStore.isKeyEntry(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public boolean engineIsCertificateEntry(String s) {
+            try {
+                return keyStore.isCertificateEntry(s);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public String engineGetCertificateAlias(Certificate certificate) {
+            try {
+                return keyStore.getCertificateAlias(certificate);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public void engineStore(OutputStream outputStream, char[] chars)
+                throws IOException, NoSuchAlgorithmException, CertificateException {
+            try {
+                keyStore.store(outputStream, chars);
+            } catch (KeyStoreException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        public void engineLoad(InputStream inputStream, char[] chars)
+                throws IOException, NoSuchAlgorithmException, CertificateException {
+            // Do nothing, the keystore is already loaded
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/KeyStoreBuilderParametersTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/KeyStoreBuilderParametersTest.java
new file mode 100644
index 0000000..ff34e5b
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/KeyStoreBuilderParametersTest.java
@@ -0,0 +1,118 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.security.KeyStore;
+import java.security.KeyStore.PasswordProtection;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.KeyStoreBuilderParameters;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class KeyStoreBuilderParametersTest {
+
+    private static void assumeObjectsAvailable() {
+        boolean available = false;
+        try {
+            Class.forName("java.util.Objects");
+            available = true;
+        } catch (ClassNotFoundException ignore) {
+            // Ignored
+        }
+        Assume.assumeTrue("Skipping test: Objects unavailable", available);
+    }
+
+    @Test
+    public void test_init_Builder_null() {
+        // KeyStoreBuilderParameters' constructor didn't check for null until
+        // Objects.requireNonNull was added
+        assumeObjectsAvailable();
+        try {
+            new KeyStoreBuilderParameters((KeyStore.Builder) null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void test_init_Builder() {
+        TestKeyStore testKeyStore = TestKeyStore.getClient();
+        KeyStore.Builder builder = KeyStore.Builder.newInstance(
+                testKeyStore.keyStore, new PasswordProtection(testKeyStore.storePassword));
+        KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(builder);
+        assertNotNull(ksbp);
+        assertNotNull(ksbp.getParameters());
+        assertEquals(1, ksbp.getParameters().size());
+        assertSame(builder, ksbp.getParameters().get(0));
+    }
+
+    @Test
+    public void test_init_List_null() {
+        try {
+            new KeyStoreBuilderParameters((List<KeyStore.Builder>) null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_init_List() {
+        TestKeyStore testKeyStore1 = TestKeyStore.getClient();
+        TestKeyStore testKeyStore2 = TestKeyStore.getServer();
+        KeyStore.Builder builder1 = KeyStore.Builder.newInstance(
+                testKeyStore1.keyStore, new PasswordProtection(testKeyStore1.storePassword));
+        KeyStore.Builder builder2 = KeyStore.Builder.newInstance(
+                testKeyStore2.keyStore, new PasswordProtection(testKeyStore2.storePassword));
+
+        List<KeyStore.Builder> list = Arrays.asList(builder1, builder2);
+        KeyStoreBuilderParameters ksbp = new KeyStoreBuilderParameters(list);
+        assertNotNull(ksbp);
+        assertNotNull(ksbp.getParameters());
+        assertNotSame(list, ksbp.getParameters());
+        assertEquals(2, ksbp.getParameters().size());
+        assertSame(builder1, ksbp.getParameters().get(0));
+        assertSame(builder2, ksbp.getParameters().get(1));
+
+        // confirm result is not modifiable
+        try {
+            ksbp.getParameters().set(0, builder2);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+            // Ignored.
+        }
+
+        // confirm result is a copy of original
+        list.set(0, builder2);
+        assertSame(builder1, ksbp.getParameters().get(0));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SNIHostNameTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SNIHostNameTest.java
new file mode 100644
index 0000000..48e8eee
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SNIHostNameTest.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2016 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.StandardConstants;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SNIHostNameTest {
+    @Test
+    public void test_byteArray_Constructor() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+
+        // From draft-josefsson-idn-test-vectors-00 section 5.2
+        byte[] idnEncoded = new byte[] {
+            (byte) 0xE4, (byte) 0xBB, (byte) 0x96, (byte) 0xE4, (byte) 0xBB, (byte) 0xAC,
+            (byte) 0xE4, (byte) 0xB8, (byte) 0xBA, (byte) 0xE4, (byte) 0xBB, (byte) 0x80,
+            (byte) 0xE4, (byte) 0xB9, (byte) 0x88, (byte) 0xE4, (byte) 0xB8, (byte) 0x8D,
+            (byte) 0xE8, (byte) 0xAF, (byte) 0xB4, (byte) 0xE4, (byte) 0xB8, (byte) 0xAD,
+            (byte) 0xE6, (byte) 0x96, (byte) 0x87,
+        };
+
+        SNIHostName hostName = new SNIHostName(idnEncoded);
+        assertEquals("xn--ihqwcrb4cv8a8dqg056pqjye", hostName.getAsciiName());
+        assertEquals(StandardConstants.SNI_HOST_NAME, hostName.getType());
+        assertEquals(Arrays.toString(idnEncoded), Arrays.toString(hostName.getEncoded()));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
new file mode 100644
index 0000000..fd767b8
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
@@ -0,0 +1,745 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.KeyManagerFactorySpi;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.TrustManagerFactorySpi;
+import javax.net.ssl.X509KeyManager;
+import junit.framework.AssertionFailedError;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLContextTest {
+
+    @Test
+    public void test_SSLContext_getDefault() throws Exception {
+        SSLContext sslContext = SSLContext.getDefault();
+        assertNotNull(sslContext);
+        try {
+            sslContext.init(null, null, null);
+            fail();
+        } catch (KeyManagementException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLContext_setDefault() throws Exception {
+        try {
+            SSLContext.setDefault(null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+
+        SSLContext defaultContext = SSLContext.getDefault();
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            SSLContext oldContext = SSLContext.getDefault();
+            assertNotNull(oldContext);
+            SSLContext newContext = SSLContext.getInstance(protocol);
+            assertNotNull(newContext);
+            assertNotSame(oldContext, newContext);
+            SSLContext.setDefault(newContext);
+            assertSame(newContext, SSLContext.getDefault());
+        }
+        SSLContext.setDefault(defaultContext);
+    }
+
+    @Test
+    public void test_SSLContext_defaultConfiguration() throws Exception {
+        SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(SSLContext.getDefault());
+
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS_WITH_DEFAULT_CONFIG) {
+            SSLContext sslContext = SSLContext.getInstance(protocol);
+            if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                sslContext.init(null, null, null);
+            }
+            SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(sslContext);
+        }
+    }
+
+    @Test
+    public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
+        // Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
+        // provided.
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(new KeyManager[] { PSKKeyManagerProxy.getConscryptPSKKeyManager(
+                                new PSKKeyManagerProxy())},
+                new TrustManager[0], null);
+        List<String> expectedCipherSuites =
+                new ArrayList<String>(StandardNames.CIPHER_SUITES_TLS13);
+        expectedCipherSuites.addAll(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
+        expectedCipherSuites.add(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION);
+        assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+    }
+
+    @Test
+    public void test_SSLContext_x509AndPskConfiguration_defaultProviderOnly() throws Exception {
+        // Test the scenario where an X509TrustManager and PSKKeyManager are provided.
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(new KeyManager[] {PSKKeyManagerProxy.getConscryptPSKKeyManager(
+                                new PSKKeyManagerProxy())},
+                null, // Use default trust managers, one of which is an X.509 one.
+                null);
+        // The TLS 1.3 cipher suites appear before the PSK ones, so we need to dedup them
+        Set<String> expectedCipherSuiteSet = new LinkedHashSet<String>();
+        expectedCipherSuiteSet.addAll(StandardNames.CIPHER_SUITES_TLS13);
+        expectedCipherSuiteSet.addAll(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
+        expectedCipherSuiteSet.addAll(StandardNames.CIPHER_SUITES_DEFAULT);
+        List<String> expectedCipherSuites = new ArrayList<String>(expectedCipherSuiteSet);
+        assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+
+        // Test the scenario where an X509KeyManager and PSKKeyManager are provided.
+        sslContext = SSLContext.getInstance("TLS");
+        // Just an arbitrary X509KeyManager -- it won't be invoked in this test.
+        X509KeyManager x509KeyManager = new RandomPrivateKeyX509ExtendedKeyManager(null);
+        sslContext.init(
+                new KeyManager[] {x509KeyManager,
+                        PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())},
+                new TrustManager[0], null);
+        assertEnabledCipherSuites(expectedCipherSuites, sslContext);
+    }
+
+    @Test
+    public void test_SSLContext_emptyConfiguration_defaultProviderOnly() throws Exception {
+        // Test the scenario where neither X.509 nor PSK KeyManagers or TrustManagers are provided.
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(new KeyManager[0], new TrustManager[0], null);
+        // No TLS 1.2 cipher suites should be enabled, since neither PSK nor X.509 key exchange
+        // can be done.  The TLS 1.3 cipher suites should be there, since key exchange isn't
+        // part of the cipher suite in 1.3.
+        List<String> expected = new ArrayList<String>(StandardNames.CIPHER_SUITES_TLS13);
+        expected.add(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION);
+        assertEnabledCipherSuites(expected, sslContext);
+    }
+
+    @Test
+    public void test_SSLContext_init_correctProtocolVersionsEnabled() throws Exception {
+        for (String tlsVersion : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            // Don't test the "Default" instance.
+            if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(tlsVersion)) {
+                continue;
+            }
+
+            SSLContext context = SSLContext.getInstance(tlsVersion);
+            context.init(null, null, null);
+
+            StandardNames.assertSSLContextEnabledProtocols(tlsVersion,
+                    ((SSLSocket) context.getSocketFactory().createSocket()).getEnabledProtocols());
+            StandardNames.assertSSLContextEnabledProtocols(tlsVersion,
+                    ((SSLServerSocket) context.getServerSocketFactory().createServerSocket())
+                            .getEnabledProtocols());
+            StandardNames.assertSSLContextEnabledProtocols(
+                    tlsVersion, context.getDefaultSSLParameters().getProtocols());
+            StandardNames.assertSSLContextEnabledProtocols(
+                    tlsVersion, context.createSSLEngine().getEnabledProtocols());
+        }
+    }
+
+    private static void assertEnabledCipherSuites(
+            List<String> expectedCipherSuites, SSLContext sslContext) throws Exception {
+        TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable();
+        assertContentsInOrder(
+                expectedCipherSuites, sslContext.createSSLEngine().getEnabledCipherSuites());
+        assertContentsInOrder(expectedCipherSuites,
+                sslContext.createSSLEngine().getSSLParameters().getCipherSuites());
+        assertContentsInOrder(
+                expectedCipherSuites, sslContext.getSocketFactory().getDefaultCipherSuites());
+        assertContentsInOrder(
+                expectedCipherSuites, sslContext.getServerSocketFactory().getDefaultCipherSuites());
+
+        SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
+        try {
+            assertContentsInOrder(expectedCipherSuites, sslSocket.getEnabledCipherSuites());
+            assertContentsInOrder(
+                    expectedCipherSuites, sslSocket.getSSLParameters().getCipherSuites());
+        } finally {
+            try {
+                sslSocket.close();
+            } catch (IOException ignored) {
+            }
+        }
+
+        SSLServerSocket sslServerSocket =
+                (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket();
+        try {
+            assertContentsInOrder(expectedCipherSuites, sslServerSocket.getEnabledCipherSuites());
+        } finally {
+            try {
+                sslSocket.close();
+            } catch (IOException ignored) {
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getInstance() throws Exception {
+        try {
+            SSLContext.getInstance(null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            assertNotNull(SSLContext.getInstance(protocol));
+            assertNotSame(SSLContext.getInstance(protocol), SSLContext.getInstance(protocol));
+        }
+
+        try {
+            SSLContext.getInstance(null, (String) null);
+            fail();
+        } catch (Exception expected) {
+            if (javaVersion() >= 9) {
+                assertTrue("Expected NullPointerException on Java 9, was "
+                                + expected.getClass().getName(),
+                        expected instanceof NullPointerException);
+            } else {
+                assertTrue(
+                        "Expected IllegalArgumentException, was " + expected.getClass().getName(),
+                        expected instanceof IllegalArgumentException);
+            }
+        }
+        try {
+            SSLContext.getInstance(null, "");
+            fail();
+        } catch (Exception expected) {
+            if (javaVersion() >= 9) {
+                assertTrue("Expected NullPointerException on Java 9, was "
+                        + expected.getClass().getName(),
+                    expected instanceof NullPointerException);
+            } else {
+                assertTrue(
+                    "Expected IllegalArgumentException, was " + expected.getClass().getName(),
+                    expected instanceof IllegalArgumentException);
+            }
+        }
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            try {
+                SSLContext.getInstance(protocol, (String) null);
+                fail();
+            } catch (IllegalArgumentException expected) {
+                // Ignored.
+            }
+        }
+        try {
+            SSLContext.getInstance(null, StandardNames.JSSE_PROVIDER_NAME);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getProtocol() throws Exception {
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            String protocolName = SSLContext.getInstance(protocol).getProtocol();
+            assertNotNull(protocolName);
+            assertTrue(protocol.startsWith(protocolName));
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getProvider() throws Exception {
+        Provider provider = SSLContext.getDefault().getProvider();
+        assertNotNull(provider);
+        assertEquals(StandardNames.JSSE_PROVIDER_NAME, provider.getName());
+    }
+
+    @Test
+    public void test_SSLContext_init_Default() throws Exception {
+        // Assert that initializing a default SSLContext fails because it's supposed to be
+        // initialized already.
+        SSLContext sslContext = SSLContext.getInstance(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT);
+        try {
+            sslContext.init(null, null, null);
+            fail();
+        } catch (KeyManagementException expected) {
+            // Ignored.
+        }
+        try {
+            sslContext.init(new KeyManager[0], new TrustManager[0], null);
+            fail();
+        } catch (KeyManagementException expected) {
+            // Ignored.
+        }
+        try {
+            sslContext.init(new KeyManager[] {new KeyManager(){}},
+                    new TrustManager[] {new TrustManager(){}}, null);
+            fail();
+        } catch (KeyManagementException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLContext_init_withNullManagerArrays() throws Exception {
+        // Assert that SSLContext.init works fine even when provided with null arrays of
+        // KeyManagers and TrustManagers.
+        // The contract of SSLContext.init is that it will for default X.509 KeyManager and
+        // TrustManager from the highest priority KeyManagerFactory and TrustManagerFactory.
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                // Default SSLContext is provided in an already initialized state
+                continue;
+            }
+            SSLContext sslContext = SSLContext.getInstance(protocol);
+            sslContext.init(null, null, null);
+        }
+    }
+
+    @Test
+    public void test_SSLContext_init_withEmptyManagerArrays() throws Exception {
+        // Assert that SSLContext.init works fine even when provided with empty arrays of
+        // KeyManagers and TrustManagers.
+        // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
+        // TrustManager.
+        // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
+        // factories throw exceptions which will make this test fail if the factories are used.
+        Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
+        invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
+                        .getProvider()
+                        .getClass());
+                assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+                    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
+                        .getProvider()
+                        .getClass());
+
+                KeyManager[] keyManagers = new KeyManager[0];
+                TrustManager[] trustManagers = new TrustManager[0];
+                for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+                    if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                        // Default SSLContext is provided in an already initialized state
+                        continue;
+                    }
+                    SSLContext sslContext = SSLContext.getInstance(protocol);
+                    sslContext.init(keyManagers, trustManagers, null);
+                }
+
+                return null;
+            }
+        });
+    }
+
+    @Test
+    public void test_SSLContext_init_withoutX509() throws Exception {
+        // Assert that SSLContext.init works fine even when provided with KeyManagers and
+        // TrustManagers which don't include the X.509 ones.
+        // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
+        // TrustManager.
+        // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
+        // factories throw exceptions which will make this test fail if the factories are used.
+        Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
+        invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
+                        .getProvider()
+                        .getClass());
+                assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
+                    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
+                        .getProvider()
+                        .getClass());
+
+                KeyManager[] keyManagers = new KeyManager[]{new KeyManager() {
+                }};
+                TrustManager[] trustManagers = new TrustManager[]{new TrustManager() {
+                }};
+                for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+                    if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                        // Default SSLContext is provided in an already initialized state
+                        continue;
+                    }
+                    SSLContext sslContext = SSLContext.getInstance(protocol);
+                    sslContext.init(keyManagers, trustManagers, null);
+                }
+
+                return null;
+            }
+        });
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class ThrowExceptionKeyAndTrustManagerFactoryProvider extends Provider {
+        public ThrowExceptionKeyAndTrustManagerFactoryProvider() {
+            super("ThrowExceptionKeyAndTrustManagerProvider", 1.0,
+                    "SSLContextTest fake KeyManagerFactory  and TrustManagerFactory provider");
+
+            put("TrustManagerFactory." + TrustManagerFactory.getDefaultAlgorithm(),
+                    ThrowExceptionTrustManagagerFactorySpi.class.getName());
+            put("TrustManagerFactory.PKIX", ThrowExceptionTrustManagagerFactorySpi.class.getName());
+
+            put("KeyManagerFactory." + KeyManagerFactory.getDefaultAlgorithm(),
+                    ThrowExceptionKeyManagagerFactorySpi.class.getName());
+            put("KeyManagerFactory.PKIX", ThrowExceptionKeyManagagerFactorySpi.class.getName());
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class ThrowExceptionTrustManagagerFactorySpi extends TrustManagerFactorySpi {
+        @Override
+        protected void engineInit(KeyStore ks) throws KeyStoreException {
+            fail();
+        }
+
+        @Override
+        protected void engineInit(ManagerFactoryParameters spec)
+                throws InvalidAlgorithmParameterException {
+            fail();
+        }
+
+        @Override
+        protected TrustManager[] engineGetTrustManagers() {
+            throw new AssertionFailedError();
+        }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class ThrowExceptionKeyManagagerFactorySpi extends KeyManagerFactorySpi {
+        @Override
+        protected void engineInit(KeyStore ks, char[] password)
+                throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
+            fail();
+        }
+
+        @Override
+        protected void engineInit(ManagerFactoryParameters spec)
+                throws InvalidAlgorithmParameterException {
+            fail();
+        }
+
+        @Override
+        protected KeyManager[] engineGetKeyManagers() {
+            throw new AssertionFailedError();
+        }
+    }
+
+    /**
+     * Installs the specified security provider as the highest provider, invokes the provided
+     * {@link Callable}, and removes the provider.
+     *
+     * @return result returned by the {@code callable}.
+     */
+    private static <T> T invokeWithHighestPrioritySecurityProvider(
+            Provider provider, Callable<T> callable) throws Exception {
+        int providerPosition = -1;
+        try {
+            providerPosition = Security.insertProviderAt(provider, 1);
+            assertEquals(1, providerPosition);
+            return callable.call();
+        } finally {
+            if (providerPosition != -1) {
+                Security.removeProvider(provider.getName());
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getSocketFactory() throws Exception {
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                SSLContext.getInstance(protocol).getSocketFactory();
+            } else {
+                try {
+                    SSLContext.getInstance(protocol).getSocketFactory();
+                    fail();
+                } catch (IllegalStateException expected) {
+                    // Ignored.
+                }
+            }
+
+            SSLContext sslContext = SSLContext.getInstance(protocol);
+            if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                sslContext.init(null, null, null);
+            }
+            SocketFactory sf = sslContext.getSocketFactory();
+            assertNotNull(sf);
+            assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getServerSocketFactory() throws Exception {
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                SSLContext.getInstance(protocol).getServerSocketFactory();
+            } else {
+                try {
+                    SSLContext.getInstance(protocol).getServerSocketFactory();
+                    fail();
+                } catch (IllegalStateException expected) {
+                    // Ignored.
+                }
+            }
+
+            SSLContext sslContext = SSLContext.getInstance(protocol);
+            if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                sslContext.init(null, null, null);
+            }
+            ServerSocketFactory ssf = sslContext.getServerSocketFactory();
+            assertNotNull(ssf);
+            assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
+        }
+    }
+
+    @Test
+    public void test_SSLContext_createSSLEngine() throws Exception {
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                SSLContext.getInstance(protocol).createSSLEngine();
+            } else {
+                try {
+                    SSLContext.getInstance(protocol).createSSLEngine();
+                    fail();
+                } catch (IllegalStateException expected) {
+                    // Ignored.
+                }
+            }
+
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                SSLContext.getInstance(protocol).createSSLEngine(null, -1);
+            } else {
+                try {
+                    SSLContext.getInstance(protocol).createSSLEngine(null, -1);
+                    fail();
+                } catch (IllegalStateException expected) {
+                    // Ignored.
+                }
+            }
+
+            {
+                SSLContext sslContext = SSLContext.getInstance(protocol);
+                if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                    sslContext.init(null, null, null);
+                }
+                SSLEngine se = sslContext.createSSLEngine();
+                assertNotNull(se);
+            }
+
+            {
+                SSLContext sslContext = SSLContext.getInstance(protocol);
+                if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                    sslContext.init(null, null, null);
+                }
+                SSLEngine se = sslContext.createSSLEngine(null, -1);
+                assertNotNull(se);
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getServerSessionContext() throws Exception {
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            SSLContext sslContext = SSLContext.getInstance(protocol);
+            SSLSessionContext sessionContext = sslContext.getServerSessionContext();
+            assertNotNull(sessionContext);
+
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                assertSame(
+                        SSLContext.getInstance(protocol).getServerSessionContext(), sessionContext);
+            } else {
+                assertNotSame(
+                        SSLContext.getInstance(protocol).getServerSessionContext(), sessionContext);
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLContext_getClientSessionContext() throws Exception {
+        for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            SSLContext sslContext = SSLContext.getInstance(protocol);
+            SSLSessionContext sessionContext = sslContext.getClientSessionContext();
+            assertNotNull(sessionContext);
+
+            if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+                assertSame(
+                        SSLContext.getInstance(protocol).getClientSessionContext(), sessionContext);
+            } else {
+                assertNotSame(
+                        SSLContext.getInstance(protocol).getClientSessionContext(), sessionContext);
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLContextTest_TestSSLContext_create() {
+        TestSSLContext testContext = TestSSLContext.create();
+        assertNotNull(testContext);
+        assertNotNull(testContext.clientKeyStore);
+        assertNull(testContext.clientStorePassword);
+        assertNotNull(testContext.serverKeyStore);
+        assertNotNull(testContext.clientKeyManagers);
+        assertNotNull(testContext.serverKeyManagers);
+        if (testContext.clientKeyManagers.length == 0) {
+            fail("No client KeyManagers");
+        }
+        if (testContext.serverKeyManagers.length == 0) {
+            fail("No server KeyManagers");
+        }
+        assertNotNull(testContext.clientKeyManagers[0]);
+        assertNotNull(testContext.serverKeyManagers[0]);
+        assertNotNull(testContext.clientTrustManager);
+        assertNotNull(testContext.serverTrustManager);
+        assertNotNull(testContext.clientContext);
+        assertNotNull(testContext.serverContext);
+        assertNotNull(testContext.serverSocket);
+        assertNotNull(testContext.host);
+        assertTrue(testContext.port != 0);
+        testContext.close();
+    }
+
+    @Test(expected = NoSuchAlgorithmException.class)
+    public void test_SSLContext_SSLv3Unsupported() throws Exception {
+        // Find the default provider for TLS and verify that it does NOT support SSLv3.
+        Provider defaultTlsProvider = null;
+        for (String protocol : new String[] {"SSLContext.TLSv1.2", "SSLContext.TLSv1"}) {
+            for (Provider p : Security.getProviders()) {
+                if (p.get(protocol) != null) {
+                    defaultTlsProvider = p;
+                    break;
+                }
+            }
+        }
+        assertNotNull(defaultTlsProvider);
+        SSLContext.getInstance("SSLv3", defaultTlsProvider);
+    }
+
+    private static void assertContentsInOrder(List<String> expected, String... actual) {
+        if (expected.size() != actual.length) {
+            fail("Unexpected length. Expected len <" + expected.size() + ">, actual len <"
+                    + actual.length + ">, expected <" + expected + ">, actual <"
+                    + Arrays.asList(actual) + ">");
+        }
+        if (!expected.equals(Arrays.asList(actual))) {
+            fail("Unexpected element(s). Expected <" + expected + ">, actual <"
+                    + Arrays.asList(actual) + ">");
+        }
+    }
+
+    private static boolean isAndroid() {
+        boolean android;
+        try {
+            Class.forName("android.app.Application", false, getSystemClassLoader());
+            android = true;
+        } catch (Throwable ignored) {
+            // Failed to load the class uniquely available in Android.
+            android = false;
+        }
+        return android;
+    }
+
+    private static int javaVersion() {
+        final int majorVersion;
+
+        if (isAndroid()) {
+            majorVersion = 6;
+        } else {
+            majorVersion = majorVersionFromJavaSpecificationVersion();
+        }
+
+        return majorVersion;
+    }
+
+    private static int majorVersionFromJavaSpecificationVersion() {
+        return majorVersion(System.getProperty("java.specification.version", "1.6"));
+    }
+
+    private static int majorVersion(final String javaSpecVersion) {
+        final String[] components = javaSpecVersion.split("\\.", -1);
+        final int[] version = new int[components.length];
+        for (int i = 0; i < components.length; i++) {
+            version[i] = Integer.parseInt(components[i]);
+        }
+
+        if (version[0] == 1) {
+            assert version[1] >= 6;
+            return version[1];
+        } else {
+            return version[0];
+        }
+    }
+
+    private static ClassLoader getSystemClassLoader() {
+        if (System.getSecurityManager() == null) {
+            return ClassLoader.getSystemClassLoader();
+        } else {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                @Override
+                public ClassLoader run() {
+                    return ClassLoader.getSystemClassLoader();
+                }
+            });
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLEngineTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLEngineTest.java
new file mode 100644
index 0000000..fc773ca
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLEngineTest.java
@@ -0,0 +1,949 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static com.android.org.conscrypt.TestUtils.UTF_8;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import java.io.IOException;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509ExtendedTrustManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLEngineTest {
+    @Test
+    public void test_SSLEngine_defaultConfiguration() throws Exception {
+        SSLConfigurationAsserts.assertSSLEngineDefaultConfiguration(
+                TestSSLContext.create().clientContext.createSSLEngine());
+    }
+
+    @Test
+    public void test_SSLEngine_getSupportedCipherSuites_returnsCopies() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        assertNotSame(e.getSupportedCipherSuites(), e.getSupportedCipherSuites());
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_getSupportedCipherSuites_connect() throws Exception {
+        // note the rare usage of non-RSA keys
+        TestKeyStore testKeyStore = new TestKeyStore.Builder()
+                                            .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
+                                            .aliasPrefix("rsa-dsa-ec")
+                                            .ca(true)
+                                            .build();
+        test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, false);
+        test_SSLEngine_getSupportedCipherSuites_connect(testKeyStore, true);
+    }
+
+    // http://b/18554122
+    @Test
+    public void test_SSLEngine_underflowsOnEmptyBuffersDuringHandshake() throws Exception {
+        final SSLEngine sslEngine = SSLContext.getDefault().createSSLEngine();
+        sslEngine.setUseClientMode(false);
+        ByteBuffer input = ByteBuffer.allocate(1024);
+        input.flip();
+        ByteBuffer output = ByteBuffer.allocate(1024);
+        sslEngine.beginHandshake();
+        assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, sslEngine.getHandshakeStatus());
+        SSLEngineResult result = sslEngine.unwrap(input, output);
+        assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW, result.getStatus());
+        assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
+    }
+
+    // http://b/18554122
+    @Test
+    public void test_SSLEngine_underflowsOnEmptyBuffersAfterHandshake() throws Exception {
+        // Note that create performs the handshake.
+        final TestSSLEnginePair engines = TestSSLEnginePair.create();
+        ByteBuffer input = ByteBuffer.allocate(1024);
+        input.flip();
+        ByteBuffer output = ByteBuffer.allocate(1024);
+        assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW,
+                engines.client.unwrap(input, output).getStatus());
+    }
+
+    @Test
+    public void test_SSLEngine_wrap_overflowOnEmptyOutputBuffer() throws Exception {
+        TestSSLEnginePair pair = TestSSLEnginePair.create();
+        ByteBuffer input = ByteBuffer.allocate(10);
+        ByteBuffer output = ByteBuffer.allocate(1024);
+        output.flip();
+        assertEquals(Status.BUFFER_OVERFLOW, pair.client.wrap(input, output).getStatus());
+    }
+
+    @Test
+    public void test_SSLEngine_unwrap_overflowOnEmptyOutputBuffer() throws Exception {
+        TestSSLEnginePair pair = TestSSLEnginePair.create();
+        ByteBuffer input = ByteBuffer.allocate(10);
+        ByteBuffer wrapped = ByteBuffer.allocate(1024);
+        assertEquals(Status.OK, pair.client.wrap(input, wrapped).getStatus());
+        wrapped.flip();
+        ByteBuffer output = ByteBuffer.allocate(1024);
+        output.flip();
+        assertEquals(Status.BUFFER_OVERFLOW, pair.server.unwrap(wrapped, output).getStatus());
+    }
+
+    private void test_SSLEngine_getSupportedCipherSuites_connect(
+            TestKeyStore testKeyStore, boolean secureRenegotiation) throws Exception {
+        KeyManager pskKeyManager =
+                PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy() {
+                    @Override
+                    protected SecretKey getKey(
+                            String identityHint, String identity, SSLEngine engine) {
+                        return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
+                    }
+                });
+        TestSSLContext c = TestSSLContext.newBuilder()
+                                   .client(testKeyStore)
+                                   .server(testKeyStore)
+                                   .clientProtocol("TLSv1.2")
+                                   .serverProtocol("TLSv1.2")
+                                   .additionalClientKeyManagers(new KeyManager[] {pskKeyManager})
+                                   .additionalServerKeyManagers(new KeyManager[] {pskKeyManager})
+                                   .build();
+
+        // Create a TestSSLContext where the KeyManager returns wrong (randomly generated) private
+        // keys, matching the algorithm and parameters of the correct keys.
+        // I couldn't find a more elegant way to achieve this other than temporarily replacing the
+        // first X509ExtendedKeyManager element of TestKeyStore.keyManagers while invoking
+        // TestSSLContext.create.
+        TestSSLContext cWithWrongPrivateKeys;
+        {
+            // Create a RandomPrivateKeyX509ExtendedKeyManager based on the first
+            // X509ExtendedKeyManager in c.serverKeyManagers.
+            KeyManager randomPrivateKeyX509ExtendedKeyManager = null;
+            for (KeyManager keyManager : c.serverKeyManagers) {
+                if (keyManager instanceof X509ExtendedKeyManager) {
+                    randomPrivateKeyX509ExtendedKeyManager =
+                            new RandomPrivateKeyX509ExtendedKeyManager(
+                                    (X509ExtendedKeyManager) keyManager);
+                    break;
+                }
+            }
+            if (randomPrivateKeyX509ExtendedKeyManager == null) {
+                fail("No X509ExtendedKeyManager in c.serverKeyManagers");
+            }
+
+            // Find the first X509ExtendedKeyManager in testKeyStore.keyManagers
+            int replaceIndex = -1;
+            for (int i = 0; i < testKeyStore.keyManagers.length; i++) {
+                KeyManager keyManager = testKeyStore.keyManagers[i];
+                if (keyManager instanceof X509ExtendedKeyManager) {
+                    replaceIndex = i;
+                    break;
+                }
+            }
+            if (replaceIndex == -1) {
+                fail("No X509ExtendedKeyManager in testKeyStore.keyManagers");
+            }
+
+            // Temporarily substitute the RandomPrivateKeyX509ExtendedKeyManager in place of the
+            // original X509ExtendedKeyManager.
+            KeyManager originalKeyManager = testKeyStore.keyManagers[replaceIndex];
+            testKeyStore.keyManagers[replaceIndex] = randomPrivateKeyX509ExtendedKeyManager;
+            cWithWrongPrivateKeys = TestSSLContext.create(testKeyStore, testKeyStore);
+            testKeyStore.keyManagers[replaceIndex] = originalKeyManager;
+        }
+
+        // To catch all the errors.
+        StringBuilder error = new StringBuilder();
+
+        String[] cipherSuites = c.clientContext.createSSLEngine().getSupportedCipherSuites();
+        for (String cipherSuite : cipherSuites) {
+            try {
+                // Skip cipher suites that are obsoleted.
+                if (StandardNames.IS_RI && "TLSv1.2".equals(c.clientContext.getProtocol())
+                        && StandardNames.CIPHER_SUITES_OBSOLETE_TLS12.contains(cipherSuite)) {
+                    continue;
+                }
+                /*
+                 * Signaling Cipher Suite Values (SCSV) cannot be used on their own, but instead in
+                 * conjunction with other cipher suites.
+                 */
+                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
+                        || cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
+                    continue;
+                }
+                /*
+                 * This test uses TLS 1.2, and the TLS 1.3 cipher suites aren't customizable
+                 * anyway.
+                 */
+                if (StandardNames.CIPHER_SUITES_TLS13.contains(cipherSuite)) {
+                    continue;
+                }
+
+                final String[] cipherSuiteArray = (secureRenegotiation
+                                ? new String[] {cipherSuite,
+                                          StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION}
+                                : new String[] {cipherSuite});
+
+                // Check that handshake succeeds.
+                TestSSLEnginePair pair = null;
+                try {
+                    pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+                        @Override
+                        void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                            client.setEnabledCipherSuites(cipherSuiteArray);
+                            server.setEnabledCipherSuites(cipherSuiteArray);
+                        }
+                    });
+                    assertConnected(pair);
+
+                    boolean needsRecordSplit = "TLS".equalsIgnoreCase(c.clientContext.getProtocol())
+                            && cipherSuite.contains("_CBC_");
+
+                    assertSendsCorrectly("This is the client. Hello!".getBytes(UTF_8), pair.client,
+                            pair.server, needsRecordSplit);
+                    assertSendsCorrectly("This is the server. Hi!".getBytes(UTF_8), pair.server,
+                            pair.client, needsRecordSplit);
+                } finally {
+                    if (pair != null) {
+                        pair.close();
+                    }
+                }
+
+                // Check that handshake fails when the server does not possess the private key
+                // corresponding to the server's certificate. This is achieved by using SSLContext
+                // cWithWrongPrivateKeys whose KeyManager returns wrong private keys that match
+                // the algorithm (and parameters) of the correct keys.
+                boolean serverAuthenticatedUsingPublicKey = true;
+                if (cipherSuite.contains("_anon_")) {
+                    serverAuthenticatedUsingPublicKey = false;
+                } else if (cipherSuite.startsWith("TLS_PSK_")
+                        || cipherSuite.startsWith("TLS_ECDHE_PSK_")) {
+                    serverAuthenticatedUsingPublicKey = false;
+                }
+                if (serverAuthenticatedUsingPublicKey) {
+                    TestSSLEnginePair p = null;
+                    try {
+                        p = TestSSLEnginePair.create(
+                                cWithWrongPrivateKeys, new TestSSLEnginePair.Hooks() {
+                                    @Override
+                                    void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                                        client.setEnabledCipherSuites(cipherSuiteArray);
+                                        server.setEnabledCipherSuites(cipherSuiteArray);
+                                    }
+                                });
+                        assertNotConnected(p);
+                    } catch (IOException expected) {
+                        // Ignored.
+                    } finally {
+                        if (p != null) {
+                            p.close();
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                String message = ("Problem trying to connect cipher suite " + cipherSuite);
+                System.out.println(message);
+                e.printStackTrace();
+                error.append(message);
+                error.append('\n');
+            }
+        }
+        c.close();
+
+        if (error.length() > 0) {
+            throw new Exception("One or more problems in "
+                    + "test_SSLEngine_getSupportedCipherSuites_connect:\n" + error);
+        }
+    }
+
+    private static void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source,
+            SSLEngine dest, boolean needsRecordSplit) throws SSLException {
+        ByteBuffer sourceOut = ByteBuffer.wrap(sourceBytes);
+        SSLSession sourceSession = source.getSession();
+        ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
+        SSLEngineResult sourceOutRes = source.wrap(sourceOut, sourceToDest);
+        sourceToDest.flip();
+
+        String sourceCipherSuite = source.getSession().getCipherSuite();
+        assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
+        assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                sourceOutRes.getHandshakeStatus());
+
+        SSLSession destSession = dest.getSession();
+        ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
+
+        int numUnwrapCalls = 0;
+        while (destIn.position() != sourceOut.limit()) {
+            SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
+            assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                    destRes.getHandshakeStatus());
+            if (needsRecordSplit && numUnwrapCalls == 0) {
+                assertEquals(sourceCipherSuite, 1, destRes.bytesProduced());
+            }
+            numUnwrapCalls++;
+        }
+
+        destIn.flip();
+        byte[] actual = new byte[destIn.remaining()];
+        destIn.get(actual);
+        assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
+
+        if (needsRecordSplit) {
+            assertEquals(sourceCipherSuite, 2, numUnwrapCalls);
+        } else {
+            assertEquals(sourceCipherSuite, 1, numUnwrapCalls);
+            assertSendsCorrectlyWhenSplit(sourceBytes, source, dest);
+        }
+    }
+
+    private static void assertSendsCorrectlyWhenSplit(final byte[] sourceBytes, SSLEngine source,
+            SSLEngine dest) throws SSLException {
+        // Split the input into three to test the version that accepts ByteBuffer[].  Three
+        // is chosen somewhat arbitrarily as a number larger than the minimum of 2 but small
+        // enough that it's not unwieldy.
+        ByteBuffer[] sourceBufs = new ByteBuffer[3];
+        int sourceLen = sourceBytes.length;
+        sourceBufs[0] = ByteBuffer.wrap(sourceBytes, 0, sourceLen / 3);
+        sourceBufs[1] = ByteBuffer.wrap(sourceBytes, sourceLen / 3, sourceLen / 3);
+        sourceBufs[2] = ByteBuffer.wrap(
+            sourceBytes, 2 * (sourceLen / 3), sourceLen - 2 * (sourceLen / 3));
+        SSLSession sourceSession = source.getSession();
+        ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
+        SSLEngineResult sourceOutRes = source.wrap(sourceBufs, sourceToDest);
+        sourceToDest.flip();
+        String sourceCipherSuite = source.getSession().getCipherSuite();
+        assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
+        assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                sourceOutRes.getHandshakeStatus());
+        SSLSession destSession = dest.getSession();
+        ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
+        int numUnwrapCalls = 0;
+        while (destIn.position() != sourceBytes.length) {
+            SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
+            assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                    destRes.getHandshakeStatus());
+            numUnwrapCalls++;
+        }
+        destIn.flip();
+        byte[] actual = new byte[destIn.remaining()];
+        destIn.get(actual);
+        assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
+        assertEquals(sourceCipherSuite, 3, numUnwrapCalls);
+    }
+
+    @Test
+    public void test_SSLEngine_getEnabledCipherSuites_returnsCopies() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        assertNotSame(e.getEnabledCipherSuites(), e.getEnabledCipherSuites());
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_setEnabledCipherSuites_storesCopy() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        String[] array = new String[] {e.getEnabledCipherSuites()[0]};
+        String originalFirstElement = array[0];
+        e.setEnabledCipherSuites(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, e.getEnabledCipherSuites()[0]);
+    }
+
+    @Test
+    public void test_SSLEngine_setEnabledCipherSuites_TLS12() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLSv1.2");
+        context.init(null, null, null);
+        SSLEngine e = context.createSSLEngine();
+
+        try {
+            e.setEnabledCipherSuites(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            e.setEnabledCipherSuites(new String[1]);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            e.setEnabledCipherSuites(new String[] {"Bogus"});
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+
+        e.setEnabledCipherSuites(new String[0]);
+        e.setEnabledCipherSuites(e.getEnabledCipherSuites());
+        e.setEnabledCipherSuites(e.getSupportedCipherSuites());
+
+        // Check that setEnabledCipherSuites affects getEnabledCipherSuites
+        String[] cipherSuites = new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(e.getSupportedCipherSuites())
+        };
+        e.setEnabledCipherSuites(cipherSuites);
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
+    }
+
+    @Test
+    public void test_SSLEngine_setEnabledCipherSuites_TLS13() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLSv1.3");
+        context.init(null, null, null);
+        SSLEngine e = context.createSSLEngine();
+        // The TLS 1.3 cipher suites should be enabled by default
+        assertTrue(new HashSet<String>(Arrays.asList(e.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+        // Disabling them should be ignored
+        e.setEnabledCipherSuites(new String[0]);
+        assertTrue(new HashSet<String>(Arrays.asList(e.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+
+        e.setEnabledCipherSuites(new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(e.getSupportedCipherSuites())
+        });
+        assertTrue(new HashSet<String>(Arrays.asList(e.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+
+        // Disabling TLS 1.3 should disable the 1.3 cipher suites
+        e.setEnabledProtocols(new String[] { "TLSv1.2" });
+        assertFalse(new HashSet<String>(Arrays.asList(e.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+    }
+
+    @Test
+    public void test_SSLEngine_getSupportedProtocols_returnsCopies() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        assertNotSame(e.getSupportedProtocols(), e.getSupportedProtocols());
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_getEnabledProtocols_returnsCopies() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        assertNotSame(e.getEnabledProtocols(), e.getEnabledProtocols());
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_setEnabledProtocols_storesCopy() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        String[] array = new String[] {e.getEnabledProtocols()[0]};
+        String originalFirstElement = array[0];
+        e.setEnabledProtocols(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, e.getEnabledProtocols()[0]);
+    }
+
+    @Test
+    public void test_SSLEngine_setEnabledProtocols() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+
+        try {
+            e.setEnabledProtocols(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            e.setEnabledProtocols(new String[1]);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            e.setEnabledProtocols(new String[] {"Bogus"});
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        e.setEnabledProtocols(new String[0]);
+        e.setEnabledProtocols(e.getEnabledProtocols());
+        e.setEnabledProtocols(e.getSupportedProtocols());
+
+        // Check that setEnabledProtocols affects getEnabledProtocols
+        for (String protocol : e.getSupportedProtocols()) {
+            if ("SSLv2Hello".equals(protocol)) {
+                try {
+                    e.setEnabledProtocols(new String[] {protocol});
+                    fail("Should fail when SSLv2Hello is set by itself");
+                } catch (IllegalArgumentException expected) {
+                    // Ignored.
+                }
+            } else {
+                String[] protocols = new String[] {protocol};
+                e.setEnabledProtocols(protocols);
+                assertEquals(Arrays.deepToString(protocols),
+                        Arrays.deepToString(e.getEnabledProtocols()));
+            }
+        }
+
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_getSession() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        SSLSession session = e.getSession();
+        assertNotNull(session);
+        assertFalse(session.isValid());
+        c.close();
+    }
+
+    // http://b/37078438
+    @Test
+    public void test_SSLEngine_beginHandshake_redundantCalls() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine client = c.clientContext.createSSLEngine(c.host.getHostName(), c.port);
+        client.setUseClientMode(true);
+        client.beginHandshake();
+        client.beginHandshake(); // This call should be ignored
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_getHandshakeSession_duringHandshake_client() throws Exception {
+        // We can't reference the actual context we're using, since we need to pass
+        // the test trust manager in to construct it, so create reference objects that
+        // we can test against.
+        final TestSSLContext referenceContext = TestSSLContext.create();
+        final SSLEngine referenceEngine = referenceContext.clientContext.createSSLEngine();
+
+        final boolean[] wasCalled = new boolean[1];
+        TestSSLContext c =
+                TestSSLContext.newBuilder()
+                        .clientTrustManager(new X509ExtendedTrustManager() {
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                try {
+                                    SSLSession session = sslEngine.getHandshakeSession();
+                                    assertNotNull(session);
+                                    // By the point of the handshake where we're validating
+                                    // certificates, the hostname is known and the cipher suite
+                                    // should be agreed
+                                    assertEquals(referenceContext.host.getHostName(),
+                                            session.getPeerHost());
+                                    String sessionSuite = session.getCipherSuite();
+                                    List<String> enabledSuites =
+                                            Arrays.asList(referenceEngine.getEnabledCipherSuites());
+                                    String message = "Handshake session has invalid cipher suite: "
+                                            + (sessionSuite == null ? "(null)" : sessionSuite);
+                                    assertTrue("Expected enabled suites to contain " + sessionSuite
+                                                    + ", got: " + enabledSuites,
+                                            enabledSuites.contains(sessionSuite));
+                                    wasCalled[0] = true;
+                                } catch (Exception e) {
+                                    throw new CertificateException("Something broke", e);
+                                }
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public X509Certificate[] getAcceptedIssuers() {
+                                return new X509Certificate[0];
+                            }
+                        })
+                        .build();
+        TestSSLEnginePair pair = TestSSLEnginePair.create(c);
+        pair.close();
+        assertTrue(wasCalled[0]);
+    }
+
+    @Test
+    public void test_SSLEngine_getHandshakeSession_duringHandshake_server() throws Exception {
+        // We can't reference the actual context we're using, since we need to pass
+        // the test trust manager in to construct it, so create reference objects that
+        // we can test against.
+        final TestSSLContext referenceContext = TestSSLContext.create();
+        final SSLEngine referenceEngine = referenceContext.clientContext.createSSLEngine();
+
+        final boolean[] wasCalled = new boolean[1];
+        TestSSLContext c =
+                TestSSLContext.newBuilder()
+                        .client(TestKeyStore.getClientCertificate())
+                        .serverTrustManager(new X509ExtendedTrustManager() {
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                try {
+                                    SSLSession session = sslEngine.getHandshakeSession();
+                                    assertNotNull(session);
+                                    // By the point of the handshake where we're validating client
+                                    // certificates, the cipher suite should be agreed and the
+                                    // server's own certificates should have been delivered
+                                    assertEquals(referenceEngine.getEnabledCipherSuites()[0],
+                                            session.getCipherSuite());
+                                    assertNotNull(session.getLocalCertificates());
+                                    assertEquals("CN=localhost",
+                                            ((X509Certificate) session.getLocalCertificates()[0])
+                                                    .getSubjectDN()
+                                                    .getName());
+                                    assertEquals("CN=Test Intermediate Certificate Authority",
+                                            ((X509Certificate) session.getLocalCertificates()[0])
+                                                    .getIssuerDN()
+                                                    .getName());
+                                    wasCalled[0] = true;
+                                } catch (Exception e) {
+                                    throw new CertificateException("Something broke", e);
+                                }
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public X509Certificate[] getAcceptedIssuers() {
+                                return referenceContext.serverTrustManager.getAcceptedIssuers();
+                            }
+                        })
+                        .build();
+        TestSSLEnginePair pair = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+            @Override
+            void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                server.setNeedClientAuth(true);
+            }
+        });
+        pair.close();
+        assertTrue(wasCalled[0]);
+    }
+
+    @Test
+    public void test_SSLEngine_getUseClientMode() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        assertFalse(c.clientContext.createSSLEngine().getUseClientMode());
+        assertFalse(c.clientContext.createSSLEngine(null, -1).getUseClientMode());
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_setUseClientMode() throws Exception {
+        boolean[] finished;
+        TestSSLEnginePair p;
+
+        // client is client, server is server
+        finished = new boolean[2];
+        p = test_SSLEngine_setUseClientMode(true, false, finished);
+        assertConnected(p);
+        assertTrue(finished[0]);
+        assertTrue(finished[1]);
+        p.close();
+
+        // client is server, server is client
+        finished = new boolean[2];
+        p = test_SSLEngine_setUseClientMode(false, true, finished);
+        assertConnected(p);
+        assertTrue(finished[0]);
+        assertTrue(finished[1]);
+        p.close();
+
+        // both are client
+        /*
+         * Our implementation throws an SSLHandshakeException, but RI just
+         * stalls forever
+         */
+        p = null;
+        try {
+            p = test_SSLEngine_setUseClientMode(true, true, null);
+            assertNotConnected(p);
+        } catch (SSLHandshakeException maybeExpected) {
+            // Ignored.
+        } finally {
+            if (p != null) {
+                p.close();
+            }
+        }
+
+        p = test_SSLEngine_setUseClientMode(false, false, null);
+        // both are server
+        assertNotConnected(p);
+        p.close();
+    }
+
+    @Test
+    public void test_SSLEngine_setUseClientMode_afterHandshake() throws Exception {
+        // can't set after handshake
+        TestSSLEnginePair pair = TestSSLEnginePair.create();
+        try {
+            pair.server.setUseClientMode(false);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            pair.client.setUseClientMode(false);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        pair.close();
+    }
+
+    private TestSSLEnginePair test_SSLEngine_setUseClientMode(final boolean clientClientMode,
+            final boolean serverClientMode, final boolean[] finished) throws Exception {
+        TestSSLContext c;
+        if (!clientClientMode && serverClientMode) {
+            c = TestSSLContext.create(TestKeyStore.getServer(), TestKeyStore.getClient());
+        } else {
+            c = TestSSLContext.create();
+        }
+
+        return TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+            @Override
+            void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                client.setUseClientMode(clientClientMode);
+                server.setUseClientMode(serverClientMode);
+            }
+        }, finished);
+    }
+
+    @Test
+    public void test_SSLEngine_getEnableSessionCreation() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        assertTrue(e.getEnableSessionCreation());
+        c.close();
+        TestSSLEnginePair.close(new SSLEngine[] {e});
+    }
+
+    @Test
+    public void test_SSLEngine_setEnableSessionCreation_server() throws Exception {
+        TestSSLEnginePair p = null;
+        try {
+            p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+                @Override
+                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                    server.setEnableSessionCreation(false);
+                }
+            });
+            assertNotConnected(p);
+        } catch (SSLException maybeExpected) {
+            // Ignored.
+        } finally {
+            if (p != null) {
+                p.close();
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_setEnableSessionCreation_client() throws Exception {
+        TestSSLEnginePair p = null;
+        try {
+            p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+                @Override
+                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                    client.setEnableSessionCreation(false);
+                }
+            });
+            fail();
+        } catch (SSLException expected) {
+            // Ignored.
+        } finally {
+            if (p != null) {
+                p.close();
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_getSSLParameters() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+
+        SSLParameters p = e.getSSLParameters();
+        assertNotNull(p);
+
+        String[] cipherSuites = p.getCipherSuites();
+        assertNotSame(cipherSuites, e.getEnabledCipherSuites());
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
+
+        String[] protocols = p.getProtocols();
+        assertNotSame(protocols, e.getEnabledProtocols());
+        assertEquals(Arrays.asList(protocols), Arrays.asList(e.getEnabledProtocols()));
+
+        assertEquals(p.getWantClientAuth(), e.getWantClientAuth());
+        assertEquals(p.getNeedClientAuth(), e.getNeedClientAuth());
+
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_setSSLParameters() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLEngine e = c.clientContext.createSSLEngine();
+        String[] defaultCipherSuites = e.getEnabledCipherSuites();
+        String[] defaultProtocols = e.getEnabledProtocols();
+        String[] supportedCipherSuites = e.getSupportedCipherSuites();
+        String[] supportedProtocols = e.getSupportedProtocols();
+
+        {
+            SSLParameters p = new SSLParameters();
+            e.setSSLParameters(p);
+            assertEquals(
+                    Arrays.asList(defaultCipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
+            assertEquals(Arrays.asList(defaultProtocols), Arrays.asList(e.getEnabledProtocols()));
+        }
+
+        {
+            SSLParameters p = new SSLParameters(supportedCipherSuites, supportedProtocols);
+            e.setSSLParameters(p);
+            assertEquals(Arrays.asList(supportedCipherSuites),
+                    Arrays.asList(e.getEnabledCipherSuites()));
+            assertEquals(Arrays.asList(supportedProtocols), Arrays.asList(e.getEnabledProtocols()));
+        }
+        {
+            SSLParameters p = new SSLParameters();
+
+            p.setNeedClientAuth(true);
+            assertFalse(e.getNeedClientAuth());
+            assertFalse(e.getWantClientAuth());
+            e.setSSLParameters(p);
+            assertTrue(e.getNeedClientAuth());
+            assertFalse(e.getWantClientAuth());
+
+            p.setWantClientAuth(true);
+            assertTrue(e.getNeedClientAuth());
+            assertFalse(e.getWantClientAuth());
+            e.setSSLParameters(p);
+            assertFalse(e.getNeedClientAuth());
+            assertTrue(e.getWantClientAuth());
+
+            p.setWantClientAuth(false);
+            assertFalse(e.getNeedClientAuth());
+            assertTrue(e.getWantClientAuth());
+            e.setSSLParameters(p);
+            assertFalse(e.getNeedClientAuth());
+            assertFalse(e.getWantClientAuth());
+        }
+        c.close();
+    }
+
+    private void assertConnected(TestSSLEnginePair e) {
+        assertConnected(e.client, e.server);
+    }
+
+    private void assertNotConnected(TestSSLEnginePair e) {
+        assertNotConnected(e.client, e.server);
+    }
+
+    private void assertConnected(SSLEngine a, SSLEngine b) {
+        assertTrue(connected(a, b));
+    }
+
+    private void assertNotConnected(SSLEngine a, SSLEngine b) {
+        assertFalse(connected(a, b));
+    }
+
+    private boolean connected(SSLEngine a, SSLEngine b) {
+        return (a.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                && b.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                && a.getSession() != null && b.getSession() != null && !a.isInboundDone()
+                && !b.isInboundDone() && !a.isOutboundDone() && !b.isOutboundDone());
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLEngineVersionCompatibilityTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLEngineVersionCompatibilityTest.java
new file mode 100644
index 0000000..bad2a27
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLEngineVersionCompatibilityTest.java
@@ -0,0 +1,755 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static com.android.org.conscrypt.TestUtils.UTF_8;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import com.android.org.conscrypt.tlswire.TlsTester;
+import com.android.org.conscrypt.tlswire.handshake.AlpnHelloExtension;
+import com.android.org.conscrypt.tlswire.handshake.ClientHello;
+import com.android.org.conscrypt.tlswire.handshake.HandshakeMessage;
+import com.android.org.conscrypt.tlswire.handshake.HelloExtension;
+import com.android.org.conscrypt.tlswire.handshake.ServerNameHelloExtension;
+import com.android.org.conscrypt.tlswire.record.TlsProtocols;
+import com.android.org.conscrypt.tlswire.record.TlsRecord;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.nio.ByteBuffer;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509TrustManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * Tests for SSLSocket classes that ensure the TLS 1.2 and TLS 1.3 implementations
+ * are compatible.
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class SSLEngineVersionCompatibilityTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} client, {1} server")
+    public static Iterable<Object[]> data() {
+        // We can't support TLS 1.3 without our own trust manager (which requires
+        // X509ExtendedTrustManager), so only test TLS 1.2 if it's not available.
+        if (TestUtils.isClassAvailable("javax.net.ssl.X509ExtendedTrustManager")) {
+            return Arrays.asList(new Object[][] {
+                    { "TLSv1.2", "TLSv1.2" },
+                    { "TLSv1.2", "TLSv1.3" },
+                    { "TLSv1.3", "TLSv1.2" },
+                    { "TLSv1.3", "TLSv1.3" },
+            });
+        } else {
+            return Arrays.asList(new Object[][]{{ "TLSv1.2", "TLSv1.2"}});
+        }
+    }
+
+    private final String clientVersion;
+    private final String serverVersion;
+
+    public SSLEngineVersionCompatibilityTest(String clientVersion, String serverVersion) {
+        this.clientVersion = clientVersion;
+        this.serverVersion = serverVersion;
+    }
+
+    private static void assertSendsCorrectly(final byte[] sourceBytes, SSLEngine source,
+            SSLEngine dest, boolean needsRecordSplit) throws SSLException {
+        ByteBuffer sourceOut = ByteBuffer.wrap(sourceBytes);
+        SSLSession sourceSession = source.getSession();
+        ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
+        SSLEngineResult sourceOutRes = source.wrap(sourceOut, sourceToDest);
+        sourceToDest.flip();
+
+        String sourceCipherSuite = source.getSession().getCipherSuite();
+        assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
+        assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                sourceOutRes.getHandshakeStatus());
+
+        SSLSession destSession = dest.getSession();
+        ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
+
+        int numUnwrapCalls = 0;
+        while (destIn.position() != sourceOut.limit()) {
+            SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
+            assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                    destRes.getHandshakeStatus());
+            if (needsRecordSplit && numUnwrapCalls == 0) {
+                assertEquals(sourceCipherSuite, 1, destRes.bytesProduced());
+            }
+            numUnwrapCalls++;
+        }
+
+        destIn.flip();
+        byte[] actual = new byte[destIn.remaining()];
+        destIn.get(actual);
+        assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
+
+        if (needsRecordSplit) {
+            assertEquals(sourceCipherSuite, 2, numUnwrapCalls);
+        } else {
+            assertEquals(sourceCipherSuite, 1, numUnwrapCalls);
+            assertSendsCorrectlyWhenSplit(sourceBytes, source, dest);
+        }
+    }
+
+    private static void assertSendsCorrectlyWhenSplit(final byte[] sourceBytes, SSLEngine source,
+            SSLEngine dest) throws SSLException {
+        // Split the input into three to test the version that accepts ByteBuffer[].  Three
+        // is chosen somewhat arbitrarily as a number larger than the minimum of 2 but small
+        // enough that it's not unwieldy.
+        ByteBuffer[] sourceBufs = new ByteBuffer[3];
+        int sourceLen = sourceBytes.length;
+        sourceBufs[0] = ByteBuffer.wrap(sourceBytes, 0, sourceLen / 3);
+        sourceBufs[1] = ByteBuffer.wrap(sourceBytes, sourceLen / 3, sourceLen / 3);
+        sourceBufs[2] = ByteBuffer.wrap(
+            sourceBytes, 2 * (sourceLen / 3), sourceLen - 2 * (sourceLen / 3));
+        SSLSession sourceSession = source.getSession();
+        ByteBuffer sourceToDest = ByteBuffer.allocate(sourceSession.getPacketBufferSize());
+        SSLEngineResult sourceOutRes = source.wrap(sourceBufs, sourceToDest);
+        sourceToDest.flip();
+        String sourceCipherSuite = source.getSession().getCipherSuite();
+        assertEquals(sourceCipherSuite, sourceBytes.length, sourceOutRes.bytesConsumed());
+        assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                sourceOutRes.getHandshakeStatus());
+        SSLSession destSession = dest.getSession();
+        ByteBuffer destIn = ByteBuffer.allocate(destSession.getApplicationBufferSize());
+        int numUnwrapCalls = 0;
+        while (destIn.position() != sourceBytes.length) {
+            SSLEngineResult destRes = dest.unwrap(sourceToDest, destIn);
+            assertEquals(sourceCipherSuite, HandshakeStatus.NOT_HANDSHAKING,
+                    destRes.getHandshakeStatus());
+            numUnwrapCalls++;
+        }
+        destIn.flip();
+        byte[] actual = new byte[destIn.remaining()];
+        destIn.get(actual);
+        assertEquals(sourceCipherSuite, Arrays.toString(sourceBytes), Arrays.toString(actual));
+        assertEquals(sourceCipherSuite, 3, numUnwrapCalls);
+    }
+
+    @Test
+    public void test_SSLEngine_beginHandshake() throws Exception {
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+
+        try {
+            c.clientContext.createSSLEngine().beginHandshake();
+            fail();
+        } catch (IllegalStateException expected) {
+            // Ignored.
+        }
+        c.close();
+
+        TestSSLEnginePair p = TestSSLEnginePair.create();
+        assertConnected(p);
+        p.close();
+    }
+
+    @Test
+    public void test_SSLEngine_beginHandshake_noKeyStore() throws Exception {
+        SSLContext clientContext = SSLContext.getInstance(clientVersion);
+        clientContext.init(null, null, null);
+        SSLContext serverContext = SSLContext.getInstance(serverVersion);
+        serverContext.init(null, null, null);
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .useDefaults(false)
+                .clientContext(clientContext)
+                .serverContext(serverContext).build();
+        SSLEngine[] p = null;
+        try {
+            // TODO Fix KnownFailure AlertException "NO SERVER CERTIFICATE FOUND"
+            // ServerHandshakeImpl.selectSuite should not select a suite without a required cert
+            p = TestSSLEnginePair.connect(c, null);
+            fail();
+        } catch (SSLHandshakeException expected) {
+            // Ignored.
+        } finally {
+            if (p != null) {
+                TestSSLEnginePair.close(p);
+            }
+        }
+        c.close();
+    }
+
+    @Test
+    public void test_SSLEngine_beginHandshake_noClientCertificate() throws Exception {
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+        SSLEngine[] engines = TestSSLEnginePair.connect(c, null);
+        assertConnected(engines[0], engines[1]);
+        c.close();
+        TestSSLEnginePair.close(engines);
+    }
+
+    @Test
+    public void test_SSLEngine_clientAuth() throws Exception {
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+        SSLEngine e = c.clientContext.createSSLEngine();
+
+        assertFalse(e.getWantClientAuth());
+        assertFalse(e.getNeedClientAuth());
+
+        // confirm turning one on by itself
+        e.setWantClientAuth(true);
+        assertTrue(e.getWantClientAuth());
+        assertFalse(e.getNeedClientAuth());
+
+        // confirm turning setting on toggles the other
+        e.setNeedClientAuth(true);
+        assertFalse(e.getWantClientAuth());
+        assertTrue(e.getNeedClientAuth());
+
+        // confirm toggling back
+        e.setWantClientAuth(true);
+        assertTrue(e.getWantClientAuth());
+        assertFalse(e.getNeedClientAuth());
+
+        // TODO Fix KnownFailure "init - invalid private key"
+        TestSSLContext clientAuthContext = new TestSSLContext.Builder()
+                .client(TestKeyStore.getClientCertificate())
+                .server(TestKeyStore.getServer())
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+        TestSSLEnginePair p =
+                TestSSLEnginePair.create(clientAuthContext, new TestSSLEnginePair.Hooks() {
+                    @Override
+                    void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                        server.setWantClientAuth(true);
+                    }
+                });
+        assertConnected(p);
+        assertNotNull(p.client.getSession().getLocalCertificates());
+        TestKeyStore.assertChainLength(p.client.getSession().getLocalCertificates());
+        TestSSLContext.assertClientCertificateChain(
+                clientAuthContext.clientTrustManager, p.client.getSession().getLocalCertificates());
+        clientAuthContext.close();
+        c.close();
+        p.close();
+    }
+
+    /**
+     * http://code.google.com/p/android/issues/detail?id=31903
+     * This test case directly tests the fix for the issue.
+     */
+    @Test
+    public void test_SSLEngine_clientAuthWantedNoClientCert() throws Exception {
+        TestSSLContext clientAuthContext = new TestSSLContext.Builder()
+                .client(TestKeyStore.getClient())
+                .server(TestKeyStore.getServer())
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+        TestSSLEnginePair p =
+                TestSSLEnginePair.create(clientAuthContext, new TestSSLEnginePair.Hooks() {
+                    @Override
+                    void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                        server.setWantClientAuth(true);
+                    }
+                });
+        assertConnected(p);
+        clientAuthContext.close();
+        p.close();
+    }
+
+    /**
+     * http://code.google.com/p/android/issues/detail?id=31903
+     * This test case verifies that if the server requires a client cert
+     * (setNeedClientAuth) but the client does not provide one SSL connection
+     * establishment will fail
+     */
+    @Test
+    public void test_SSLEngine_clientAuthNeededNoClientCert() throws Exception {
+        TestSSLContext clientAuthContext = new TestSSLContext.Builder()
+                .client(TestKeyStore.getClient())
+                .server(TestKeyStore.getServer())
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+        TestSSLEnginePair p = null;
+        try {
+            p = TestSSLEnginePair.create(clientAuthContext, new TestSSLEnginePair.Hooks() {
+                @Override
+                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                    server.setNeedClientAuth(true);
+                }
+            });
+            fail();
+        } catch (SSLException expected) {
+            // Ignored.
+        } finally {
+            clientAuthContext.close();
+            if (p != null) {
+                p.close();
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_endpointVerification_Success() throws Exception {
+        TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable();
+        // The default hostname verifier on OpenJDK just rejects all hostnames,
+        // which is not helpful, so replace with a basic functional one.
+        HostnameVerifier oldDefault = HttpsURLConnection.getDefaultHostnameVerifier();
+        HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+        try {
+            TestSSLContext c = TestSSLContext.newBuilder()
+                    .clientProtocol(clientVersion)
+                    .serverProtocol(serverVersion).build();
+            TestSSLEnginePair p = TestSSLEnginePair.create(c, new TestSSLEnginePair.Hooks() {
+                @Override
+                void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                    SSLParameters p = client.getSSLParameters();
+                    p.setEndpointIdentificationAlgorithm("HTTPS");
+                    client.setSSLParameters(p);
+                }
+            });
+            assertConnected(p);
+            c.close();
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(oldDefault);
+        }
+    }
+
+    @Test
+    public void test_TestSSLEnginePair_create() throws Exception {
+        TestSSLEnginePair test = TestSSLEnginePair.create(
+                TestSSLContext.newBuilder()
+                        .clientProtocol(clientVersion)
+                        .serverProtocol(serverVersion).build());
+        assertNotNull(test.c);
+        assertNotNull(test.server);
+        assertNotNull(test.client);
+        assertConnected(test);
+        test.close();
+    }
+
+    private final int NUM_STRESS_ITERATIONS = 1000;
+
+    @Test
+    public void test_SSLEngine_Multiple_Thread_Success() throws Exception {
+        final TestSSLEnginePair pair = TestSSLEnginePair.create(
+                TestSSLContext.newBuilder()
+                        .clientProtocol(clientVersion)
+                        .serverProtocol(serverVersion).build());
+        try {
+            assertConnected(pair);
+
+            final CountDownLatch startUpSync = new CountDownLatch(2);
+            ExecutorService executor = Executors.newFixedThreadPool(2);
+            Future<Void> client = executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    startUpSync.countDown();
+
+                    for (int i = 0; i < NUM_STRESS_ITERATIONS; i++) {
+                        assertSendsCorrectly("This is the client. Hello!".getBytes(UTF_8),
+                                pair.client, pair.server, false);
+                    }
+
+                    return null;
+                }
+            });
+            Future<Void> server = executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    startUpSync.countDown();
+
+                    for (int i = 0; i < NUM_STRESS_ITERATIONS; i++) {
+                        assertSendsCorrectly("This is the server. Hi!".getBytes(UTF_8), pair.server,
+                                pair.client, false);
+                    }
+
+                    return null;
+                }
+            });
+            executor.shutdown();
+            client.get();
+            server.get();
+        } finally {
+            pair.close();
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_CloseOutbound() throws Exception {
+        final TestSSLEnginePair pair = TestSSLEnginePair.create(
+                TestSSLContext.newBuilder()
+                        .clientProtocol(clientVersion)
+                        .serverProtocol(serverVersion).build());
+        try {
+            assertConnected(pair);
+
+            // Closing the outbound direction should cause a close_notify to be sent
+            pair.client.closeOutbound();
+            ByteBuffer clientOut = ByteBuffer
+                    .allocate(pair.client.getSession().getPacketBufferSize());
+            SSLEngineResult res = pair.client.wrap(ByteBuffer.wrap(new byte[0]), clientOut);
+            assertEquals(Status.CLOSED, res.getStatus());
+            assertEquals(HandshakeStatus.NOT_HANDSHAKING, res.getHandshakeStatus());
+            assertTrue(res.bytesProduced() > 0);
+
+            // Read the close_notify in the server
+            clientOut.flip();
+            ByteBuffer serverIn = ByteBuffer
+                    .allocate(pair.server.getSession().getApplicationBufferSize());
+            res = pair.server.unwrap(clientOut, serverIn);
+            assertEquals(Status.CLOSED, res.getStatus());
+            assertEquals(HandshakeStatus.NEED_WRAP, res.getHandshakeStatus());
+
+            // Reading the close_notify should cause a close_notify to be sent back
+            ByteBuffer serverOut = ByteBuffer
+                    .allocate(pair.server.getSession().getPacketBufferSize());
+            res = pair.server.wrap(ByteBuffer.wrap(new byte[0]), serverOut);
+            assertEquals(Status.CLOSED, res.getStatus());
+            assertEquals(HandshakeStatus.NOT_HANDSHAKING, res.getHandshakeStatus());
+            assertTrue(res.bytesProduced() > 0);
+
+            // Read the close_notify in the client
+            serverOut.flip();
+            ByteBuffer clientIn = ByteBuffer
+                    .allocate(pair.client.getSession().getApplicationBufferSize());
+            res = pair.client.unwrap(serverOut, clientIn);
+            assertEquals(Status.CLOSED, res.getStatus());
+            assertEquals(HandshakeStatus.NOT_HANDSHAKING, res.getHandshakeStatus());
+
+            // Both sides have received close_notify messages, so both peers should have
+            // registered that they're finished
+            assertTrue(pair.client.isInboundDone() && pair.client.isOutboundDone());
+            assertTrue(pair.server.isInboundDone() && pair.server.isOutboundDone());
+        } finally {
+            pair.close();
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_Closed() throws Exception {
+        final TestSSLEnginePair pair = TestSSLEnginePair.create(
+                TestSSLContext.newBuilder()
+                        .clientProtocol(clientVersion)
+                        .serverProtocol(serverVersion).build());
+        pair.close();
+        ByteBuffer out = ByteBuffer.allocate(pair.client.getSession().getPacketBufferSize());
+        SSLEngineResult res = pair.client.wrap(ByteBuffer.wrap(new byte[] { 0x01 }), out);
+        assertEquals(Status.CLOSED, res.getStatus());
+        // The engine should have a close_notify alert pending, so it should ignore the
+        // proffered data and push the alert into out
+        assertEquals(0, res.bytesConsumed());
+        assertNotEquals(0, res.bytesProduced());
+
+        res = pair.client.unwrap(ByteBuffer.wrap(new byte[] { 0x01} ), out);
+        assertEquals(Status.CLOSED, res.getStatus());
+        assertEquals(0, res.bytesConsumed());
+        assertEquals(0, res.bytesProduced());
+    }
+
+    @Test
+    public void test_SSLEngine_ClientHello_record_size() throws Exception {
+        // This test checks the size of ClientHello of the default SSLEngine. TLS/SSL handshakes
+        // with older/unpatched F5/BIG-IP appliances are known to stall and time out when
+        // the fragment containing ClientHello is between 256 and 511 (inclusive) bytes long.
+        SSLContext context = SSLContext.getInstance(clientVersion);
+        context.init(null, null, null);
+        SSLEngine e = context.createSSLEngine();
+        e.setUseClientMode(true);
+
+        // Enable SNI extension on the engine (this is typically enabled by default)
+        // to increase the size of ClientHello.
+        Conscrypt.setHostname(e, "sslenginetest.androidcts.google.com");
+
+        // Enable Session Tickets extension on the engine (this is typically enabled
+        // by default) to increase the size of ClientHello.
+        Conscrypt.setUseSessionTickets(e, true);
+
+        TlsRecord firstReceivedTlsRecord = TlsTester.parseRecord(getFirstChunk(e));
+
+        assertEquals("TLS record type", TlsProtocols.HANDSHAKE, firstReceivedTlsRecord.type);
+        HandshakeMessage handshakeMessage = HandshakeMessage.read(
+                new DataInputStream(new ByteArrayInputStream(firstReceivedTlsRecord.fragment)));
+        assertEquals(
+                "HandshakeMessage type", HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
+
+        int fragmentLength = firstReceivedTlsRecord.fragment.length;
+        if ((fragmentLength >= 256) && (fragmentLength <= 511)) {
+            fail("Fragment containing ClientHello is of dangerous length: " + fragmentLength
+                    + " bytes");
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_ClientHello_SNI() throws Exception {
+        SSLContext context = SSLContext.getInstance(clientVersion);
+        context.init(null, null, null);
+        SSLEngine e = context.createSSLEngine();
+        e.setUseClientMode(true);
+
+        Conscrypt.setHostname(e, "sslenginetest.androidcts.google.com");
+
+        ClientHello clientHello = TlsTester.parseClientHello(getFirstChunk(e));
+        ServerNameHelloExtension sniExtension =
+                (ServerNameHelloExtension) clientHello.findExtensionByType(
+                        HelloExtension.TYPE_SERVER_NAME);
+
+        assertNotNull(sniExtension);
+        assertEquals(Arrays.asList("sslenginetest.androidcts.google.com"), sniExtension.hostnames);
+    }
+
+    @Test
+    public void test_SSLEngine_ClientHello_ALPN() throws Exception {
+        String[] protocolList = new String[] { "h2", "http/1.1" };
+
+        SSLContext context = SSLContext.getInstance(clientVersion);
+        context.init(null, null, null);
+        SSLEngine e = context.createSSLEngine();
+        e.setUseClientMode(true);
+
+        Conscrypt.setApplicationProtocols(e, protocolList);
+
+        ClientHello clientHello = TlsTester.parseClientHello(getFirstChunk(e));
+        AlpnHelloExtension alpnExtension =
+                (AlpnHelloExtension) clientHello.findExtensionByType(
+                        HelloExtension.TYPE_APPLICATION_LAYER_PROTOCOL_NEGOTIATION);
+        assertNotNull(alpnExtension);
+        assertEquals(Arrays.asList(protocolList), alpnExtension.protocols);
+    }
+
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
+
+    private static byte[] getFirstChunk(SSLEngine e) throws SSLException {
+        ByteBuffer out = ByteBuffer.allocate(64 * 1024);
+
+        e.wrap(EMPTY_BUFFER, out);
+        out.flip();
+        byte[] data = new byte[out.limit()];
+        out.get(data);
+
+        return data;
+    }
+
+    @Test
+    public void test_SSLEngine_TlsUnique() throws Exception {
+        // tls_unique isn't supported in TLS 1.3
+        assumeTlsV1_2Connection();
+        TestSSLEnginePair pair = TestSSLEnginePair.create(
+                TestSSLContext.newBuilder()
+                        .clientProtocol(clientVersion)
+                        .serverProtocol(serverVersion).build(),
+                new TestSSLEnginePair.Hooks() {
+                    @Override
+                    void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                        assertNull(Conscrypt.getTlsUnique(client));
+                        assertNull(Conscrypt.getTlsUnique(server));
+                    }
+                });
+        try {
+            assertConnected(pair);
+
+            byte[] clientTlsUnique = Conscrypt.getTlsUnique(pair.client);
+            byte[] serverTlsUnique = Conscrypt.getTlsUnique(pair.server);
+            assertNotNull(clientTlsUnique);
+            assertNotNull(serverTlsUnique);
+            assertArrayEquals(clientTlsUnique, serverTlsUnique);
+        } finally {
+            pair.close();
+        }
+    }
+
+    @Test
+    public void test_SSLEngine_EKM() throws Exception {
+        TestSSLEnginePair pair = TestSSLEnginePair.create(
+                TestSSLContext.newBuilder()
+                        .clientProtocol(clientVersion)
+                        .serverProtocol(serverVersion).build(),
+                new TestSSLEnginePair.Hooks() {
+                    @Override
+                    void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+                        try {
+                            assertNull(Conscrypt.exportKeyingMaterial(client, "FOO", null, 20));
+                            assertNull(Conscrypt.exportKeyingMaterial(server, "FOO", null, 20));
+                        } catch (SSLException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
+        try {
+            assertConnected(pair);
+
+            byte[] clientEkm = Conscrypt.exportKeyingMaterial(pair.client, "FOO", null, 20);
+            byte[] serverEkm = Conscrypt.exportKeyingMaterial(pair.server, "FOO", null, 20);
+            assertNotNull(clientEkm);
+            assertNotNull(serverEkm);
+            assertEquals(20, clientEkm.length);
+            assertEquals(20, serverEkm.length);
+            assertArrayEquals(clientEkm, serverEkm);
+
+            byte[] clientContextEkm = Conscrypt.exportKeyingMaterial(
+                    pair.client, "FOO", new byte[0], 20);
+            byte[] serverContextEkm = Conscrypt.exportKeyingMaterial(
+                    pair.server, "FOO", new byte[0], 20);
+            assertNotNull(clientContextEkm);
+            assertNotNull(serverContextEkm);
+            assertEquals(20, clientContextEkm.length);
+            assertEquals(20, serverContextEkm.length);
+            assertArrayEquals(clientContextEkm, serverContextEkm);
+
+            // In TLS 1.2, an empty context and a null context are different (RFC 5705, section 4),
+            // but in TLS 1.3 they are the same (RFC 8446, section 7.5).
+            if ("TLSv1.2".equals(negotiatedVersion())) {
+                assertFalse(Arrays.equals(clientEkm, clientContextEkm));
+            } else {
+                assertTrue(Arrays.equals(clientEkm, clientContextEkm));
+            }
+        } finally {
+            pair.close();
+        }
+    }
+
+    // Test whether an exception thrown from within the TrustManager properly flows immediately
+    // to the caller and doesn't get caught and held by the SSLEngine.  This was previously
+    // the behavior of Conscrypt, see https://github.com/google/conscrypt/issues/577.
+    @Test
+    public void test_SSLEngine_Exception() throws Exception {
+        final TestSSLContext referenceContext = TestSSLContext.create();
+        class ThrowingTrustManager implements X509TrustManager {
+            public boolean threw = false;
+            @Override
+            public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
+                    throws CertificateException {}
+            @Override
+            public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
+                    throws CertificateException {
+                threw = true;
+                throw new CertificateException("Nope!");
+            }
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return referenceContext.clientTrustManager.getAcceptedIssuers();
+            }
+        }
+        ThrowingTrustManager trustManager = new ThrowingTrustManager();
+        final TestSSLContext c = TestSSLContext.newBuilder()
+                                         .clientProtocol(clientVersion)
+                                         .serverProtocol(serverVersion)
+                                         .clientTrustManager(trustManager)
+                                         .build();
+
+        // The following code is taken from TestSSLEnginePair.connect()
+        SSLSession session = c.clientContext.createSSLEngine().getSession();
+
+        int packetBufferSize = session.getPacketBufferSize();
+        ByteBuffer clientToServer = ByteBuffer.allocate(packetBufferSize);
+        ByteBuffer serverToClient = ByteBuffer.allocate(packetBufferSize);
+
+        int applicationBufferSize = session.getApplicationBufferSize();
+        ByteBuffer scratch = ByteBuffer.allocate(applicationBufferSize);
+
+        SSLEngine client = c.clientContext.createSSLEngine(c.host.getHostName(), c.port);
+        SSLEngine server = c.serverContext.createSSLEngine();
+        client.setUseClientMode(true);
+        server.setUseClientMode(false);
+        client.beginHandshake();
+        server.beginHandshake();
+
+        try {
+            while (true) {
+                boolean clientDone = client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+                boolean serverDone = server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+                if (clientDone && serverDone) {
+                    break;
+                }
+
+                boolean progress = TestSSLEnginePair.handshakeStep(
+                        client, clientToServer, serverToClient, scratch, new boolean[1]);
+                progress |= TestSSLEnginePair.handshakeStep(
+                        server, serverToClient, clientToServer, scratch, new boolean[1]);
+                assertFalse(trustManager.threw);
+                if (!progress) {
+                    break;
+                }
+            }
+            fail();
+        } catch (SSLHandshakeException expected) {
+            assertTrue(expected.getCause() instanceof CertificateException);
+        }
+        assertTrue(trustManager.threw);
+    }
+
+    private void assertConnected(TestSSLEnginePair e) {
+        assertConnected(e.client, e.server);
+    }
+
+    private void assertConnected(SSLEngine a, SSLEngine b) {
+        assertTrue(connected(a, b));
+    }
+
+    private boolean connected(SSLEngine a, SSLEngine b) {
+        return (a.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                && b.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                && a.getSession() != null && b.getSession() != null && !a.isInboundDone()
+                && !b.isInboundDone() && !a.isOutboundDone() && !b.isOutboundDone());
+    }
+
+    // Assumes that the negotiated connection will be TLS 1.2
+    private void assumeTlsV1_2Connection() {
+        assumeTrue("TLSv1.2".equals(negotiatedVersion()));
+    }
+
+    /**
+     * Returns the version that a connection between {@code clientVersion} and
+     * {@code serverVersion} should produce.
+     */
+    private String negotiatedVersion() {
+        if (clientVersion.equals("TLSv1.3") && serverVersion.equals("TLSv1.3")) {
+            return "TLSv1.3";
+        } else {
+            return "TLSv1.2";
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLParametersTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLParametersTest.java
new file mode 100644
index 0000000..93cb054
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLParametersTest.java
@@ -0,0 +1,241 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIMatcher;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLParameters;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLParametersTest {
+    @Test
+    public void test_SSLParameters_emptyConstructor() {
+        SSLParameters p = new SSLParameters();
+        assertNull(p.getCipherSuites());
+        assertNull(p.getProtocols());
+        assertFalse(p.getWantClientAuth());
+        assertFalse(p.getNeedClientAuth());
+    }
+
+    @Test
+    public void test_SSLParameters_cipherSuitesConstructor() {
+        String[] cipherSuites = new String[] {"foo", null, "bar"};
+        SSLParameters p = new SSLParameters(cipherSuites);
+        assertNotNull(p.getCipherSuites());
+        assertNotSame(cipherSuites, p.getCipherSuites());
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
+        assertNull(p.getProtocols());
+        assertFalse(p.getWantClientAuth());
+        assertFalse(p.getNeedClientAuth());
+    }
+
+    @Test
+    public void test_SSLParameters_cpherSuitesProtocolsConstructor() {
+        String[] cipherSuites = new String[] {"foo", null, "bar"};
+        String[] protocols = new String[] {"baz", null, "qux"};
+        SSLParameters p = new SSLParameters(cipherSuites, protocols);
+        assertNotNull(p.getCipherSuites());
+        assertNotNull(p.getProtocols());
+        assertNotSame(cipherSuites, p.getCipherSuites());
+        assertNotSame(protocols, p.getProtocols());
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
+        assertEquals(Arrays.asList(protocols), Arrays.asList(p.getProtocols()));
+        assertFalse(p.getWantClientAuth());
+        assertFalse(p.getNeedClientAuth());
+    }
+
+    @Test
+    public void test_SSLParameters_CipherSuites() {
+        SSLParameters p = new SSLParameters();
+        assertNull(p.getCipherSuites());
+
+        // confirm clone on input
+        String[] cipherSuites = new String[] {"fnord"};
+        String[] copy = cipherSuites.clone();
+        p.setCipherSuites(copy);
+        copy[0] = null;
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
+
+        // confirm clone on output
+        assertNotSame(p.getCipherSuites(), p.getCipherSuites());
+    }
+
+    @Test
+    public void test_SSLParameters_Protocols() {
+        SSLParameters p = new SSLParameters();
+        assertNull(p.getProtocols());
+
+        // confirm clone on input
+        String[] protocols = new String[] {"fnord"};
+        String[] copy = protocols.clone();
+        p.setProtocols(copy);
+        copy[0] = null;
+        assertEquals(Arrays.asList(protocols), Arrays.asList(p.getProtocols()));
+
+        // confirm clone on output
+        assertNotSame(p.getProtocols(), p.getProtocols());
+    }
+
+    @Test
+    public void test_SSLParameters_ClientAuth() {
+        SSLParameters p = new SSLParameters();
+        assertFalse(p.getWantClientAuth());
+        assertFalse(p.getNeedClientAuth());
+
+        // confirm turning one on by itself
+        p.setWantClientAuth(true);
+        assertTrue(p.getWantClientAuth());
+        assertFalse(p.getNeedClientAuth());
+
+        // confirm turning setting on toggles the other
+        p.setNeedClientAuth(true);
+        assertFalse(p.getWantClientAuth());
+        assertTrue(p.getNeedClientAuth());
+
+        // confirm toggling back
+        p.setWantClientAuth(true);
+        assertTrue(p.getWantClientAuth());
+        assertFalse(p.getNeedClientAuth());
+    }
+
+    @Test
+    public void test_SSLParameters_setServerNames_duplicatedNameThrows() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+
+        SSLParameters p = new SSLParameters();
+        ArrayList<SNIServerName> dupeNames = new ArrayList<SNIServerName>();
+        dupeNames.add(new SNIHostName("www.example.com"));
+        dupeNames.add(new SNIHostName("www.example.com"));
+        try {
+            p.setServerNames(dupeNames);
+            fail("Should throw IllegalArgumentException when names are duplicated");
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLParameters_setServerNames_setNull_getNull() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        p.setServerNames(
+                Collections.singletonList((SNIServerName) new SNIHostName("www.example.com")));
+        assertNotNull(p.getServerNames());
+        p.setServerNames(null);
+        assertNull(p.getServerNames());
+    }
+
+    @Test
+    public void test_SSLParameters_setServerNames_setEmpty_getEmpty() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        p.setServerNames(new ArrayList<SNIServerName>());
+        Collection<SNIServerName> actual = p.getServerNames();
+        assertNotNull(actual);
+        assertEquals(0, actual.size());
+    }
+
+    @Test
+    public void test_SSLParameters_getServerNames_unmodifiable() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        p.setServerNames(
+                Collections.singletonList((SNIServerName) new SNIHostName("www.example.com")));
+        Collection<SNIServerName> actual = p.getServerNames();
+        try {
+            actual.add(new SNIHostName("www.foo.com"));
+            fail("Should not allow modifications to the list");
+        } catch (UnsupportedOperationException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLParameters_setSNIMatchers_duplicatedNameThrows() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        ArrayList<SNIMatcher> dupeMatchers = new ArrayList<SNIMatcher>();
+        dupeMatchers.add(SNIHostName.createSNIMatcher("www\\.example\\.com"));
+        dupeMatchers.add(SNIHostName.createSNIMatcher("www\\.example\\.com"));
+        try {
+            p.setSNIMatchers(dupeMatchers);
+            fail("Should throw IllegalArgumentException when matchers are duplicated");
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLParameters_setSNIMatchers_setNull_getNull() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        p.setSNIMatchers(
+                Collections.singletonList(SNIHostName.createSNIMatcher("www\\.example\\.com")));
+        assertNotNull(p.getSNIMatchers());
+        p.setSNIMatchers(null);
+        assertNull(p.getSNIMatchers());
+    }
+
+    @Test
+    public void test_SSLParameters_setSNIMatchers_setEmpty_getEmpty() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        p.setSNIMatchers(
+                Collections.singletonList(SNIHostName.createSNIMatcher("www\\.example\\.com")));
+        assertEquals(1, p.getSNIMatchers().size());
+        p.setSNIMatchers(Collections.<SNIMatcher>emptyList());
+        Collection<SNIMatcher> actual = p.getSNIMatchers();
+        assertNotNull(actual);
+        assertEquals(0, actual.size());
+    }
+
+    @Test
+    public void test_SSLParameters_getSNIMatchers_unmodifiable() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        SSLParameters p = new SSLParameters();
+        p.setSNIMatchers(
+                Collections.singletonList(SNIHostName.createSNIMatcher("www\\.example\\.com")));
+        Collection<SNIMatcher> actual = p.getSNIMatchers();
+        try {
+            actual.add(SNIHostName.createSNIMatcher("www\\.google\\.com"));
+            fail("Should not allow modification of list");
+        } catch (UnsupportedOperationException expected) {
+            // Ignored.
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLServerSocketFactoryTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLServerSocketFactoryTest.java
new file mode 100644
index 0000000..debf19c
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLServerSocketFactoryTest.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt.javax.net.ssl;
+
+import javax.net.ssl.SSLServerSocketFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLServerSocketFactoryTest {
+
+    @Test
+    public void testDefaultConfiguration() throws Exception {
+        SSLConfigurationAsserts.assertSSLServerSocketFactoryDefaultConfiguration(
+                (SSLServerSocketFactory) SSLServerSocketFactory.getDefault());
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLServerSocketTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLServerSocketTest.java
new file mode 100644
index 0000000..7ad349e
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLServerSocketTest.java
@@ -0,0 +1,130 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLServerSocketTest {
+
+    @Test
+    public void testDefaultConfiguration() throws Exception {
+        SSLConfigurationAsserts.assertSSLServerSocketDefaultConfiguration(
+                (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket());
+    }
+
+    @Test
+    public void testSetEnabledCipherSuitesAffectsGetter_TLS12() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLSv1.2");
+        context.init(null, null, null);
+        SSLServerSocket socket =
+                (SSLServerSocket) context.getServerSocketFactory().createServerSocket();
+        String[] cipherSuites = new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(socket.getSupportedCipherSuites())
+        };
+        socket.setEnabledCipherSuites(cipherSuites);
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(socket.getEnabledCipherSuites()));
+    }
+
+    @Test
+    public void testSetEnabledCipherSuitesAffectsGetter_TLS13() throws Exception {
+        SSLServerSocket socket =
+                (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+        String[] cipherSuites = new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(socket.getSupportedCipherSuites())};
+        socket.setEnabledCipherSuites(cipherSuites);
+        List<String> expected = new ArrayList<String>(StandardNames.CIPHER_SUITES_TLS13);
+        expected.addAll(Arrays.asList(cipherSuites));
+        assertEquals(expected, Arrays.asList(socket.getEnabledCipherSuites()));
+    }
+
+    @Test
+    public void testSetEnabledCipherSuitesStoresCopy() throws Exception {
+        SSLServerSocket socket =
+                (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+        String[] array = new String[] {socket.getEnabledCipherSuites()[0]};
+        String originalFirstElement = array[0];
+        socket.setEnabledCipherSuites(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, socket.getEnabledCipherSuites()[0]);
+    }
+
+    @Test
+    public void testSetEnabledProtocolsAffectsGetter() throws Exception {
+        SSLServerSocket socket =
+                (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+        String[] protocols = new String[] {socket.getSupportedProtocols()[0]};
+        socket.setEnabledProtocols(protocols);
+        assertEquals(Arrays.asList(protocols), Arrays.asList(socket.getEnabledProtocols()));
+    }
+
+    @Test
+    public void testSetEnabledProtocolsStoresCopy() throws Exception {
+        SSLServerSocket socket =
+                (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket();
+        String[] array = new String[] {socket.getEnabledProtocols()[0]};
+        String originalFirstElement = array[0];
+        socket.setEnabledProtocols(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, socket.getEnabledProtocols()[0]);
+    }
+
+    @Test
+    public void test_SSLSocket_setEnabledCipherSuites_TLS13() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLSv1.3");
+        context.init(null, null, null);
+        SSLServerSocketFactory sf = context.getServerSocketFactory();
+        SSLServerSocket ssl = (SSLServerSocket) sf.createServerSocket();
+        // The TLS 1.3 cipher suites should be enabled by default
+        assertTrue(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+        // Disabling them should be ignored
+        ssl.setEnabledCipherSuites(new String[0]);
+        assertTrue(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+
+        ssl.setEnabledCipherSuites(new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(ssl.getSupportedCipherSuites())
+        });
+        assertTrue(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+
+        // Disabling TLS 1.3 should disable 1.3 cipher suites
+        ssl.setEnabledProtocols(new String[] { "TLSv1.2" });
+        assertFalse(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSessionContextTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSessionContextTest.java
new file mode 100644
index 0000000..4f51dd6
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSessionContextTest.java
@@ -0,0 +1,419 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static com.android.org.conscrypt.Conscrypt.isConscrypt;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
+import com.android.org.conscrypt.TestUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class SSLSessionContextTest {
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<?> data() {
+        // We can't support TLS 1.3 without our own trust manager (which requires
+        // X509ExtendedTrustManager), so only test TLS 1.2 if it's not available.
+        if (TestUtils.isClassAvailable("javax.net.ssl.X509ExtendedTrustManager")) {
+            return Arrays.asList("TLSv1.2", "TLSv1.3");
+        } else {
+            return Arrays.asList("TLSv1.2");
+        }
+    }
+
+    private final String protocol;
+
+    public SSLSessionContextTest(String protocol) {
+        this.protocol = protocol;
+    }
+
+    private TestSSLContext newTestContext() {
+        return TestSSLContext.newBuilder()
+                .clientProtocol(protocol)
+                .serverProtocol(protocol)
+                .build();
+    }
+
+    private boolean isTls13() {
+        return "TLSv1.3".equals(protocol);
+    }
+
+    @Test
+    public void test_SSLSessionContext_getIds() {
+        TestSSLContext c = newTestContext();
+        assertSSLSessionContextSize(0, c);
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create(newTestContext()).connect();
+        if (isTls13()) {
+            assertSSLSessionContextSizeAtLeast(1, s.c);
+        } else {
+            assertSSLSessionContextSize(1, s.c);
+        }
+        Enumeration<byte[]> clientIds = s.c.clientContext.getClientSessionContext().getIds();
+        Enumeration<byte[]> serverIds = s.c.serverContext.getServerSessionContext().getIds();
+        byte[] clientId = clientIds.nextElement();
+        assertEquals(32, clientId.length);
+        if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertFalse(serverIds.hasMoreElements());
+        } else {
+            byte[] serverId = serverIds.nextElement();
+            assertEquals(32, serverId.length);
+            assertTrue(Arrays.equals(clientId, serverId));
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_getSession() {
+        TestSSLContext c = newTestContext();
+        try {
+            c.clientContext.getClientSessionContext().getSession(null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+        assertNull(c.clientContext.getClientSessionContext().getSession(new byte[0]));
+        assertNull(c.clientContext.getClientSessionContext().getSession(new byte[1]));
+        try {
+            c.serverContext.getServerSessionContext().getSession(null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+        assertNull(c.serverContext.getServerSessionContext().getSession(new byte[0]));
+        assertNull(c.serverContext.getServerSessionContext().getSession(new byte[1]));
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create(newTestContext()).connect();
+        SSLSessionContext client = s.c.clientContext.getClientSessionContext();
+        SSLSessionContext server = s.c.serverContext.getServerSessionContext();
+        byte[] clientId = client.getIds().nextElement();
+        assertNotNull(client.getSession(clientId));
+        assertTrue(Arrays.equals(clientId, client.getSession(clientId).getId()));
+        if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertFalse(server.getIds().hasMoreElements());
+        } else {
+            byte[] serverId = server.getIds().nextElement();
+            assertNotNull(server.getSession(serverId));
+            assertTrue(Arrays.equals(serverId, server.getSession(serverId).getId()));
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_getSessionCacheSize() {
+        TestSSLContext c = newTestContext();
+        int expectedClientSessionCacheSize = expectedClientSslSessionCacheSize(c);
+        int expectedServerSessionCacheSize = expectedServerSslSessionCacheSize(c);
+        assertEquals(expectedClientSessionCacheSize,
+                c.clientContext.getClientSessionContext().getSessionCacheSize());
+        assertEquals(expectedServerSessionCacheSize,
+                c.serverContext.getServerSessionContext().getSessionCacheSize());
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create(newTestContext()).connect();
+        assertEquals(expectedClientSessionCacheSize,
+                s.c.clientContext.getClientSessionContext().getSessionCacheSize());
+        assertEquals(expectedServerSessionCacheSize,
+                s.c.serverContext.getServerSessionContext().getSessionCacheSize());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionCacheSize_noConnect() {
+        TestSSLContext c = newTestContext();
+        int expectedClientSessionCacheSize = expectedClientSslSessionCacheSize(c);
+        int expectedServerSessionCacheSize = expectedServerSslSessionCacheSize(c);
+        assertNoConnectSetSessionCacheSizeBehavior(
+                expectedClientSessionCacheSize, c.clientContext.getClientSessionContext());
+        assertNoConnectSetSessionCacheSizeBehavior(
+                expectedServerSessionCacheSize, c.serverContext.getServerSessionContext());
+        c.close();
+    }
+
+    private static void assertNoConnectSetSessionCacheSizeBehavior(
+            int expectedDefault, SSLSessionContext s) {
+        try {
+            s.setSessionCacheSize(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        assertEquals(expectedDefault, s.getSessionCacheSize());
+        s.setSessionCacheSize(1);
+        assertEquals(1, s.getSessionCacheSize());
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionCacheSize_oneConnect() {
+        TestSSLSocketPair s = TestSSLSocketPair.create(newTestContext()).connect();
+        int expectedClientSessionCacheSize = expectedClientSslSessionCacheSize(s.c);
+        int expectedServerSessionCacheSize = expectedServerSslSessionCacheSize(s.c);
+        SSLSessionContext client = s.c.clientContext.getClientSessionContext();
+        SSLSessionContext server = s.c.serverContext.getServerSessionContext();
+        assertEquals(expectedClientSessionCacheSize, client.getSessionCacheSize());
+        assertEquals(expectedServerSessionCacheSize, server.getSessionCacheSize());
+        if (isTls13()) {
+            assertSSLSessionContextSizeAtLeast(1, s.c);
+        } else {
+            assertSSLSessionContextSize(1, s.c);
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionCacheSize_dynamic() throws Exception {
+        TestSSLContext c = newTestContext();
+        SSLSessionContext client = c.clientContext.getClientSessionContext();
+        SSLSessionContext server = c.serverContext.getServerSessionContext();
+
+        String[] supportedCipherSuites = c.serverSocket.getSupportedCipherSuites();
+        c.serverSocket.setEnabledCipherSuites(supportedCipherSuites);
+        Deque<String> uniqueCipherSuites =
+                new ArrayDeque<String>(Arrays.asList(supportedCipherSuites));
+        // only use RSA cipher suites which will work with our TrustProvider
+        Iterator<String> i = uniqueCipherSuites.iterator();
+        while (i.hasNext()) {
+            String cipherSuite = i.next();
+
+            // Certificate key length too long for export ciphers
+            if (cipherSuite.startsWith("SSL_RSA_EXPORT_")) {
+                i.remove();
+                continue;
+            }
+
+            if (cipherSuite.startsWith("SSL_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("TLS_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("TLS_DHE_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("SSL_DHE_RSA_")) {
+                continue;
+            }
+            i.remove();
+        }
+
+        /*
+         * having more than 3 uniqueCipherSuites is a test
+         * requirement, not a requirement of the interface or
+         * implementation. It simply allows us to make sure that we
+         * will not get a cached session ID since we'll have to
+         * renegotiate a new session due to the new cipher suite
+         * requirement. even this test only really needs three if it
+         * reused the unique cipher suites every time it resets the
+         * session cache.
+         */
+        assertTrue(uniqueCipherSuites.size() >= 3);
+        String cipherSuite1 = uniqueCipherSuites.pop();
+        String cipherSuite2 = uniqueCipherSuites.pop();
+        String cipherSuite3 = uniqueCipherSuites.pop();
+
+        List<SSLSocket[]> toClose = new ArrayList<SSLSocket[]>();
+        toClose.add(
+                TestSSLSocketPair.create(c).connect(new String[] {cipherSuite1}, null).sockets());
+        if (isTls13()) {
+            assertSSLSessionContextSizeAtLeast(1, c);
+        } else {
+            assertSSLSessionContextSize(1, c);
+        }
+        toClose.add(
+                TestSSLSocketPair.create(c).connect(new String[] {cipherSuite2}, null).sockets());
+        if (isTls13()) {
+            assertSSLSessionContextSizeAtLeast(2, c);
+        } else {
+            assertSSLSessionContextSize(2, c);
+        }
+        toClose.add(
+                TestSSLSocketPair.create(c).connect(new String[] {cipherSuite3}, null).sockets());
+        if (isTls13()) {
+            assertSSLSessionContextSizeAtLeast(3, c);
+        } else {
+            assertSSLSessionContextSize(3, c);
+        }
+
+        client.setSessionCacheSize(1);
+        server.setSessionCacheSize(1);
+        assertEquals(1, client.getSessionCacheSize());
+        assertEquals(1, server.getSessionCacheSize());
+        assertSSLSessionContextSize(1, c);
+        toClose.add(
+                TestSSLSocketPair.create(c).connect(new String[] {cipherSuite1}, null).sockets());
+        assertSSLSessionContextSize(1, c);
+
+        client.setSessionCacheSize(2);
+        server.setSessionCacheSize(2);
+        toClose.add(
+                TestSSLSocketPair.create(c).connect(new String[] {cipherSuite2}, null).sockets());
+        assertSSLSessionContextSize(2, c);
+        toClose.add(
+                TestSSLSocketPair.create(c).connect(new String[] {cipherSuite3}, null).sockets());
+        assertSSLSessionContextSize(2, c);
+
+        for (SSLSocket[] pair : toClose) {
+            for (SSLSocket s : pair) {
+                s.close();
+            }
+        }
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_getSessionTimeout() {
+        TestSSLContext c = newTestContext();
+        int expectedCacheTimeout = expectedSslSessionCacheTimeout(c);
+        assertEquals(expectedCacheTimeout,
+                c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(expectedCacheTimeout,
+                c.serverContext.getServerSessionContext().getSessionTimeout());
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create(newTestContext()).connect();
+        assertEquals(expectedCacheTimeout,
+                s.c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(expectedCacheTimeout,
+                s.c.serverContext.getServerSessionContext().getSessionTimeout());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSessionContext_setSessionTimeout() throws Exception {
+        TestSSLContext c = newTestContext();
+        int expectedCacheTimeout = expectedSslSessionCacheTimeout(c);
+        assertEquals(expectedCacheTimeout,
+                c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(expectedCacheTimeout,
+                c.serverContext.getServerSessionContext().getSessionTimeout());
+        c.clientContext.getClientSessionContext().setSessionTimeout(0);
+        c.serverContext.getServerSessionContext().setSessionTimeout(0);
+        assertEquals(0, c.clientContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(0, c.serverContext.getServerSessionContext().getSessionTimeout());
+
+        try {
+            c.clientContext.getClientSessionContext().setSessionTimeout(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            c.serverContext.getServerSessionContext().setSessionTimeout(-1);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        c.close();
+
+        TestSSLSocketPair s = TestSSLSocketPair.create(newTestContext()).connect();
+        if (isTls13()) {
+            assertSSLSessionContextSizeAtLeast(1, s.c);
+        } else {
+            assertSSLSessionContextSize(1, s.c);
+        }
+        Thread.sleep(1000);
+        s.c.clientContext.getClientSessionContext().setSessionTimeout(1);
+        s.c.serverContext.getServerSessionContext().setSessionTimeout(1);
+        assertSSLSessionContextSize(0, s.c);
+        s.close();
+    }
+
+    private static void assertSSLSessionContextSize(int expected, TestSSLContext c) {
+        assertSSLSessionContextSize(expected, c.clientContext.getClientSessionContext(),
+                c.serverContext.getServerSessionContext());
+        assertSSLSessionContextSize(0, c.serverContext.getClientSessionContext(),
+                c.clientContext.getServerSessionContext());
+    }
+
+    private static void assertSSLSessionContextSize(
+            int expected, SSLSessionContext client, SSLSessionContext server) {
+        assertSSLSessionContextSize(expected, client, false);
+        assertSSLSessionContextSize(expected, server, true);
+    }
+
+    private static void assertSSLSessionContextSize(
+            int expected, SSLSessionContext s, boolean server) {
+        if (server && TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertEquals(0, numSessions(s));
+        } else {
+            assertEquals(expected, numSessions(s));
+        }
+    }
+
+    private static void assertSSLSessionContextSizeAtLeast(int expected, TestSSLContext c) {
+        assertSSLSessionContextSizeAtLeast(expected, c.clientContext.getClientSessionContext(),
+                c.serverContext.getServerSessionContext());
+        assertSSLSessionContextSizeAtLeast(0, c.serverContext.getClientSessionContext(),
+                c.clientContext.getServerSessionContext());
+    }
+
+    private static void assertSSLSessionContextSizeAtLeast(
+            int expected, SSLSessionContext client, SSLSessionContext server) {
+        assertSSLSessionContextSizeAtLeast(expected, client, false);
+        assertSSLSessionContextSizeAtLeast(expected, server, true);
+    }
+
+    private static void assertSSLSessionContextSizeAtLeast(
+            int expected, SSLSessionContext s, boolean server) {
+        if (server && TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertEquals(0, numSessions(s));
+        } else {
+            assertTrue("numSessions: " + numSessions(s) + ", expected at least: " + expected,
+                    numSessions(s) >= expected);
+        }
+    }
+
+    private int expectedClientSslSessionCacheSize(TestSSLContext c) {
+        return isConscrypt(c.clientContext.getProvider()) ? 10 : 0;
+    }
+
+    private int expectedServerSslSessionCacheSize(TestSSLContext c) {
+        return isConscrypt(c.serverContext.getProvider()) ? 100 : 0;
+    }
+
+    private int expectedSslSessionCacheTimeout(TestSSLContext c) {
+        return isConscrypt(c.serverContext.getProvider()) ? 8 * 3600 : 24 * 3600;
+    }
+
+    private static int numSessions(SSLSessionContext s) {
+        return Collections.list(s.getIds()).size();
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSessionTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSessionTest.java
new file mode 100644
index 0000000..4fe8310
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSessionTest.java
@@ -0,0 +1,537 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSocket;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLSessionTest {
+    @Test
+    public void test_SSLSocket_TestSSLSessions_create() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid);
+        assertFalse(s.invalid.isValid());
+        assertTrue(s.server.isValid());
+        assertTrue(s.client.isValid());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getApplicationBufferSize() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertTrue(s.invalid.getApplicationBufferSize() > 0);
+        assertTrue(s.server.getApplicationBufferSize() > 0);
+        assertTrue(s.client.getApplicationBufferSize() > 0);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getCipherSuite() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getCipherSuite());
+        assertEquals(StandardNames.CIPHER_SUITE_INVALID, s.invalid.getCipherSuite());
+        assertNotNull(s.server.getCipherSuite());
+        assertNotNull(s.client.getCipherSuite());
+        assertEquals(s.server.getCipherSuite(), s.client.getCipherSuite());
+        StandardNames.assertValidCipherSuites(new String[] {s.server.getCipherSuite()});
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getCreationTime() {
+        // We use OpenSSL, which only returns times accurate to the nearest second.
+        // NativeCrypto just multiplies by 1000, which looks like truncation, which
+        // would make it appear as if the OpenSSL side of things was created before
+        // we called it.
+        long t0 = System.currentTimeMillis() / 1000;
+        TestSSLSessions s = TestSSLSessions.create();
+        long t1 = System.currentTimeMillis() / 1000;
+
+        assertTrue(s.invalid.getCreationTime() > 0);
+
+        long sTime = s.server.getCreationTime() / 1000;
+        assertTrue(sTime + " >= " + t0, sTime >= t0);
+        assertTrue(sTime + " <= " + t1, sTime <= t1);
+
+        long cTime = s.client.getCreationTime() / 1000;
+        assertTrue(cTime + " >= " + t0, cTime >= t0);
+        assertTrue(cTime + " <= " + t1, cTime <= t1);
+
+        s.close();
+    }
+
+    // TLS 1.2 and TLS 1.3 sessions are philosophically different: In TLS 1.3, sessions for
+    // resumption are sent outside the handshake, are generally single-use, and there can be
+    // multiple cached at any time, whereas in TLS 1.2 the session caching info is sent as part of
+    // the handshake and effectively enhances the current session.  So in TLS 1.3, the current
+    // session has no ID (and cannot be resumed), whereas in TLS 1.2, the current session gets
+    // an ID and can be used for session resumption.
+
+    @Test
+    public void test_SSLSession_getId_TLS12() {
+        TestSSLSessions s = TestSSLSessions.create(TestSSLContext.newBuilder()
+                                                           .clientProtocol("TLSv1.2")
+                                                           .serverProtocol("TLSv1.2")
+                                                           .build());
+        assertNotNull(s.invalid.getId());
+        assertNotNull(s.server.getId());
+        assertNotNull(s.client.getId());
+        assertEquals(0, s.invalid.getId().length);
+        if (TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+            assertEquals(0, s.server.getId().length);
+        } else {
+            assertEquals(32, s.server.getId().length);
+            assertTrue(Arrays.equals(s.server.getId(), s.client.getId()));
+        }
+        assertEquals(32, s.client.getId().length);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getId_TLS13() {
+        TestSSLSessions s = TestSSLSessions.create(TestSSLContext.newBuilder()
+                                                           .clientProtocol("TLSv1.3")
+                                                           .serverProtocol("TLSv1.3")
+                                                           .build());
+        assertNotNull(s.invalid.getId());
+        assertNotNull(s.server.getId());
+        assertNotNull(s.client.getId());
+        assertEquals(0, s.invalid.getId().length);
+        assertEquals(0, s.server.getId().length);
+        assertEquals(0, s.client.getId().length);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getLastAccessedTime() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertTrue(s.invalid.getLastAccessedTime() > 0);
+        assertTrue(s.server.getLastAccessedTime() > 0);
+        assertTrue(s.client.getLastAccessedTime() > 0);
+        assertTrue("s.server.getLastAccessedTime()=" + s.server.getLastAccessedTime() + " "
+                        + "s.client.getLastAccessedTime()=" + s.client.getLastAccessedTime(),
+                Math.abs(s.server.getLastAccessedTime() - s.client.getLastAccessedTime())
+                        <= 1000);
+        assertTrue(s.server.getLastAccessedTime() >= s.server.getCreationTime());
+        assertTrue(s.client.getLastAccessedTime() >= s.client.getCreationTime());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getLocalCertificates() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getLocalCertificates());
+        assertNull(s.client.getLocalCertificates());
+        assertNotNull(s.server.getLocalCertificates());
+        TestKeyStore.assertChainLength(s.server.getLocalCertificates());
+        TestSSLContext.assertServerCertificateChain(
+                s.s.c.serverTrustManager, s.server.getLocalCertificates());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.server.getLocalCertificates()[0], s.s.c.serverKeyStore);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getLocalPrincipal() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getLocalPrincipal());
+        assertNull(s.client.getLocalPrincipal());
+        assertNotNull(s.server.getLocalPrincipal());
+        assertNotNull(s.server.getLocalPrincipal().getName());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.server.getLocalPrincipal(), s.s.c.serverKeyStore);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPacketBufferSize() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertTrue(s.invalid.getPacketBufferSize() > 0);
+        assertTrue(s.server.getPacketBufferSize() > 0);
+        assertTrue(s.client.getPacketBufferSize() > 0);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerCertificateChain() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getPeerCertificateChain();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        assertNotNull(s.client.getPeerCertificates());
+        TestKeyStore.assertChainLength(s.client.getPeerCertificateChain());
+        try {
+            assertNull(s.server.getPeerCertificateChain());
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerCertificates() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getPeerCertificates();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        assertNotNull(s.client.getPeerCertificates());
+        TestKeyStore.assertChainLength(s.client.getPeerCertificates());
+        TestSSLContext.assertServerCertificateChain(
+                s.s.c.serverTrustManager, s.client.getPeerCertificates());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.client.getPeerCertificates()[0], s.s.c.serverKeyStore);
+        try {
+            s.server.getPeerCertificates();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerCertificates_resumption() throws Exception {
+        TestSSLContext context = TestSSLContext.create();
+
+        // Ensure that the session is reused to the best of our ability
+        context.clientContext.getClientSessionContext().setSessionTimeout(1000000);
+        context.clientContext.getClientSessionContext().setSessionCacheSize(0);
+
+        SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                context.host, context.port);
+        SSLSocket server = (SSLSocket) context.serverSocket.accept();
+        connect(client, server);
+
+        assertNotNull(client.getSession().getPeerCertificates());
+
+        client.close();
+        server.close();
+
+        client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                context.host, context.port);
+        server = (SSLSocket) context.serverSocket.accept();
+        connect(client, server);
+
+        assertNotNull(client.getSession().getPeerCertificates());
+
+        client.close();
+        server.close();
+        context.close();
+    }
+
+    private static void connect(final SSLSocket client, final SSLSocket server)
+            throws InterruptedException, ExecutionException {
+        ExecutorService executor = Executors.newFixedThreadPool(2);
+        Future<Void> s = executor.submit(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.startHandshake();
+                return null;
+            }
+        });
+        Future<Void> c = executor.submit(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                client.startHandshake();
+                return null;
+            }
+        });
+        executor.shutdown();
+        s.get();
+        c.get();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerHost() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getPeerHost());
+        assertNotNull(s.server.getPeerHost());
+        assertNotNull(s.client.getPeerHost());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerPort() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertEquals(-1, s.invalid.getPeerPort());
+        assertTrue(s.server.getPeerPort() > 0);
+        assertEquals(s.s.c.port, s.client.getPeerPort());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getPeerPrincipal() throws Exception {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getPeerPrincipal();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        try {
+            s.server.getPeerPrincipal();
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // Ignored.
+        }
+        assertNotNull(s.client.getPeerPrincipal());
+        assertNotNull(s.client.getPeerPrincipal().getName());
+        TestSSLContext.assertCertificateInKeyStore(
+                s.client.getPeerPrincipal(), s.s.c.serverKeyStore);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getProtocol() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getProtocol());
+        assertEquals("NONE", s.invalid.getProtocol());
+        assertNotNull(s.server.getProtocol());
+        assertNotNull(s.client.getProtocol());
+        assertEquals(s.server.getProtocol(), s.client.getProtocol());
+        assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(s.server.getProtocol()));
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getSessionContext() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNull(s.invalid.getSessionContext());
+        assertNotNull(s.server.getSessionContext());
+        assertNotNull(s.client.getSessionContext());
+        assertEquals(s.s.c.serverContext.getServerSessionContext(), s.server.getSessionContext());
+        assertEquals(s.s.c.clientContext.getClientSessionContext(), s.client.getSessionContext());
+        assertNotSame(s.server.getSessionContext(), s.client.getSessionContext());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getValue() {
+        TestSSLSessions s = TestSSLSessions.create();
+        try {
+            s.invalid.getValue(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        assertNull(s.invalid.getValue("BOGUS"));
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_getValueNames() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertNotNull(s.invalid.getValueNames());
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_invalidate() {
+        TestSSLSessions s = TestSSLSessions.create();
+
+        assertFalse(s.invalid.isValid());
+        s.invalid.invalidate();
+        assertFalse(s.invalid.isValid());
+        assertNull(s.invalid.getSessionContext());
+
+        assertTrue(s.server.isValid());
+        s.server.invalidate();
+        assertFalse(s.server.isValid());
+        assertNull(s.server.getSessionContext());
+
+        assertTrue(s.client.isValid());
+        s.client.invalidate();
+        assertFalse(s.client.isValid());
+        assertNull(s.client.getSessionContext());
+
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_isValid() {
+        TestSSLSessions s = TestSSLSessions.create();
+        assertFalse(s.invalid.isValid());
+        assertTrue(s.server.isValid());
+        assertTrue(s.client.isValid());
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_putValue() {
+        TestSSLSessions s = TestSSLSessions.create();
+        String key = "KEY";
+        String value = "VALUE";
+        assertNull(s.invalid.getValue(key));
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.invalid.putValue(key, value);
+        assertSame(value, s.invalid.getValue(key));
+        assertEquals(1, s.invalid.getValueNames().length);
+        assertEquals(key, s.invalid.getValueNames()[0]);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_removeValue() {
+        TestSSLSessions s = TestSSLSessions.create();
+        String key = "KEY";
+        String value = "VALUE";
+        s.invalid.putValue(key, value);
+        assertEquals(1, s.invalid.getValueNames().length);
+        assertEquals(key, s.invalid.getValueNames()[0]);
+        s.invalid.removeValue(key);
+        assertNull(s.invalid.getValue(key));
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.close();
+    }
+
+    @Test
+    public void test_SSLSession_BindingListener() {
+        final TestSSLSessions s = TestSSLSessions.create();
+        final String key = "KEY";
+        final boolean[] bound = new boolean[] {false};
+        final Object value = new SSLSessionBindingListener() {
+            @Override
+            public void valueBound(SSLSessionBindingEvent e) {
+                assertEquals(s.client, e.getSession());
+                assertEquals(key, e.getName());
+                assertFalse(bound[0]);
+                bound[0] = true;
+            }
+
+            @Override
+            public void valueUnbound(SSLSessionBindingEvent e) {
+                assertEquals(s.client, e.getSession());
+                assertEquals(key, e.getName());
+                assertTrue(bound[0]);
+                bound[0] = false;
+            }
+        };
+        s.client.putValue(key, value);
+        assertSame(value, s.client.getValue(key));
+        assertTrue(bound[0]);
+        s.client.removeValue(key);
+        assertFalse(bound[0]);
+    }
+
+    @Test
+    public void test_SSLSession_valueIndependence() {
+        // Multiple sessions should have independent value stores
+        for (int i = 0; i < 2; i++) {
+            TestSSLSessions s = TestSSLSessions.create();
+            String key = "KEY";
+            String value = "VALUE";
+            assertNull(s.invalid.getValue(key));
+            assertEquals(0, s.invalid.getValueNames().length);
+            s.invalid.putValue(key, value);
+            assertSame(value, s.invalid.getValue(key));
+            assertEquals(1, s.invalid.getValueNames().length);
+            assertEquals(key, s.invalid.getValueNames()[0]);
+            s.close();
+        }
+    }
+
+    private static String alterOriginalHostName(InetAddress inetAddress, String originalHostName)
+            throws Exception {
+        Method getHolder = InetAddress.class.getDeclaredMethod("holder");
+        getHolder.setAccessible(true);
+
+        Field originalHostNameField = Class.forName("java.net.InetAddress$InetAddressHolder")
+                .getDeclaredField("originalHostName");
+        originalHostNameField.setAccessible(true);
+
+        Object holder = getHolder.invoke(inetAddress);
+        String oldValue = (String)originalHostNameField.get(holder);
+        originalHostNameField.set(holder, originalHostName);
+        return oldValue;
+    }
+
+    // http://b/35942385
+    @Test
+    public void test_SSLSession_getPeerHostFromInetAddress() throws Exception {
+        TestUtils.assumeAndroid();
+        InetAddress inetAddress = TestUtils.getLoopbackAddress();
+        String oldOriginalHostName = alterOriginalHostName(inetAddress, "foobar");
+        try {
+            final TestSSLContext c = TestSSLContext.create();
+            final SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
+                    TestUtils.getLoopbackAddress(), 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();
+
+            SSLSession sslSession = client.getSession();
+            assertEquals("foobar", sslSession.getPeerHost());
+
+            future.get();
+            client.close();
+            server.close();
+            c.close();
+        } finally {
+            // Restore the original value (InetAddress objects are cached).
+            alterOriginalHostName(inetAddress, oldOriginalHostName);
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketFactoryTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketFactoryTest.java
new file mode 100644
index 0000000..d13c039
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketFactoryTest.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLSocketFactoryTest {
+
+    @Test
+    public void test_SSLSocketFactory_getDefault() {
+        SocketFactory sf = SSLSocketFactory.getDefault();
+        assertNotNull(sf);
+        assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
+    }
+
+    @Test
+    public void test_SSLSocketFactory_defaultConfiguration() throws Exception {
+        SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(
+                (SSLSocketFactory) SSLSocketFactory.getDefault());
+    }
+
+    @Test
+    public void test_SSLSocketFactory_getDefaultCipherSuitesReturnsCopies() {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        assertNotSame(sf.getDefaultCipherSuites(), sf.getDefaultCipherSuites());
+    }
+
+    @Test
+    public void test_SSLSocketFactory_getSupportedCipherSuitesReturnsCopies() {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        assertNotSame(sf.getSupportedCipherSuites(), sf.getSupportedCipherSuites());
+    }
+
+    @Test
+    public void test_SSLSocketFactory_createSocket() throws Exception {
+        try {
+            SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            sf.createSocket(null, null, -1, false);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        }
+
+        try {
+            SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            sf.createSocket(new Socket(), null, -1, false);
+            fail();
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+
+        ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0);
+        InetSocketAddress sa = (InetSocketAddress) ss.getLocalSocketAddress();
+        InetAddress host = sa.getAddress();
+        int port = sa.getPort();
+        Socket s = new Socket(host, port);
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        Socket ssl = sf.createSocket(s, null, -1, false);
+        assertNotNull(ssl);
+        assertTrue(SSLSocket.class.isAssignableFrom(ssl.getClass()));
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketTest.java
new file mode 100644
index 0000000..457ce1d
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketTest.java
@@ -0,0 +1,1104 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static com.android.org.conscrypt.TestUtils.UTF_8;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLProtocolException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509ExtendedTrustManager;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import com.android.org.conscrypt.tlswire.TlsTester;
+import com.android.org.conscrypt.tlswire.handshake.CipherSuite;
+import com.android.org.conscrypt.tlswire.handshake.ClientHello;
+import com.android.org.conscrypt.tlswire.handshake.CompressionMethod;
+import com.android.org.conscrypt.tlswire.handshake.EllipticCurve;
+import com.android.org.conscrypt.tlswire.handshake.EllipticCurvesHelloExtension;
+import com.android.org.conscrypt.tlswire.handshake.HelloExtension;
+import com.android.org.conscrypt.tlswire.util.TlsProtocolVersion;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import tests.net.DelegatingSSLSocketFactory;
+import tests.util.ForEachRunner;
+import tests.util.ForEachRunner.Callback;
+import tests.util.Pair;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLSocketTest {
+    private ExecutorService executor;
+    private ThreadGroup threadGroup;
+
+    @Before
+    public void setup() {
+        threadGroup = new ThreadGroup("SSLSocketTest");
+        executor = Executors.newCachedThreadPool(new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+                return new Thread(threadGroup, r);
+            }
+        });
+    }
+
+    @After
+    public void teardown() throws InterruptedException {
+        executor.shutdownNow();
+        executor.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void test_SSLSocket_defaultConfiguration() throws Exception {
+        SSLConfigurationAsserts.assertSSLSocketDefaultConfiguration(
+                (SSLSocket) SSLSocketFactory.getDefault().createSocket());
+    }
+
+    @Test
+    public void test_SSLSocket_getSupportedCipherSuites_returnsCopies() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        assertNotSame(ssl.getSupportedCipherSuites(), ssl.getSupportedCipherSuites());
+    }
+
+    @Test
+    public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
+        // note the rare usage of non-RSA keys
+        TestKeyStore testKeyStore = new TestKeyStore.Builder()
+                                            .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
+                                            .aliasPrefix("rsa-dsa-ec")
+                                            .ca(true)
+                                            .build();
+        StringBuilder error = new StringBuilder();
+        test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore, error);
+        if (error.length() > 0) {
+            throw new Exception("One or more problems in "
+                    + "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error);
+        }
+    }
+
+    private void test_SSLSocket_getSupportedCipherSuites_connect(
+            TestKeyStore testKeyStore, StringBuilder error) throws Exception {
+        String clientToServerString = "this is sent from the client to the server...";
+        String serverToClientString = "... and this from the server to the client";
+        byte[] clientToServer = clientToServerString.getBytes(UTF_8);
+        byte[] serverToClient = serverToClientString.getBytes(UTF_8);
+        KeyManager pskKeyManager =
+                PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy() {
+                    @Override
+                    protected SecretKey getKey(
+                            String identityHint, String identity, Socket socket) {
+                        return newKey();
+                    }
+
+                    @Override
+                    protected SecretKey getKey(
+                            String identityHint, String identity, SSLEngine engine) {
+                        return newKey();
+                    }
+
+                    private SecretKey newKey() {
+                        return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
+                    }
+                });
+        TestSSLContext c = TestSSLContext.newBuilder()
+                                   .client(testKeyStore)
+                                   .server(testKeyStore)
+                                   .clientProtocol("TLSv1.2")
+                                   .serverProtocol("TLSv1.2")
+                                   .additionalClientKeyManagers(new KeyManager[] {pskKeyManager})
+                                   .additionalServerKeyManagers(new KeyManager[] {pskKeyManager})
+                                   .build();
+        String[] cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
+        for (String cipherSuite : cipherSuites) {
+            try {
+                /*
+                 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on
+                 * its own, but instead in conjunction with other
+                 * cipher suites.
+                 */
+                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
+                    continue;
+                }
+                /*
+                 * Similarly with the TLS_FALLBACK_SCSV suite, it is not
+                 * a selectable suite, but is used in conjunction with
+                 * other cipher suites.
+                 */
+                if (cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
+                    continue;
+                }
+                /*
+                 * This test uses TLS 1.2, and the TLS 1.3 cipher suites aren't customizable
+                 * anyway.
+                 */
+                if (StandardNames.CIPHER_SUITES_TLS13.contains(cipherSuite)) {
+                    continue;
+                }
+                String[] clientCipherSuiteArray =
+                        new String[] {cipherSuite, StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION};
+                TestSSLSocketPair socketPair = TestSSLSocketPair.create(c).connect(
+                        clientCipherSuiteArray, clientCipherSuiteArray);
+                SSLSocket server = socketPair.server;
+                SSLSocket client = socketPair.client;
+                // Check that the client can read the message sent by the server
+                server.getOutputStream().write(serverToClient);
+                byte[] clientFromServer = new byte[serverToClient.length];
+                readFully(client.getInputStream(), clientFromServer);
+                assertEquals(serverToClientString, new String(clientFromServer, UTF_8));
+                // Check that the server can read the message sent by the client
+                client.getOutputStream().write(clientToServer);
+                byte[] serverFromClient = new byte[clientToServer.length];
+                readFully(server.getInputStream(), serverFromClient);
+                assertEquals(clientToServerString, new String(serverFromClient, UTF_8));
+                // Check that the server and the client cannot read anything else
+                // (reads should time out)
+                server.setSoTimeout(10);
+                try {
+                    @SuppressWarnings("unused")
+                    int value = server.getInputStream().read();
+                    fail();
+                } catch (IOException expected) {
+                    // Ignored.
+                }
+                client.setSoTimeout(10);
+                try {
+                    @SuppressWarnings("unused")
+                    int value = client.getInputStream().read();
+                    fail();
+                } catch (IOException expected) {
+                    // Ignored.
+                }
+                client.close();
+                server.close();
+            } catch (Exception maybeExpected) {
+                String message = ("Problem trying to connect cipher suite " + cipherSuite);
+                System.out.println(message);
+                maybeExpected.printStackTrace();
+                error.append(message);
+                error.append('\n');
+            }
+        }
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites());
+    }
+
+    @Test
+    public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] array = new String[] {ssl.getEnabledCipherSuites()[0]};
+        String originalFirstElement = array[0];
+        ssl.setEnabledCipherSuites(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, ssl.getEnabledCipherSuites()[0]);
+    }
+
+    @Test
+    public void test_SSLSocket_setEnabledCipherSuites_TLS12() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLSv1.2");
+        context.init(null, null, null);
+        SSLSocket ssl = (SSLSocket) context.getSocketFactory().createSocket();
+        try {
+            ssl.setEnabledCipherSuites(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            ssl.setEnabledCipherSuites(new String[1]);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            ssl.setEnabledCipherSuites(new String[] {"Bogus"});
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        ssl.setEnabledCipherSuites(new String[0]);
+        ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+        ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
+        // Check that setEnabledCipherSuites affects getEnabledCipherSuites
+        String[] cipherSuites = new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(ssl.getSupportedCipherSuites())
+        };
+        ssl.setEnabledCipherSuites(cipherSuites);
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
+    }
+
+    @Test
+    public void test_SSLSocket_setEnabledCipherSuites_TLS13() throws Exception {
+        SSLContext context = SSLContext.getInstance("TLSv1.3");
+        context.init(null, null, null);
+        SSLSocketFactory sf = context.getSocketFactory();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        // The TLS 1.3 cipher suites should be enabled by default
+        assertTrue(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+        // Disabling them should be ignored
+        ssl.setEnabledCipherSuites(new String[0]);
+        assertTrue(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+
+        ssl.setEnabledCipherSuites(new String[] {
+                TestUtils.pickArbitraryNonTls13Suite(ssl.getSupportedCipherSuites())
+        });
+        assertTrue(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+
+        // Disabling TLS 1.3 should disable 1.3 cipher suites
+        ssl.setEnabledProtocols(new String[] { "TLSv1.2" });
+        assertFalse(new HashSet<String>(Arrays.asList(ssl.getEnabledCipherSuites()))
+                .containsAll(StandardNames.CIPHER_SUITES_TLS13));
+    }
+
+    @Test
+    public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        assertNotSame(ssl.getSupportedProtocols(), ssl.getSupportedProtocols());
+    }
+
+    @Test
+    public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols());
+    }
+
+    @Test
+    public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] array = new String[] {ssl.getEnabledProtocols()[0]};
+        String originalFirstElement = array[0];
+        ssl.setEnabledProtocols(array);
+        array[0] = "Modified after having been set";
+        assertEquals(originalFirstElement, ssl.getEnabledProtocols()[0]);
+    }
+
+    @Test
+    public void test_SSLSocket_setEnabledProtocols() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        try {
+            ssl.setEnabledProtocols(null);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            ssl.setEnabledProtocols(new String[1]);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            ssl.setEnabledProtocols(new String[] {"Bogus"});
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        ssl.setEnabledProtocols(new String[0]);
+        ssl.setEnabledProtocols(ssl.getEnabledProtocols());
+        ssl.setEnabledProtocols(ssl.getSupportedProtocols());
+        // Check that setEnabledProtocols affects getEnabledProtocols
+        for (String protocol : ssl.getSupportedProtocols()) {
+            if ("SSLv2Hello".equals(protocol)) {
+                try {
+                    ssl.setEnabledProtocols(new String[] {protocol});
+                    fail("Should fail when SSLv2Hello is set by itself");
+                } catch (IllegalArgumentException expected) {
+                    // Ignored.
+                }
+            } else {
+                String[] protocols = new String[] {protocol};
+                ssl.setEnabledProtocols(protocols);
+                assertEquals(Arrays.deepToString(protocols),
+                        Arrays.deepToString(ssl.getEnabledProtocols()));
+            }
+        }
+    }
+
+    /**
+     * Tests that when the client has a hole in their supported protocol list, the
+     * lower span of contiguous protocols is used in practice.
+     */
+    @Test
+    public void test_SSLSocket_noncontiguousProtocols_useLower() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLContext clientContext = c.clientContext;
+        SSLSocket client = (SSLSocket)
+                clientContext.getSocketFactory().createSocket(c.host, c.port);
+        client.setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1"});
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        server.setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1.1", "TLSv1"});
+        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();
+
+        assertEquals("TLSv1", client.getSession().getProtocol());
+
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    /**
+     * Tests that protocol negotiation succeeds when the highest-supported protocol
+     * for both client and server isn't supported by the other.
+     */
+    @Test
+    public void test_SSLSocket_noncontiguousProtocols_canNegotiate() throws Exception {
+        TestSSLContext c = TestSSLContext.create();
+        SSLContext clientContext = c.clientContext;
+        SSLSocket client = (SSLSocket)
+                clientContext.getSocketFactory().createSocket(c.host, c.port);
+        client.setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1"});
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        server.setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1"});
+        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();
+
+        assertEquals("TLSv1", client.getSession().getProtocol());
+
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_getSession() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        SSLSession session = ssl.getSession();
+        assertNotNull(session);
+        assertFalse(session.isValid());
+    }
+
+    @Test
+    public void test_SSLSocket_getHandshakeSession_unconnected() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket socket = (SSLSocket) sf.createSocket();
+        SSLSession session = socket.getHandshakeSession();
+        assertNull(session);
+    }
+
+    @Test
+    public void test_SSLSocket_getHandshakeSession_duringHandshake_client() throws Exception {
+        // We can't reference the actual context we're using, since we need to pass
+        // the test trust manager in to construct it, so create reference objects that
+        // we can test against.
+        final TestSSLContext referenceContext = TestSSLContext.create();
+        final SSLSocket referenceClientSocket =
+                (SSLSocket) referenceContext.clientContext.getSocketFactory().createSocket();
+
+        final boolean[] wasCalled = new boolean[1];
+        TestSSLContext c =
+                TestSSLContext.newBuilder()
+                        .clientTrustManager(new X509ExtendedTrustManager() {
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                try {
+                                    SSLSocket sslSocket = (SSLSocket) socket;
+                                    SSLSession session = sslSocket.getHandshakeSession();
+                                    assertNotNull(session);
+                                    // By the point of the handshake where we're validating
+                                    // certificates, the hostname is known and the cipher suite
+                                    // should be agreed
+                                    assertEquals(referenceContext.host.getHostName(),
+                                            session.getPeerHost());
+                                    assertEquals(referenceClientSocket.getEnabledCipherSuites()[0],
+                                            session.getCipherSuite());
+                                    wasCalled[0] = true;
+                                } catch (Exception e) {
+                                    throw new CertificateException("Something broke", e);
+                                }
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public X509Certificate[] getAcceptedIssuers() {
+                                return new X509Certificate[0];
+                            }
+                        })
+                        .build();
+        SSLContext clientContext = c.clientContext;
+        SSLSocket client =
+                (SSLSocket) 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();
+
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+        assertTrue(wasCalled[0]);
+    }
+
+    @Test
+    public void test_SSLSocket_getHandshakeSession_duringHandshake_server() throws Exception {
+        // We can't reference the actual context we're using, since we need to pass
+        // the test trust manager in to construct it, so create reference objects that
+        // we can test against.
+        final TestSSLContext referenceContext = TestSSLContext.create();
+        final SSLSocket referenceClientSocket =
+                (SSLSocket) referenceContext.clientContext.getSocketFactory().createSocket();
+
+        final boolean[] wasCalled = new boolean[1];
+        TestSSLContext c =
+                TestSSLContext.newBuilder()
+                        .client(TestKeyStore.getClientCertificate())
+                        .serverTrustManager(new X509ExtendedTrustManager() {
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                try {
+                                    SSLSocket sslSocket = (SSLSocket) socket;
+                                    SSLSession session = sslSocket.getHandshakeSession();
+                                    assertNotNull(session);
+                                    // By the point of the handshake where we're validating client
+                                    // certificates, the cipher suite should be agreed and the
+                                    // server's own certificates should have been delivered
+                                    assertEquals(referenceClientSocket.getEnabledCipherSuites()[0],
+                                            session.getCipherSuite());
+                                    assertNotNull(session.getLocalCertificates());
+                                    assertEquals("CN=localhost",
+                                            ((X509Certificate) session.getLocalCertificates()[0])
+                                                    .getSubjectDN()
+                                                    .getName());
+                                    assertEquals("CN=Test Intermediate Certificate Authority",
+                                            ((X509Certificate) session.getLocalCertificates()[0])
+                                                    .getIssuerDN()
+                                                    .getName());
+                                    wasCalled[0] = true;
+                                } catch (Exception e) {
+                                    throw new CertificateException("Something broke", e);
+                                }
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, Socket socket) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s, SSLEngine sslEngine) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkClientTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public void checkServerTrusted(X509Certificate[] x509Certificates,
+                                    String s) throws CertificateException {
+                                throw new CertificateException("Shouldn't be called");
+                            }
+
+                            @Override
+                            public X509Certificate[] getAcceptedIssuers() {
+                                return referenceContext.serverTrustManager.getAcceptedIssuers();
+                            }
+                        })
+                        .build();
+        SSLContext clientContext = c.clientContext;
+        SSLSocket client =
+                (SSLSocket) 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.setNeedClientAuth(true);
+                server.startHandshake();
+                return null;
+            }
+        });
+        executor.shutdown();
+        client.startHandshake();
+
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+        assertTrue(wasCalled[0]);
+    }
+
+    @Test
+    public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
+        // can't set after handshake
+        TestSSLSocketPair pair = TestSSLSocketPair.create().connect();
+        try {
+            pair.server.setUseClientMode(false);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        try {
+            pair.client.setUseClientMode(false);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_untrustedServer() throws Exception {
+        TestSSLContext c =
+                TestSSLContext.create(TestKeyStore.getClientCA2(), TestKeyStore.getServer());
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.startHandshake();
+                    fail();
+                } catch (SSLHandshakeException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLHandshakeException expected) {
+            assertTrue(expected.getCause() instanceof CertificateException);
+        }
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_getSSLParameters() throws Exception {
+        TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable();
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        SSLParameters p = ssl.getSSLParameters();
+        assertNotNull(p);
+        String[] cipherSuites = p.getCipherSuites();
+        assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
+        assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
+        String[] protocols = p.getProtocols();
+        assertNotSame(protocols, ssl.getEnabledProtocols());
+        assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
+        assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
+        assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
+        assertNull(p.getEndpointIdentificationAlgorithm());
+        p.setEndpointIdentificationAlgorithm(null);
+        assertNull(p.getEndpointIdentificationAlgorithm());
+        p.setEndpointIdentificationAlgorithm("HTTPS");
+        assertEquals("HTTPS", p.getEndpointIdentificationAlgorithm());
+        p.setEndpointIdentificationAlgorithm("FOO");
+        assertEquals("FOO", p.getEndpointIdentificationAlgorithm());
+    }
+
+    @Test
+    public void test_SSLSocket_setSSLParameters() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
+        String[] defaultProtocols = ssl.getEnabledProtocols();
+        String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
+        String[] supportedProtocols = ssl.getSupportedProtocols();
+        {
+            SSLParameters p = new SSLParameters();
+            ssl.setSSLParameters(p);
+            assertEquals(Arrays.asList(defaultCipherSuites),
+                    Arrays.asList(ssl.getEnabledCipherSuites()));
+            assertEquals(Arrays.asList(defaultProtocols), Arrays.asList(ssl.getEnabledProtocols()));
+        }
+        {
+            SSLParameters p = new SSLParameters(supportedCipherSuites, supportedProtocols);
+            ssl.setSSLParameters(p);
+            assertEquals(Arrays.asList(supportedCipherSuites),
+                    Arrays.asList(ssl.getEnabledCipherSuites()));
+            assertEquals(
+                    Arrays.asList(supportedProtocols), Arrays.asList(ssl.getEnabledProtocols()));
+        }
+        {
+            SSLParameters p = new SSLParameters();
+            p.setNeedClientAuth(true);
+            assertFalse(ssl.getNeedClientAuth());
+            assertFalse(ssl.getWantClientAuth());
+            ssl.setSSLParameters(p);
+            assertTrue(ssl.getNeedClientAuth());
+            assertFalse(ssl.getWantClientAuth());
+            p.setWantClientAuth(true);
+            assertTrue(ssl.getNeedClientAuth());
+            assertFalse(ssl.getWantClientAuth());
+            ssl.setSSLParameters(p);
+            assertFalse(ssl.getNeedClientAuth());
+            assertTrue(ssl.getWantClientAuth());
+            p.setWantClientAuth(false);
+            assertFalse(ssl.getNeedClientAuth());
+            assertTrue(ssl.getWantClientAuth());
+            ssl.setSSLParameters(p);
+            assertFalse(ssl.getNeedClientAuth());
+            assertFalse(ssl.getWantClientAuth());
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_setSoTimeout_basic() throws Exception {
+        ServerSocket listening = new ServerSocket(0);
+        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
+        assertEquals(0, underlying.getSoTimeout());
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        Socket wrapping = sf.createSocket(underlying, null, -1, false);
+        assertEquals(0, wrapping.getSoTimeout());
+        // setting wrapper sets underlying and ...
+        int expectedTimeoutMillis = 1000; // 10 was too small because it was affected by rounding
+        wrapping.setSoTimeout(expectedTimeoutMillis);
+        // The kernel can round the requested value based on the HZ setting. We allow up to 10ms.
+        assertTrue(Math.abs(expectedTimeoutMillis - wrapping.getSoTimeout()) <= 10);
+        assertTrue(Math.abs(expectedTimeoutMillis - underlying.getSoTimeout()) <= 10);
+        // ... getting wrapper inspects underlying
+        underlying.setSoTimeout(0);
+        assertEquals(0, wrapping.getSoTimeout());
+        assertEquals(0, underlying.getSoTimeout());
+    }
+
+    @Test
+    public void test_SSLSocket_setSoTimeout_wrapper() throws Exception {
+        ServerSocket listening = new ServerSocket(0);
+        // setSoTimeout applies to read, not connect, so connect first
+        Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
+        Socket server = listening.accept();
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        Socket clientWrapping = sf.createSocket(underlying, null, -1, false);
+        underlying.setSoTimeout(1);
+        try {
+            @SuppressWarnings("unused")
+            int value = clientWrapping.getInputStream().read();
+            fail();
+        } catch (SocketTimeoutException expected) {
+            // Ignored.
+        }
+        clientWrapping.close();
+        server.close();
+        underlying.close();
+        listening.close();
+    }
+
+    @Test
+    public void test_TestSSLSocketPair_create() {
+        TestSSLSocketPair test = TestSSLSocketPair.create().connect();
+        assertNotNull(test.c);
+        assertNotNull(test.server);
+        assertNotNull(test.client);
+        assertTrue(test.server.isConnected());
+        assertTrue(test.client.isConnected());
+        assertFalse(test.server.isClosed());
+        assertFalse(test.client.isClosed());
+        assertNotNull(test.server.getSession());
+        assertNotNull(test.client.getSession());
+        assertTrue(test.server.getSession().isValid());
+        assertTrue(test.client.getSession().isValid());
+        test.close();
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_cipherSuites() throws Exception {
+        ForEachRunner.runNamed(new Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = TlsTester
+                        .captureTlsHandshakeClientHello(executor, sslSocketFactory);
+                final String[] cipherSuites;
+                // RFC 5746 allows you to send an empty "renegotiation_info" extension *or*
+                // a special signaling cipher suite. The TLS API has no way to check or
+                // indicate that a certain TLS extension should be used.
+                HelloExtension renegotiationInfoExtension =
+                    clientHello.findExtensionByType(HelloExtension.TYPE_RENEGOTIATION_INFO);
+                if (renegotiationInfoExtension != null
+                    && renegotiationInfoExtension.data.length == 1
+                    && renegotiationInfoExtension.data[0] == 0) {
+                    cipherSuites = new String[clientHello.cipherSuites.size() + 1];
+                    cipherSuites[clientHello.cipherSuites.size()] =
+                        StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION;
+                } else {
+                    cipherSuites = new String[clientHello.cipherSuites.size()];
+                }
+                for (int i = 0; i < clientHello.cipherSuites.size(); i++) {
+                    CipherSuite cipherSuite = clientHello.cipherSuites.get(i);
+                    cipherSuites[i] = cipherSuite.getAndroidName();
+                }
+                StandardNames.assertDefaultCipherSuites(cipherSuites);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_supportedCurves() throws Exception {
+        ForEachRunner.runNamed(new Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = TlsTester
+                        .captureTlsHandshakeClientHello(executor, sslSocketFactory);
+                EllipticCurvesHelloExtension ecExtension =
+                    (EllipticCurvesHelloExtension) clientHello.findExtensionByType(
+                        HelloExtension.TYPE_ELLIPTIC_CURVES);
+                final String[] supportedCurves;
+                if (ecExtension == null) {
+                    supportedCurves = new String[0];
+                } else {
+                    assertTrue(ecExtension.wellFormed);
+                    supportedCurves = new String[ecExtension.supported.size()];
+                    for (int i = 0; i < ecExtension.supported.size(); i++) {
+                        EllipticCurve curve = ecExtension.supported.get(i);
+                        supportedCurves[i] = curve.toString();
+                    }
+                }
+                StandardNames.assertDefaultEllipticCurves(supportedCurves);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_clientProtocolVersion() throws Exception {
+        ForEachRunner.runNamed(new Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = TlsTester
+                        .captureTlsHandshakeClientHello(executor, sslSocketFactory);
+                assertEquals(TlsProtocolVersion.TLSv1_2, clientHello.clientVersion);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_compressionMethods() throws Exception {
+        ForEachRunner.runNamed(new Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = TlsTester
+                        .captureTlsHandshakeClientHello(executor, sslSocketFactory);
+                assertEquals(Collections.singletonList(CompressionMethod.NULL),
+                    clientHello.compressionMethods);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
+    private List<Pair<String, SSLSocketFactory>> getSSLSocketFactoriesToTest()
+            throws NoSuchAlgorithmException, KeyManagementException {
+        List<Pair<String, SSLSocketFactory>> result =
+                new ArrayList<Pair<String, SSLSocketFactory>>();
+        result.add(Pair.of("default", (SSLSocketFactory) SSLSocketFactory.getDefault()));
+        for (String sslContextProtocol : StandardNames.SSL_CONTEXT_PROTOCOLS_WITH_DEFAULT_CONFIG) {
+            SSLContext sslContext = SSLContext.getInstance(sslContextProtocol);
+            if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(sslContextProtocol)) {
+                continue;
+            }
+            sslContext.init(null, null, null);
+            result.add(Pair.of("SSLContext(\"" + sslContext.getProtocol() + "\")",
+                    sslContext.getSocketFactory()));
+        }
+        return result;
+    }
+
+    @Test
+    public void test_SSLSocket_sendsTlsFallbackScsv_Fallback_Success() throws Exception {
+        TestSSLContext context = TestSSLContext.create();
+        final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                context.host, context.port);
+        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
+        final String[] serverCipherSuites = server.getEnabledCipherSuites();
+        final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
+        System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
+        clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
+        Future<Void> s = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.setEnabledProtocols(new String[]{"TLSv1.2"});
+                server.setEnabledCipherSuites(serverCipherSuites);
+                server.startHandshake();
+                return null;
+            }
+        });
+        Future<Void> c = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                client.setEnabledProtocols(new String[]{"TLSv1.2"});
+                client.setEnabledCipherSuites(clientCipherSuites);
+                client.startHandshake();
+                return null;
+            }
+        });
+        s.get();
+        c.get();
+        client.close();
+        server.close();
+        context.close();
+    }
+
+    // Confirms that communication without the TLS_FALLBACK_SCSV cipher works as it always did.
+    @Test
+    public void test_SSLSocket_sendsNoTlsFallbackScsv_Fallback_Success() throws Exception {
+        TestSSLContext context = TestSSLContext.create();
+        final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                context.host, context.port);
+        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
+        // Confirm absence of TLS_FALLBACK_SCSV.
+        assertFalse(Arrays.asList(client.getEnabledCipherSuites())
+                            .contains(StandardNames.CIPHER_SUITE_FALLBACK));
+        Future<Void> s = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.1"});
+                server.startHandshake();
+                return null;
+            }
+        });
+        Future<Void> c = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                client.setEnabledProtocols(new String[]{"TLSv1.1"});
+                client.startHandshake();
+                return null;
+            }
+        });
+        s.get();
+        c.get();
+        client.close();
+        server.close();
+        context.close();
+    }
+
+    private static void assertInappropriateFallbackIsCause(Throwable cause) {
+        assertTrue(cause.getMessage(),
+                cause.getMessage().contains("inappropriate fallback")
+                        || cause.getMessage().contains("INAPPROPRIATE_FALLBACK"));
+    }
+
+    @Test
+    public void test_SSLSocket_sendsTlsFallbackScsv_InappropriateFallback_Failure()
+            throws Exception {
+        TestSSLContext context = TestSSLContext.create();
+        final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                context.host, context.port);
+        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
+        final String[] serverCipherSuites = server.getEnabledCipherSuites();
+        // Add TLS_FALLBACK_SCSV
+        final String[] clientCipherSuites = new String[serverCipherSuites.length + 1];
+        System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length);
+        clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK;
+        Future<Void> s = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1"});
+                server.setEnabledCipherSuites(serverCipherSuites);
+                try {
+                    server.startHandshake();
+                    fail("Should result in inappropriate fallback");
+                } catch (SSLHandshakeException expected) {
+                    Throwable cause = expected.getCause();
+                    assertEquals(SSLProtocolException.class, cause.getClass());
+                    assertInappropriateFallbackIsCause(cause);
+                }
+                return null;
+            }
+        });
+        Future<Void> c = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                client.setEnabledProtocols(new String[]{"TLSv1"});
+                client.setEnabledCipherSuites(clientCipherSuites);
+                try {
+                    client.startHandshake();
+                    fail("Should receive TLS alert inappropriate fallback");
+                } catch (SSLHandshakeException expected) {
+                    Throwable cause = expected.getCause();
+                    assertEquals(SSLProtocolException.class, cause.getClass());
+                    assertInappropriateFallbackIsCause(cause);
+                }
+                return null;
+            }
+        });
+        s.get();
+        c.get();
+        client.close();
+        server.close();
+        context.close();
+    }
+
+    @Test
+    public void test_SSLSocket_tlsFallback_byVersion() throws Exception {
+        for (final String protocol : new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"}) {
+            SSLSocketFactory factory = new DelegatingSSLSocketFactory(
+                    (SSLSocketFactory) SSLSocketFactory.getDefault()) {
+                @Override
+                protected SSLSocket configureSocket(SSLSocket socket) {
+                    socket.setEnabledProtocols(new String[] {protocol});
+                    String[] enabled = socket.getEnabledCipherSuites();
+                    String[] cipherSuites = new String[socket.getEnabledCipherSuites().length + 1];
+                    System.arraycopy(enabled, 0, cipherSuites, 0, enabled.length);
+                    cipherSuites[cipherSuites.length - 1] = StandardNames.CIPHER_SUITE_FALLBACK;
+                    socket.setEnabledCipherSuites(cipherSuites);
+                    return socket;
+                }
+            };
+            ClientHello clientHello = TlsTester.captureTlsHandshakeClientHello(executor, factory);
+            if (protocol.equals("TLSv1.2") || protocol.equals("TLSv1.3")) {
+                assertFalse(clientHello.cipherSuites.contains(
+                        CipherSuite.valueOf("TLS_FALLBACK_SCSV")));
+            } else {
+                assertTrue(clientHello.cipherSuites.contains(
+                        CipherSuite.valueOf("TLS_FALLBACK_SCSV")));
+            }
+        }
+    }
+
+    private <T> Future<T> runAsync(Callable<T> callable) {
+        return executor.submit(callable);
+    }
+
+    private static void readFully(InputStream in, byte[] dst) throws IOException {
+        int offset = 0;
+        int byteCount = dst.length;
+        while (byteCount > 0) {
+            int bytesRead = in.read(dst, offset, byteCount);
+            if (bytesRead < 0) {
+                throw new EOFException();
+            }
+            offset += bytesRead;
+            byteCount -= bytesRead;
+        }
+    }
+
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
new file mode 100644
index 0000000..b0594e6
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLSocketVersionCompatibilityTest.java
@@ -0,0 +1,2056 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static com.android.org.conscrypt.TestUtils.UTF_8;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import com.android.org.conscrypt.testing.OpaqueProvider;
+import com.android.org.conscrypt.tlswire.TlsTester;
+import com.android.org.conscrypt.tlswire.handshake.AlpnHelloExtension;
+import com.android.org.conscrypt.tlswire.handshake.ClientHello;
+import com.android.org.conscrypt.tlswire.handshake.HandshakeMessage;
+import com.android.org.conscrypt.tlswire.handshake.HelloExtension;
+import com.android.org.conscrypt.tlswire.handshake.ServerNameHelloExtension;
+import com.android.org.conscrypt.tlswire.record.TlsProtocols;
+import com.android.org.conscrypt.tlswire.record.TlsRecord;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.Method;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import javax.net.ssl.ExtendedSSLSession;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.StandardConstants;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import tests.net.DelegatingSSLSocketFactory;
+import tests.util.ForEachRunner;
+import tests.util.ForEachRunner.Callback;
+import tests.util.Pair;
+
+/**
+ * Tests for SSLSocket classes that ensure the TLS 1.2 and TLS 1.3 implementations
+ * are compatible.
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class SSLSocketVersionCompatibilityTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} client, {1} server")
+    public static Iterable<Object[]> data() {
+        // We can't support TLS 1.3 without our own trust manager (which requires
+        // X509ExtendedTrustManager), so only test TLS 1.2 if it's not available.
+        if (TestUtils.isClassAvailable("javax.net.ssl.X509ExtendedTrustManager")) {
+            return Arrays.asList(new Object[][] {
+                    { "TLSv1.2", "TLSv1.2" },
+                    { "TLSv1.2", "TLSv1.3" },
+                    { "TLSv1.3", "TLSv1.2" },
+                    { "TLSv1.3", "TLSv1.3" },
+            });
+        } else {
+            return Arrays.asList(new Object[][]{{ "TLSv1.2", "TLSv1.2"}});
+        }
+    }
+
+    private final String clientVersion;
+    private final String serverVersion;
+    private ExecutorService executor;
+    private ThreadGroup threadGroup;
+
+    public SSLSocketVersionCompatibilityTest(String clientVersion, String serverVersion) {
+        this.clientVersion = clientVersion;
+        this.serverVersion = serverVersion;
+    }
+
+    @Before
+    public void setup() {
+        threadGroup = new ThreadGroup("SSLSocketVersionedTest");
+        executor = Executors.newCachedThreadPool(new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+                return new Thread(threadGroup, r);
+            }
+        });
+    }
+
+    @After
+    public void teardown() throws InterruptedException {
+        executor.shutdownNow();
+        executor.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void test_SSLSocket_startHandshake() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion).build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.startHandshake();
+                assertNotNull(server.getSession());
+                assertNull(server.getHandshakeSession());
+                try {
+                    server.getSession().getPeerCertificates();
+                    fail();
+                } catch (SSLPeerUnverifiedException expected) {
+                    // Ignored.
+                }
+                Certificate[] localCertificates = server.getSession().getLocalCertificates();
+                assertNotNull(localCertificates);
+                TestKeyStore.assertChainLength(localCertificates);
+                assertNotNull(localCertificates[0]);
+                TestSSLContext
+                    .assertServerCertificateChain(c.serverTrustManager, localCertificates);
+                TestSSLContext.assertCertificateInKeyStore(localCertificates[0], c.serverKeyStore);
+                return null;
+            }
+        });
+        client.startHandshake();
+        assertNotNull(client.getSession());
+        assertNull(client.getSession().getLocalCertificates());
+        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
+        assertNotNull(peerCertificates);
+        TestKeyStore.assertChainLength(peerCertificates);
+        assertNotNull(peerCertificates[0]);
+        TestSSLContext.assertServerCertificateChain(c.clientTrustManager, peerCertificates);
+        TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+    private static final class SSLServerSessionIdCallable implements Callable<byte[]> {
+        private final SSLSocket server;
+        private SSLServerSessionIdCallable(SSLSocket server) {
+            this.server = server;
+        }
+        @Override
+        public byte[] call() throws Exception {
+            server.startHandshake();
+            assertNotNull(server.getSession());
+            assertNotNull(server.getSession().getId());
+            return server.getSession().getId();
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_confirmSessionReuse() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final SSLSocket client1 = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
+                c.host.getHostName(), c.port);
+        final SSLSocket server1 = (SSLSocket) c.serverSocket.accept();
+        final Future<byte[]> future1 = runAsync(new SSLServerSessionIdCallable(server1));
+        client1.startHandshake();
+        assertNotNull(client1.getSession());
+        assertNotNull(client1.getSession().getId());
+        final byte[] clientSessionId1 = client1.getSession().getId();
+        final byte[] serverSessionId1 = future1.get();
+        assertTrue(Arrays.equals(clientSessionId1, serverSessionId1));
+        client1.close();
+        server1.close();
+        final SSLSocket client2 = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
+                c.host.getHostName(), c.port);
+        final SSLSocket server2 = (SSLSocket) c.serverSocket.accept();
+        final Future<byte[]> future2 = runAsync(new SSLServerSessionIdCallable(server2));
+        client2.startHandshake();
+        assertNotNull(client2.getSession());
+        assertNotNull(client2.getSession().getId());
+        final byte[] clientSessionId2 = client2.getSession().getId();
+        final byte[] serverSessionId2 = future2.get();
+        assertTrue(Arrays.equals(clientSessionId2, serverSessionId2));
+        client2.close();
+        server2.close();
+        assertTrue(Arrays.equals(clientSessionId1, clientSessionId2));
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_NoEnabledCipherSuites_Failure() throws Exception {
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .useDefaults(false)
+                .clientContext(defaultInit(SSLContext.getInstance(clientVersion)))
+                .serverContext(defaultInit(SSLContext.getInstance(serverVersion)))
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        client.setEnabledCipherSuites(new String[0]);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.startHandshake();
+                    fail();
+                } catch (SSLHandshakeException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLHandshakeException expected) {
+            // Ignored.
+        }
+        future.get();
+        server.close();
+        client.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_startHandshake_noKeyStore() throws Exception {
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .useDefaults(false)
+                .clientContext(defaultInit(SSLContext.getInstance(clientVersion)))
+                .serverContext(defaultInit(SSLContext.getInstance(serverVersion)))
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.startHandshake();
+                    fail();
+                } catch (SSLHandshakeException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLHandshakeException expected) {
+            // Ignored.
+        }
+        future.get();
+        server.close();
+        client.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLContext clientContext = c.clientContext;
+        SSLSocket client =
+                (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.startHandshake();
+                return null;
+            }
+        });
+        client.startHandshake();
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_HandshakeCompletedListener() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.startHandshake();
+                return null;
+            }
+        });
+        final boolean[] handshakeCompletedListenerCalled = new boolean[1];
+        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
+            @Override
+            public void handshakeCompleted(HandshakeCompletedEvent event) {
+                try {
+                    SSLSession session = event.getSession();
+                    String cipherSuite = event.getCipherSuite();
+                    Certificate[] localCertificates = event.getLocalCertificates();
+                    Certificate[] peerCertificates = event.getPeerCertificates();
+                    javax.security.cert.X509Certificate[] peerCertificateChain =
+                        event.getPeerCertificateChain();
+                    Principal peerPrincipal = event.getPeerPrincipal();
+                    Principal localPrincipal = event.getLocalPrincipal();
+                    SSLSocket socket = event.getSocket();
+                    assertNotNull(session);
+                    byte[] id = session.getId();
+                    assertNotNull(id);
+                    if (negotiatedVersion().equals("TLSv1.2")) {
+                        // Session ticket delivery happens inside the handshake in TLS 1.2,
+                        // but outside it for TLS 1.3.
+                        assertEquals(32, id.length);
+                        assertNotNull(c.clientContext.getClientSessionContext().getSession(id));
+                    } else {
+                        assertEquals(0, id.length);
+                    }
+                    assertNotNull(cipherSuite);
+                    assertTrue(Arrays.asList(client.getEnabledCipherSuites())
+                            .contains(cipherSuite));
+                    assertTrue(Arrays.asList(c.serverSocket.getEnabledCipherSuites())
+                            .contains(cipherSuite));
+
+                    assertNull(localCertificates);
+                    assertNotNull(peerCertificates);
+                    TestKeyStore.assertChainLength(peerCertificates);
+                    assertNotNull(peerCertificates[0]);
+                    TestSSLContext
+                        .assertServerCertificateChain(c.clientTrustManager, peerCertificates);
+                    TestSSLContext
+                        .assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
+                    assertNotNull(peerCertificateChain);
+                    TestKeyStore.assertChainLength(peerCertificateChain);
+                    assertNotNull(peerCertificateChain[0]);
+                    TestSSLContext.assertCertificateInKeyStore(
+                        peerCertificateChain[0].getSubjectDN(), c.serverKeyStore);
+                    assertNotNull(peerPrincipal);
+                    TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore);
+                    assertNull(localPrincipal);
+                    assertNotNull(socket);
+                    assertSame(client, socket);
+                    assertNull(socket.getHandshakeSession());
+                    synchronized (handshakeCompletedListenerCalled) {
+                        handshakeCompletedListenerCalled[0] = true;
+                        handshakeCompletedListenerCalled.notify();
+                    }
+                    handshakeCompletedListenerCalled[0] = true;
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        client.startHandshake();
+        future.get();
+        if (negotiatedVersion().equals("TLSv1.2")) {
+            assertNotNull(
+                    c.serverContext.getServerSessionContext()
+                            .getSession(client.getSession().getId()));
+        }
+        synchronized (handshakeCompletedListenerCalled) {
+            while (!handshakeCompletedListenerCalled[0]) {
+                handshakeCompletedListenerCalled.wait();
+            }
+        }
+        client.close();
+        server.close();
+        c.close();
+    }
+    private static final class TestUncaughtExceptionHandler implements UncaughtExceptionHandler {
+        Throwable actualException;
+        @Override
+        public void uncaughtException(Thread thread, Throwable ex) {
+            assertNull(actualException);
+            actualException = ex;
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception {
+        final Thread self = Thread.currentThread();
+        final UncaughtExceptionHandler original = self.getUncaughtExceptionHandler();
+        final RuntimeException expectedException = new RuntimeException("expected");
+        final TestUncaughtExceptionHandler test = new TestUncaughtExceptionHandler();
+        self.setUncaughtExceptionHandler(test);
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.startHandshake();
+                return null;
+            }
+        });
+        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
+            @Override
+            public void handshakeCompleted(HandshakeCompletedEvent event) {
+                throw expectedException;
+            }
+        });
+        client.startHandshake();
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+        assertSame(expectedException, test.actualException);
+        self.setUncaughtExceptionHandler(original);
+    }
+
+    @Test
+    public void test_SSLSocket_getUseClientMode() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        assertTrue(client.getUseClientMode());
+        assertFalse(server.getUseClientMode());
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void testClientMode_normal() throws Exception {
+        // Client is client and server is server.
+        test_SSLSocket_setUseClientMode(true, false);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void testClientMode_reverse() throws Exception {
+        // Client is server and server is client.
+        test_SSLSocket_setUseClientMode(false, true);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void testClientMode_bothClient() throws Exception {
+        test_SSLSocket_setUseClientMode(true, true);
+    }
+
+    @Test
+    public void testClientMode_bothServer() throws Exception {
+        try {
+            test_SSLSocket_setUseClientMode(false, false);
+            fail();
+        } catch (SocketTimeoutException expected) {
+            // Ignore
+        } catch (SSLHandshakeException expected) {
+            // Depending on the timing of the socket closures, this can happen as well.
+            assertTrue("Unexpected handshake error: " + expected.getMessage(),
+                    expected.getMessage().toLowerCase().contains("connection closed"));
+        }
+    }
+
+    private void test_SSLSocket_setUseClientMode(
+            final boolean clientClientMode, final boolean serverClientMode) throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<IOException> future = runAsync(new Callable<IOException>() {
+            @Override
+            public IOException call() throws Exception {
+                try {
+                    if (!serverClientMode) {
+                        server.setSoTimeout(1000);
+                    }
+                    server.setUseClientMode(serverClientMode);
+                    server.startHandshake();
+                    return null;
+                } catch (SSLHandshakeException e) {
+                    return e;
+                } catch (SocketTimeoutException e) {
+                    return e;
+                }
+            }
+        });
+        if (!clientClientMode) {
+            client.setSoTimeout(1000);
+        }
+        client.setUseClientMode(clientClientMode);
+        client.startHandshake();
+        IOException ioe = future.get();
+        if (ioe != null) {
+            throw ioe;
+        }
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_clientAuth() throws Exception {
+        TestSSLContext c = new TestSSLContext.Builder()
+                .client(TestKeyStore.getClientCertificate())
+                .server(TestKeyStore.getServer())
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                assertFalse(server.getWantClientAuth());
+                assertFalse(server.getNeedClientAuth());
+                // confirm turning one on by itself
+                server.setWantClientAuth(true);
+                assertTrue(server.getWantClientAuth());
+                assertFalse(server.getNeedClientAuth());
+                // confirm turning setting on toggles the other
+                server.setNeedClientAuth(true);
+                assertFalse(server.getWantClientAuth());
+                assertTrue(server.getNeedClientAuth());
+                // confirm toggling back
+                server.setWantClientAuth(true);
+                assertTrue(server.getWantClientAuth());
+                assertFalse(server.getNeedClientAuth());
+                server.startHandshake();
+                return null;
+            }
+        });
+        client.startHandshake();
+        assertNotNull(client.getSession().getLocalCertificates());
+        TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
+        TestSSLContext.assertClientCertificateChain(
+                c.clientTrustManager, client.getSession().getLocalCertificates());
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_clientAuth_bogusAlias() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLContext clientContext = SSLContext.getInstance(clientVersion);
+        X509KeyManager keyManager = new X509KeyManager() {
+            @Override
+            public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+                return "bogus";
+            }
+            @Override
+            public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+                throw new AssertionError();
+            }
+            @Override
+            public X509Certificate[] getCertificateChain(String alias) {
+                // return null for "bogus" alias
+                return null;
+            }
+            @Override
+            public String[] getClientAliases(String keyType, Principal[] issuers) {
+                throw new AssertionError();
+            }
+            @Override
+            public String[] getServerAliases(String keyType, Principal[] issuers) {
+                throw new AssertionError();
+            }
+            @Override
+            public PrivateKey getPrivateKey(String alias) {
+                // return null for "bogus" alias
+                return null;
+            }
+        };
+        clientContext.init(
+                new KeyManager[] {keyManager}, new TrustManager[] {c.clientTrustManager}, null);
+        SSLSocket client =
+                (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.setNeedClientAuth(true);
+                    server.startHandshake();
+                    fail();
+                } catch (SSLHandshakeException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        try {
+            client.startHandshake();
+            // In TLS 1.3, the alert will only show up once we try to use the connection, since
+            // the client finishes the handshake without feedback from the server
+            client.getInputStream().read();
+            fail();
+        } catch (SSLException expected) {
+            // before we would get a NullPointerException from passing
+            // due to the null PrivateKey return by the X509KeyManager.
+        }
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_clientAuth_OpaqueKey_RSA() throws Exception {
+        run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientCertificate());
+    }
+
+    @Test
+    public void test_SSLSocket_clientAuth_OpaqueKey_EC_RSA() throws Exception {
+        run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcRsaCertificate());
+    }
+
+    @Test
+    public void test_SSLSocket_clientAuth_OpaqueKey_EC_EC() throws Exception {
+        run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcEcCertificate());
+    }
+    private void run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore keyStore) throws Exception {
+        // OpaqueProvider will not be allowed to operate if the VM we're running on
+        // requires Oracle signatures for provider jars, since we don't sign the test jar.
+        TestUtils.assumeAllowsUnsignedCrypto();
+        try {
+            Security.insertProviderAt(new OpaqueProvider(), 1);
+            final TestSSLContext c = new TestSSLContext.Builder()
+                    .client(keyStore)
+                    .server(TestKeyStore.getServer())
+                    .clientProtocol(clientVersion)
+                    .serverProtocol(serverVersion)
+                    .build();
+            SSLContext clientContext = SSLContext.getInstance("TLS");
+            final X509KeyManager delegateKeyManager = (X509KeyManager) c.clientKeyManagers[0];
+            X509KeyManager keyManager = new X509KeyManager() {
+                @Override
+                public String chooseClientAlias(
+                        String[] keyType, Principal[] issuers, Socket socket) {
+                    return delegateKeyManager.chooseClientAlias(keyType, issuers, socket);
+                }
+                @Override
+                public String chooseServerAlias(
+                        String keyType, Principal[] issuers, Socket socket) {
+                    return delegateKeyManager.chooseServerAlias(keyType, issuers, socket);
+                }
+                @Override
+                public X509Certificate[] getCertificateChain(String alias) {
+                    return delegateKeyManager.getCertificateChain(alias);
+                }
+                @Override
+                public String[] getClientAliases(String keyType, Principal[] issuers) {
+                    return delegateKeyManager.getClientAliases(keyType, issuers);
+                }
+                @Override
+                public String[] getServerAliases(String keyType, Principal[] issuers) {
+                    return delegateKeyManager.getServerAliases(keyType, issuers);
+                }
+                @Override
+                public PrivateKey getPrivateKey(String alias) {
+                    PrivateKey privKey = delegateKeyManager.getPrivateKey(alias);
+                    return OpaqueProvider.wrapKey(privKey);
+                }
+            };
+            clientContext.init(
+                    new KeyManager[] {keyManager}, new TrustManager[] {c.clientTrustManager}, null);
+            SSLSocket client =
+                    (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, c.port);
+            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+            Future<Void> future = runAsync(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    server.setNeedClientAuth(true);
+                    server.startHandshake();
+                    return null;
+                }
+            });
+            client.startHandshake();
+            assertNotNull(client.getSession().getLocalCertificates());
+            TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
+            TestSSLContext.assertClientCertificateChain(
+                    c.clientTrustManager, client.getSession().getLocalCertificates());
+            future.get();
+            client.close();
+            server.close();
+            c.close();
+        } finally {
+            Security.removeProvider(OpaqueProvider.NAME);
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_TrustManagerRuntimeException() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLContext clientContext = SSLContext.getInstance("TLS");
+        X509TrustManager trustManager = new X509TrustManager() {
+            @Override
+            public void checkClientTrusted(X509Certificate[] chain, String authType)
+                    throws CertificateException {
+                throw new AssertionError();
+            }
+            @Override
+            public void checkServerTrusted(X509Certificate[] chain, String authType)
+                    throws CertificateException {
+                throw new RuntimeException(); // throw a RuntimeException from custom TrustManager
+            }
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                throw new AssertionError();
+            }
+        };
+        clientContext.init(null, new TrustManager[] {trustManager}, null);
+        SSLSocket client =
+                (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.startHandshake();
+                    fail();
+                } catch (SSLHandshakeException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLHandshakeException expected) {
+            // before we would get a RuntimeException from checkServerTrusted.
+        }
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_getEnableSessionCreation() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        assertTrue(client.getEnableSessionCreation());
+        assertTrue(server.getEnableSessionCreation());
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_setEnableSessionCreation_server() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                server.setEnableSessionCreation(false);
+                try {
+                    server.startHandshake();
+                    fail();
+                } catch (SSLException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLException expected) {
+            // Ignored.
+        }
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_setEnableSessionCreation_client() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.startHandshake();
+                    fail();
+                } catch (SSLException expected) {
+                    // Ignored.
+                }
+                return null;
+            }
+        });
+        client.setEnableSessionCreation(false);
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLException expected) {
+            // Ignored.
+        }
+        future.get();
+        client.close();
+        server.close();
+        c.close();
+    }
+
+    @Test
+    public void test_SSLSocket_close() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        TestSSLSocketPair pair = TestSSLSocketPair.create(c).connect();
+        SSLSocket server = pair.server;
+        SSLSocket client = pair.client;
+        assertFalse(server.isClosed());
+        assertFalse(client.isClosed());
+        InputStream input = client.getInputStream();
+        OutputStream output = client.getOutputStream();
+        server.close();
+        client.close();
+        assertTrue(server.isClosed());
+        assertTrue(client.isClosed());
+        // close after close is okay...
+        server.close();
+        client.close();
+        // ...so are a lot of other operations...
+        HandshakeCompletedListener l = new HandshakeCompletedListener() {
+            @Override
+            public void handshakeCompleted(HandshakeCompletedEvent e) {
+            }
+        };
+        client.addHandshakeCompletedListener(l);
+        assertNotNull(client.getEnabledCipherSuites());
+        assertNotNull(client.getEnabledProtocols());
+        client.getEnableSessionCreation();
+        client.getNeedClientAuth();
+        assertNotNull(client.getSession());
+        assertNotNull(client.getSSLParameters());
+        assertNotNull(client.getSupportedProtocols());
+        client.getUseClientMode();
+        client.getWantClientAuth();
+        client.removeHandshakeCompletedListener(l);
+        client.setEnabledCipherSuites(new String[0]);
+        client.setEnabledProtocols(new String[0]);
+        client.setEnableSessionCreation(false);
+        client.setNeedClientAuth(false);
+        client.setSSLParameters(client.getSSLParameters());
+        client.setWantClientAuth(false);
+        // ...but some operations are expected to give SocketException...
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        try {
+            client.getInputStream();
+            fail();
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        try {
+            client.getOutputStream();
+            fail();
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        try {
+            @SuppressWarnings("unused")
+            int value = input.read();
+            fail();
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        try {
+            @SuppressWarnings("unused")
+            int bytesRead = input.read(null, -1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        try {
+            output.write(-1);
+            fail();
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        try {
+            output.write(null, -1, -1);
+            fail();
+        } catch (NullPointerException expected) {
+            // Ignored.
+        } catch (SocketException expected) {
+            // Ignored.
+        }
+        // ... and one gives IllegalArgumentException
+        try {
+            client.setUseClientMode(false);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+        pair.close();
+    }
+    /**
+     * b/3350645 Test to confirm that an SSLSocket.close() performing
+     * an SSL_shutdown does not throw an IOException if the peer
+     * socket has been closed.
+     */
+    @Test
+    public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception {
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final Socket underlying = new Socket(c.host, c.port);
+        final SSLSocket wrapping = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
+                underlying, c.host.getHostName(), c.port, false);
+        Future<Void> clientFuture = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                wrapping.startHandshake();
+                wrapping.getOutputStream().write(42);
+                // close the underlying socket,
+                // so that no SSL shutdown is sent
+                underlying.close();
+                wrapping.close();
+                return null;
+            }
+        });
+        SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        server.startHandshake();
+        @SuppressWarnings("unused")
+        int value = server.getInputStream().read();
+        // wait for thread to finish so we know client is closed.
+        clientFuture.get();
+        // close should cause an SSL_shutdown which will fail
+        // because the peer has closed, but it shouldn't throw.
+        server.close();
+    }
+
+    @Test
+    public void test_SSLSocket_endpointIdentification_Success() throws Exception {
+        TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable();
+        // The default hostname verifier on OpenJDK just rejects all hostnames,
+        // which is not helpful, so replace with a basic functional one.
+        HostnameVerifier oldDefault = HttpsURLConnection.getDefaultHostnameVerifier();
+        HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+        try {
+            final TestSSLContext c = new TestSSLContext.Builder()
+                    .clientProtocol(clientVersion)
+                    .serverProtocol(serverVersion)
+                    .build();
+            SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
+            SSLParameters p = client.getSSLParameters();
+            p.setEndpointIdentificationAlgorithm("HTTPS");
+            client.setSSLParameters(p);
+            client.connect(new InetSocketAddress(c.host, c.port));
+            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+            Future<Void> future = runAsync(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    server.startHandshake();
+                    assertNotNull(server.getSession());
+                    try {
+                        server.getSession().getPeerCertificates();
+                        fail();
+                    } catch (SSLPeerUnverifiedException expected) {
+                        // Ignored.
+                    }
+                    Certificate[] localCertificates = server.getSession().getLocalCertificates();
+                    assertNotNull(localCertificates);
+                    TestKeyStore.assertChainLength(localCertificates);
+                    assertNotNull(localCertificates[0]);
+                    TestSSLContext
+                            .assertCertificateInKeyStore(localCertificates[0], c.serverKeyStore);
+                    return null;
+                }
+            });
+            client.startHandshake();
+            assertNotNull(client.getSession());
+            assertNull(client.getSession().getLocalCertificates());
+            Certificate[] peerCertificates = client.getSession().getPeerCertificates();
+            assertNotNull(peerCertificates);
+            TestKeyStore.assertChainLength(peerCertificates);
+            assertNotNull(peerCertificates[0]);
+            TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
+            future.get();
+            client.close();
+            server.close();
+            c.close();
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(oldDefault);
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_endpointIdentification_Failure() throws Exception {
+        TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable();
+        // The default hostname verifier on OpenJDK just rejects all hostnames,
+        // which is not helpful, so replace with a basic functional one.
+        HostnameVerifier oldDefault = HttpsURLConnection.getDefaultHostnameVerifier();
+        HttpsURLConnection.setDefaultHostnameVerifier(new TestHostnameVerifier());
+        try {
+            final TestSSLContext c = new TestSSLContext.Builder()
+                    .clientProtocol(clientVersion)
+                    .serverProtocol(serverVersion)
+                    .build();
+            SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
+            SSLParameters p = client.getSSLParameters();
+            p.setEndpointIdentificationAlgorithm("HTTPS");
+            client.setSSLParameters(p);
+            client.connect(c.getLoopbackAsHostname("unmatched.example.com", c.port));
+            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+            Future<Void> future = runAsync(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    try {
+                        server.startHandshake();
+                        fail("Should receive SSLHandshakeException as server");
+                    } catch (SSLHandshakeException expected) {
+                        // Ignored.
+                    }
+                    return null;
+                }
+            });
+            try {
+                client.startHandshake();
+                fail("Should throw when hostname does not match expected");
+            } catch (SSLHandshakeException expected) {
+                // Ignored.
+            } finally {
+                try {
+                    future.get();
+                } finally {
+                    client.close();
+                    server.close();
+                    c.close();
+                }
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(oldDefault);
+        }
+    }
+
+    @Test(expected = SocketTimeoutException.class)
+    public void test_SSLSocket_setSoWriteTimeout() throws Exception {
+        // Only run this test on Linux since it relies on non-posix methods.
+        assumeTrue("Test only runs on Linux. Current OS: " + osName(), isLinux());
+
+        // In jb-mr2 it was found that we need to also set SO_RCVBUF
+        // to a minimal size or the write would not block.
+        final int receiveBufferSize = 128;
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .serverReceiveBufferSize(receiveBufferSize)
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+
+        final SSLSocket client =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, c.port);
+
+        // Try to make the client SO_SNDBUF size as small as possible
+        // (it can default to 512k or even megabytes).  Note that
+        // socket(7) says that the kernel will double the request to
+        // leave room for its own book keeping and that the minimal
+        // value will be 2048. Also note that tcp(7) says the value
+        // needs to be set before connect(2).
+        int sendBufferSize = 1024;
+        client.setSendBufferSize(sendBufferSize);
+        sendBufferSize = client.getSendBufferSize();
+
+        // Start the handshake.
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                client.startHandshake();
+                return null;
+            }
+        });
+        server.startHandshake();
+
+        assertTrue(isConscryptSocket(client));
+        // The concrete class that Conscrypt returns has methods on it that have no
+        // equivalent on the public API (like setSoWriteTimeout), so users have
+        // previously used reflection to access those otherwise-inaccessible methods
+        // on that class.  The concrete class used to be named OpenSSLSocketImpl, so
+        // check that OpenSSLSocketImpl is still in the class hierarchy so applications
+        // that rely on getting that class back still work.
+        Class<?> superClass = client.getClass();
+        do {
+            superClass = superClass.getSuperclass();
+        } while (superClass != Object.class && !superClass.getName().endsWith("OpenSSLSocketImpl"));
+        assertEquals("OpenSSLSocketImpl", superClass.getSimpleName());
+
+
+        try {
+            setWriteTimeout(client, 1);
+
+            // Add extra space to the write to exceed the send buffer
+            // size and cause the write to block.
+            final int extra = 1;
+            client.getOutputStream().write(new byte[sendBufferSize + extra]);
+        } finally {
+            future.get();
+            client.close();
+            server.close();
+            c.close();
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_reusedNpnSocket() throws Exception {
+        byte[] npnProtocols = new byte[] {
+                8, 'h', 't', 't', 'p', '/', '1', '.', '1'
+        };
+
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
+
+        assertTrue(isConscryptSocket(client));
+        Class<?> actualClass = client.getClass();
+        Method setNpnProtocols = actualClass.getMethod("setNpnProtocols", byte[].class);
+
+        ExecutorService executor = Executors.newSingleThreadExecutor();
+
+        // First connection with NPN set on client and server
+        {
+            setNpnProtocols.invoke(client, npnProtocols);
+            client.connect(new InetSocketAddress(c.host, c.port));
+
+            final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+            assertTrue(isConscryptSocket(server));
+            setNpnProtocols.invoke(server, npnProtocols);
+
+            Future<Void> future = executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    server.startHandshake();
+                    return null;
+                }
+            });
+            client.startHandshake();
+
+            future.get();
+            client.close();
+            server.close();
+        }
+
+        // Second connection with client NPN already set on the SSL context, but
+        // without server NPN set.
+        {
+            SSLServerSocket serverSocket = (SSLServerSocket) c.serverContext
+                    .getServerSocketFactory().createServerSocket(0);
+            InetAddress host = InetAddress.getLocalHost();
+            int port = serverSocket.getLocalPort();
+
+            client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
+            client.connect(new InetSocketAddress(host, port));
+
+            final SSLSocket server = (SSLSocket) serverSocket.accept();
+
+            Future<Void> future = executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    server.startHandshake();
+                    return null;
+                }
+            });
+            client.startHandshake();
+
+            future.get();
+            client.close();
+            server.close();
+            serverSocket.close();
+        }
+
+        c.close();
+    }
+
+    // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
+    @Test
+    public void test_SSLSocket_interrupt_readUnderlyingAndCloseUnderlying() throws Exception {
+        test_SSLSocket_interrupt_case(true, true);
+    }
+
+    // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
+    @Test
+    public void test_SSLSocket_interrupt_readUnderlyingAndCloseWrapper() throws Exception {
+        test_SSLSocket_interrupt_case(true, false);
+    }
+
+    // TODO(nmittler): FD socket gets stuck in read on Windows and OSX.
+    @Test
+    public void test_SSLSocket_interrupt_readWrapperAndCloseUnderlying() throws Exception {
+        test_SSLSocket_interrupt_case(false, true);
+    }
+
+    // TODO(nmittler): Conscrypt socket read may return -1 instead of SocketException.
+    @Test
+    public void test_SSLSocket_interrupt_readWrapperAndCloseWrapper() throws Exception {
+        test_SSLSocket_interrupt_case(false, false);
+    }
+
+    private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying)
+            throws Exception {
+        final int readingTimeoutMillis = 5000;
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final Socket underlying = new Socket(c.host, c.port);
+        final SSLSocket clientWrapping =
+                (SSLSocket) c.clientContext.getSocketFactory().createSocket(
+                        underlying, c.host.getHostName(), c.port, true);
+
+        if (isConscryptFdSocket(clientWrapping) && !readUnderlying && closeUnderlying) {
+            // TODO(nmittler): FD socket gets stuck in the read on Windows and OSX.
+            assumeFalse("Skipping interrupt test on Windows", isWindows());
+            assumeFalse("Skipping interrupt test on OSX", isOsx());
+        }
+
+        SSLSocket server = (SSLSocket) c.serverSocket.accept();
+
+        // Start the handshake.
+        Future<Integer> handshakeFuture = runAsync(new Callable<Integer>() {
+            @Override
+            public Integer call() throws Exception {
+                clientWrapping.startHandshake();
+                return clientWrapping.getInputStream().read();
+            }
+        });
+        server.startHandshake();
+        // TLS 1.3 sends some post-handshake management messages, so send a single byte through
+        // to process through those messages.
+        server.getOutputStream().write(42);
+        assertEquals(42, handshakeFuture.get().intValue());
+
+        final Socket toRead = readUnderlying ? underlying : clientWrapping;
+        final Socket toClose = closeUnderlying ? underlying : clientWrapping;
+
+        // Schedule the socket to be closed in 1 second.
+        Future<Void> future = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                Thread.sleep(1000);
+                toClose.close();
+                return null;
+            }
+        });
+
+        // Read from the socket.
+        try {
+            toRead.setSoTimeout(readingTimeoutMillis);
+            int read = toRead.getInputStream().read();
+            // In the case of reading the wrapper and closing the underlying socket,
+            // there is a race condition between the reading thread being woken and
+            // reading the socket again and the closing thread marking the file descriptor
+            // as invalid.  If the latter happens first, a SocketException is thrown,
+            // but if the former happens first it just looks like the peer closed the
+            // connection and a -1 return is acceptable.
+            if (read != -1 || readUnderlying || !closeUnderlying) {
+                fail();
+            }
+        } catch (SocketTimeoutException e) {
+            throw e;
+        } catch (IOException expected) {
+            // Expected
+        }
+
+        future.get();
+        server.close();
+        underlying.close();
+        server.close();
+    }
+
+    /**
+     * b/7014266 Test to confirm that an SSLSocket.close() on one
+     * thread will interrupt another thread blocked reading on the same
+     * socket.
+     */
+    // TODO(nmittler): Interrupts do not work with the engine-based socket.
+    @Test
+    public void test_SSLSocket_interrupt_read_withoutAutoClose() throws Exception {
+        final int readingTimeoutMillis = 5000;
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final Socket underlying = new Socket(c.host, c.port);
+        final SSLSocket wrapping = (SSLSocket) c.clientContext.getSocketFactory().createSocket(
+                underlying, c.host.getHostName(), c.port, false);
+
+        // TODO(nmittler): Interrupts do not work with the engine-based socket.
+        assumeFalse(isConscryptEngineSocket(wrapping));
+
+        Future<Void> clientFuture = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                wrapping.startHandshake();
+                try {
+                    wrapping.setSoTimeout(readingTimeoutMillis);
+                    wrapping.getInputStream().read();
+                    fail();
+                } catch (SocketException expected) {
+                    // Conscrypt throws an exception complaining that the socket is closed
+                    // if it's interrupted by a close() in the middle of a read()
+                    assertTrue(expected.getMessage().contains("closed"));
+                }
+                return null;
+            }
+        });
+        SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        server.startHandshake();
+
+        // Wait for the client to at least be in the "read" method before calling close()
+        Thread[] threads = new Thread[1];
+        threadGroup.enumerate(threads);
+        if (threads[0] != null) {
+            boolean clientInRead = false;
+            while (!clientInRead) {
+                StackTraceElement[] elements = threads[0].getStackTrace();
+                for (StackTraceElement element : elements) {
+                    if ("read".equals(element.getMethodName())) {
+                        // The client might be executing "read" but still not have reached the
+                        // point in which it's blocked reading. This is causing flakiness
+                        // (b/24367646). Delaying for a fraction of the timeout.
+                        Thread.sleep(1000);
+                        clientInRead = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        wrapping.close();
+
+        clientFuture.get();
+        server.close();
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_record_size() throws Exception {
+        // This test checks the size of ClientHello of the default SSLSocket. TLS/SSL handshakes
+        // with older/unpatched F5/BIG-IP appliances are known to stall and time out when
+        // the fragment containing ClientHello is between 256 and 511 (inclusive) bytes long.
+        SSLContext sslContext = SSLContext.getInstance(clientVersion);
+        sslContext.init(null, null, null);
+        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+        sslSocketFactory = new DelegatingSSLSocketFactory(sslSocketFactory) {
+            @Override
+            protected SSLSocket configureSocket(SSLSocket socket) {
+                // Enable SNI extension on the socket (this is typically enabled by default)
+                // to increase the size of ClientHello.
+                setHostname(socket);
+
+                // Enable Session Tickets extension on the socket (this is typically enabled
+                // by default) to increase the size of ClientHello.
+                enableSessionTickets(socket);
+                return socket;
+            }
+        };
+        TlsRecord firstReceivedTlsRecord = TlsTester.captureTlsHandshakeFirstTlsRecord(executor, sslSocketFactory);
+        assertEquals("TLS record type", TlsProtocols.HANDSHAKE, firstReceivedTlsRecord.type);
+        HandshakeMessage handshakeMessage = HandshakeMessage.read(
+                new DataInputStream(new ByteArrayInputStream(firstReceivedTlsRecord.fragment)));
+        assertEquals(
+                "HandshakeMessage type", HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
+        int fragmentLength = firstReceivedTlsRecord.fragment.length;
+        if ((fragmentLength >= 256) && (fragmentLength <= 511)) {
+            fail("Fragment containing ClientHello is of dangerous length: " + fragmentLength
+                    + " bytes");
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_SNI() throws Exception {
+        ForEachRunner.runNamed(new Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = TlsTester
+                    .captureTlsHandshakeClientHello(executor, sslSocketFactory);
+                ServerNameHelloExtension sniExtension =
+                    (ServerNameHelloExtension) clientHello.findExtensionByType(
+                        HelloExtension.TYPE_SERVER_NAME);
+                assertNotNull(sniExtension);
+                assertEquals(
+                    Collections.singletonList("localhost.localdomain"), sniExtension.hostnames);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
+    @Test
+    public void test_SSLSocket_ClientHello_ALPN() throws Exception {
+        final String[] protocolList = new String[] { "h2", "http/1.1" };
+        
+        ForEachRunner.runNamed(new Callback<SSLSocketFactory>() {
+            @Override
+            public void run(SSLSocketFactory sslSocketFactory) throws Exception {
+                ClientHello clientHello = TlsTester.captureTlsHandshakeClientHello(executor,
+                        new DelegatingSSLSocketFactory(sslSocketFactory) {
+                            @Override public SSLSocket configureSocket(SSLSocket socket) {
+                                Conscrypt.setApplicationProtocols(socket, protocolList);
+                                return socket;
+                            }
+                        });
+                AlpnHelloExtension alpnExtension =
+                        (AlpnHelloExtension) clientHello.findExtensionByType(
+                                HelloExtension.TYPE_APPLICATION_LAYER_PROTOCOL_NEGOTIATION);
+                assertNotNull(alpnExtension);
+                assertEquals(Arrays.asList(protocolList), alpnExtension.protocols);
+            }
+        }, getSSLSocketFactoriesToTest());
+    }
+
+    private List<Pair<String, SSLSocketFactory>> getSSLSocketFactoriesToTest()
+            throws NoSuchAlgorithmException, KeyManagementException {
+        List<Pair<String, SSLSocketFactory>> result =
+                new ArrayList<Pair<String, SSLSocketFactory>>();
+        result.add(Pair.of("default", (SSLSocketFactory) SSLSocketFactory.getDefault()));
+        for (String sslContextProtocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+            SSLContext sslContext = SSLContext.getInstance(sslContextProtocol);
+            if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(sslContextProtocol)) {
+                continue;
+            }
+            sslContext.init(null, null, null);
+            result.add(Pair.of("SSLContext(\"" + sslContext.getProtocol() + "\")",
+                    sslContext.getSocketFactory()));
+        }
+        return result;
+    }
+
+    // http://b/18428603
+    @Test
+    public void test_SSLSocket_getPortWithSNI() throws Exception {
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        SSLSocket client =
+            (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+        try {
+            client.connect(new InetSocketAddress(context.host, context.port));
+            setHostname(client);
+            assertTrue(client.getPort() > 0);
+        } finally {
+            client.close();
+            context.close();
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_SNIHostName() throws Exception {
+        TestUtils.assumeSNIHostnameAvailable();
+        final TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket();
+        SSLParameters clientParams = client.getSSLParameters();
+        clientParams.setServerNames(
+                Collections.singletonList((SNIServerName) new SNIHostName("www.example.com")));
+        client.setSSLParameters(clientParams);
+        SSLParameters serverParams = c.serverSocket.getSSLParameters();
+        serverParams.setSNIMatchers(
+                Collections.singletonList(SNIHostName.createSNIMatcher("www\\.example\\.com")));
+        c.serverSocket.setSSLParameters(serverParams);
+        client.connect(new InetSocketAddress(c.host, c.port));
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        @SuppressWarnings("unused")
+        Future<?> future = runAsync(new Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
+                client.startHandshake();
+                return null;
+            }
+        });
+        server.startHandshake();
+        SSLSession serverSession = server.getSession();
+        assertTrue(serverSession instanceof ExtendedSSLSession);
+        ExtendedSSLSession extendedServerSession = (ExtendedSSLSession) serverSession;
+        List<SNIServerName> requestedNames = extendedServerSession.getRequestedServerNames();
+        assertNotNull(requestedNames);
+        assertEquals(1, requestedNames.size());
+        SNIServerName serverName = requestedNames.get(0);
+        assertEquals(StandardConstants.SNI_HOST_NAME, serverName.getType());
+        assertTrue(serverName instanceof SNIHostName);
+        SNIHostName serverHostName = (SNIHostName) serverName;
+        assertEquals("www.example.com", serverHostName.getAsciiName());
+    }
+
+    @Test
+    public void test_SSLSocket_ClientGetsAlertDuringHandshake_HasGoodExceptionMessage()
+            throws Exception {
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final ServerSocket listener = ServerSocketFactory.getDefault().createServerSocket(0);
+        final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                context.host, listener.getLocalPort());
+        final Socket server = listener.accept();
+        Future<Void> c = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    client.startHandshake();
+                    fail("Should receive handshake exception");
+                } catch (SSLHandshakeException expected) {
+                    assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN"));
+                    assertFalse(expected.getMessage().contains("You should never see this."));
+                }
+                return null;
+            }
+        });
+        Future<Void> s = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                // Wait until the client sends something.
+                byte[] scratch = new byte[8192];
+                @SuppressWarnings("unused")
+                int bytesRead = server.getInputStream().read(scratch);
+                // Write a bogus TLS alert:
+                // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Protocol Version)
+                server.getOutputStream()
+                    .write(new byte[]{0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46});
+                // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Close Notify)
+                server.getOutputStream()
+                    .write(new byte[]{0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00});
+                return null;
+            }
+        });
+        c.get(5, TimeUnit.SECONDS);
+        s.get(5, TimeUnit.SECONDS);
+        client.close();
+        server.close();
+        listener.close();
+        context.close();
+    }
+
+    @Test
+    public void test_SSLSocket_ServerGetsAlertDuringHandshake_HasGoodExceptionMessage()
+            throws Exception {
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final Socket client = SocketFactory.getDefault().createSocket(context.host, context.port);
+        final SSLSocket server = (SSLSocket) context.serverSocket.accept();
+        Future<Void> s = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                try {
+                    server.startHandshake();
+                    fail("Should receive handshake exception");
+                } catch (SSLHandshakeException expected) {
+                    assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN"));
+                    assertFalse(expected.getMessage().contains("You should never see this."));
+                }
+                return null;
+            }
+        });
+        Future<Void> c = runAsync(new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                // Send bogus ClientHello:
+                // TLSv1.2 Record Layer: Handshake Protocol: Client Hello
+                client.getOutputStream().write(new byte[]{
+                    (byte) 0x16, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0xb9,
+                    (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xb5, (byte) 0x03,
+                    (byte) 0x03, (byte) 0x5a, (byte) 0x31, (byte) 0xba, (byte) 0x44,
+                    (byte) 0x24, (byte) 0xfd, (byte) 0xf0, (byte) 0x56, (byte) 0x46,
+                    (byte) 0xea, (byte) 0xee, (byte) 0x1c, (byte) 0x62, (byte) 0x8f,
+                    (byte) 0x18, (byte) 0x04, (byte) 0xbd, (byte) 0x1c, (byte) 0xbc,
+                    (byte) 0xbf, (byte) 0x6d, (byte) 0x84, (byte) 0x12, (byte) 0xe9,
+                    (byte) 0x94, (byte) 0xf5, (byte) 0x1c, (byte) 0x15, (byte) 0x3e,
+                    (byte) 0x79, (byte) 0x01, (byte) 0xe2, (byte) 0x00, (byte) 0x00,
+                    (byte) 0x28, (byte) 0xc0, (byte) 0x2b, (byte) 0xc0, (byte) 0x2c,
+                    (byte) 0xc0, (byte) 0x2f, (byte) 0xc0, (byte) 0x30, (byte) 0x00,
+                    (byte) 0x9e, (byte) 0x00, (byte) 0x9f, (byte) 0xc0, (byte) 0x09,
+                    (byte) 0xc0, (byte) 0x0a, (byte) 0xc0, (byte) 0x13, (byte) 0xc0,
+                    (byte) 0x14, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x39,
+                    (byte) 0xc0, (byte) 0x07, (byte) 0xc0, (byte) 0x11, (byte) 0x00,
+                    (byte) 0x9c, (byte) 0x00, (byte) 0x9d, (byte) 0x00, (byte) 0x2f,
+                    (byte) 0x00, (byte) 0x35, (byte) 0x00, (byte) 0x05, (byte) 0x00,
+                    (byte) 0xff, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x64,
+                    (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x04, (byte) 0x03,
+                    (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x0a,
+                    (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x32, (byte) 0x00,
+                    (byte) 0x0e, (byte) 0x00, (byte) 0x0d, (byte) 0x00, (byte) 0x19,
+                    (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x0c, (byte) 0x00,
+                    (byte) 0x18, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x0a,
+                    (byte) 0x00, (byte) 0x16, (byte) 0x00, (byte) 0x17, (byte) 0x00,
+                    (byte) 0x08, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x07,
+                    (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x15, (byte) 0x00,
+                    (byte) 0x04, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x12,
+                    (byte) 0x00, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x00,
+                    (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x0f,
+                    (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x11, (byte) 0x00,
+                    (byte) 0x0d, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x1e,
+                    (byte) 0x06, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x06,
+                    (byte) 0x03, (byte) 0x05, (byte) 0x01, (byte) 0x05, (byte) 0x02,
+                    (byte) 0x05, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x04,
+                    (byte) 0x02, (byte) 0x04, (byte) 0x03, (byte) 0x03, (byte) 0x01,
+                    (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x02,
+                    (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x03,
+                });
+                // Wait until the server sends something.
+                byte[] scratch = new byte[8192];
+                @SuppressWarnings("unused")
+                int bytesRead = client.getInputStream().read(scratch);
+                // Write a bogus TLS alert:
+                // TLSv1.2 Record Layer: Alert (Level: Warning, Description:
+                // Protocol Version)
+                client.getOutputStream()
+                    .write(new byte[]{0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46});
+                // TLSv1.2 Record Layer: Alert (Level: Warning, Description:
+                // Close Notify)
+                client.getOutputStream()
+                    .write(new byte[]{0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00});
+                return null;
+            }
+        });
+        c.get(5, TimeUnit.SECONDS);
+        s.get(5, TimeUnit.SECONDS);
+        client.close();
+        server.close();
+        context.close();
+    }
+
+    @Test
+    public void test_SSLSocket_SSLv3Unsupported() throws Exception {
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        final SSLSocket client =
+                (SSLSocket) context.clientContext.getSocketFactory().createSocket();
+        // For app compatibility, SSLv3 is stripped out when setting only.
+        client.setEnabledProtocols(new String[] {"SSLv3"});
+        assertEquals(0, client.getEnabledProtocols().length);
+        try {
+            client.setEnabledProtocols(new String[] {"SSL"});
+            fail("SSLSocket should not support SSL protocol");
+        } catch (IllegalArgumentException expected) {
+            // Ignored.
+        }
+    }
+
+    // Under some circumstances, the file descriptor socket may get finalized but still
+    // be reused by the JDK's built-in HTTP connection reuse code.  Ensure that a
+    // SocketException is thrown if that happens.
+    @Test
+    public void test_SSLSocket_finalizeThrowsProperException() throws Exception {
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        TestSSLSocketPair test = TestSSLSocketPair.create(context).connect();
+        try {
+            if (isConscryptFdSocket(test.client)) {
+                // The finalize method might be declared on a superclass rather than this
+                // class.
+                Method method = null;
+                Class<?> clazz = test.client.getClass();
+                while (clazz != null) {
+                    try {
+                        method = clazz.getDeclaredMethod("finalize");
+                        break;
+                    } catch (NoSuchMethodException e) {
+                        // Try the superclass
+                    }
+                    clazz = clazz.getSuperclass();
+                }
+                assertNotNull(method);
+                method.setAccessible(true);
+                method.invoke(test.client);
+                try {
+                    test.client.getOutputStream().write(new byte[] { 0x01 });
+                    fail("The socket shouldn't work after being finalized");
+                } catch (SocketException expected) {
+                    // Expected
+                }
+            }
+        } finally {
+            test.close();
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_TlsUnique() throws Exception {
+        // tls_unique isn't supported in TLS 1.3
+        assumeTlsV1_2Connection();
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        TestSSLSocketPair pair = TestSSLSocketPair.create(context);
+        try {
+            assertNull(Conscrypt.getTlsUnique(pair.client));
+            assertNull(Conscrypt.getTlsUnique(pair.server));
+
+            pair.connect();
+
+            byte[] clientTlsUnique = Conscrypt.getTlsUnique(pair.client);
+            byte[] serverTlsUnique = Conscrypt.getTlsUnique(pair.server);
+            assertNotNull(clientTlsUnique);
+            assertNotNull(serverTlsUnique);
+            assertArrayEquals(clientTlsUnique, serverTlsUnique);
+        } finally {
+            pair.close();
+        }
+    }
+
+    // Tests that all cipher suites have a 12-byte tls-unique channel binding value.  If this
+    // test fails, that means some cipher suite has been added that uses a customized verify_data
+    // length and we need to update MAX_TLS_UNIQUE_LENGTH in native_crypto.cc to account for that.
+    @Test
+    public void test_SSLSocket_TlsUniqueLength() throws Exception {
+        // tls_unique isn't supported in TLS 1.3
+        assumeTlsV1_2Connection();
+        // note the rare usage of non-RSA keys
+        TestKeyStore testKeyStore = new TestKeyStore.Builder()
+                .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA")
+                .aliasPrefix("rsa-dsa-ec")
+                .ca(true)
+                .build();
+        KeyManager pskKeyManager =
+                PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy() {
+                    @Override
+                    protected SecretKey getKey(
+                            String identityHint, String identity, Socket socket) {
+                        return newKey();
+                    }
+
+                    @Override
+                    protected SecretKey getKey(
+                            String identityHint, String identity, SSLEngine engine) {
+                        return newKey();
+                    }
+
+                    private SecretKey newKey() {
+                        return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
+                    }
+                });
+        TestSSLContext c = TestSSLContext.newBuilder()
+                .client(testKeyStore)
+                .server(testKeyStore)
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .additionalClientKeyManagers(new KeyManager[] {pskKeyManager})
+                .additionalServerKeyManagers(new KeyManager[] {pskKeyManager})
+                .build();
+        for (String cipherSuite : c.clientContext.getSocketFactory().getSupportedCipherSuites()) {
+            if (cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)
+                    || cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) {
+                continue;
+            }
+            /*
+             * tls_unique only works on 1.2, so skip TLS 1.3 cipher suites.
+             */
+            if (StandardNames.CIPHER_SUITES_TLS13.contains(cipherSuite)) {
+                continue;
+            }
+            TestSSLSocketPair pair = TestSSLSocketPair.create(c);
+            try {
+                String[] cipherSuites =
+                        new String[] {cipherSuite, StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION};
+                pair.connect(cipherSuites, cipherSuites);
+
+                assertEquals(cipherSuite, pair.client.getSession().getCipherSuite());
+
+                byte[] clientTlsUnique = Conscrypt.getTlsUnique(pair.client);
+                byte[] serverTlsUnique = Conscrypt.getTlsUnique(pair.server);
+                assertNotNull(clientTlsUnique);
+                assertNotNull(serverTlsUnique);
+                assertArrayEquals(clientTlsUnique, serverTlsUnique);
+                assertEquals(12, clientTlsUnique.length);
+            } catch (Exception e) {
+                throw new AssertionError("Cipher suite is " + cipherSuite, e);
+            } finally {
+                pair.client.close();
+                pair.server.close();
+            }
+        }
+    }
+
+    @Test
+    public void test_SSLSocket_EKM() throws Exception {
+        TestSSLContext context = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        TestSSLSocketPair pair = TestSSLSocketPair.create(context);
+        try {
+            // No EKM values available before handshaking
+            assertNull(Conscrypt.exportKeyingMaterial(pair.client, "FOO", null, 20));
+            assertNull(Conscrypt.exportKeyingMaterial(pair.server, "FOO", null, 20));
+
+            pair.connect();
+
+            byte[] clientEkm = Conscrypt.exportKeyingMaterial(pair.client, "FOO", null, 20);
+            byte[] serverEkm = Conscrypt.exportKeyingMaterial(pair.server, "FOO", null, 20);
+            assertNotNull(clientEkm);
+            assertNotNull(serverEkm);
+            assertEquals(20, clientEkm.length);
+            assertEquals(20, serverEkm.length);
+            assertArrayEquals(clientEkm, serverEkm);
+
+            byte[] clientContextEkm = Conscrypt.exportKeyingMaterial(
+                    pair.client, "FOO", new byte[0], 20);
+            byte[] serverContextEkm = Conscrypt.exportKeyingMaterial(
+                    pair.server, "FOO", new byte[0], 20);
+            assertNotNull(clientContextEkm);
+            assertNotNull(serverContextEkm);
+            assertEquals(20, clientContextEkm.length);
+            assertEquals(20, serverContextEkm.length);
+            assertArrayEquals(clientContextEkm, serverContextEkm);
+
+            // In TLS 1.2, an empty context and a null context are different (RFC 5705, section 4),
+            // but in TLS 1.3 they are the same (RFC 8446, section 7.5).
+            if ("TLSv1.2".equals(negotiatedVersion())) {
+                assertFalse(Arrays.equals(clientEkm, clientContextEkm));
+            } else {
+                assertTrue(Arrays.equals(clientEkm, clientContextEkm));
+            }
+        } finally {
+            pair.close();
+        }
+    }
+
+    // Tests that a socket will close cleanly even if it fails to create due to an
+    // internal IOException
+    @Test
+    public void test_SSLSocket_CloseCleanlyOnConstructorFailure() throws Exception {
+        TestSSLContext c = new TestSSLContext.Builder()
+                .clientProtocol(clientVersion)
+                .serverProtocol(serverVersion)
+                .build();
+        try {
+            c.clientContext.getSocketFactory().createSocket(c.host, 1);
+            fail();
+        } catch (ConnectException ignored) {
+            // Ignored.
+        }
+    }
+
+    private static void setWriteTimeout(Object socket, int timeout) {
+        Exception ex = null;
+        try {
+            Method method = socket.getClass().getMethod("setSoWriteTimeout", int.class);
+            method.setAccessible(true);
+            method.invoke(socket, timeout);
+        } catch (Exception e) {
+            ex = e;
+        }
+        // Engine-based socket currently has the method but throws UnsupportedOperationException.
+        assumeNoException("Client socket does not support setting write timeout", ex);
+    }
+
+    private static void setHostname(SSLSocket socket) {
+        try {
+            Method method = socket.getClass().getMethod("setHostname", String.class);
+            method.setAccessible(true);
+            method.invoke(socket, "sslsockettest.androidcts.google.com");
+        } catch (NoSuchMethodException ignored) {
+            // Ignored.
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to enable SNI", e);
+        }
+    }
+
+    private static void enableSessionTickets(SSLSocket socket) {
+        try {
+            Method method =
+                    socket.getClass().getMethod("setUseSessionTickets", boolean.class);
+            method.setAccessible(true);
+            method.invoke(socket, true);
+        } catch (NoSuchMethodException ignored) {
+            // Ignored.
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to enable Session Tickets", e);
+        }
+    }
+
+    private static boolean isConscryptSocket(SSLSocket socket) {
+        return isConscryptFdSocket(socket) || isConscryptEngineSocket(socket);
+    }
+
+    private static boolean isConscryptFdSocket(SSLSocket socket) {
+        Class<?> clazz = socket.getClass();
+        while (clazz != Object.class && !"ConscryptFileDescriptorSocket".equals(clazz.getSimpleName())) {
+            clazz = clazz.getSuperclass();
+        }
+        return "ConscryptFileDescriptorSocket".equals(clazz.getSimpleName());
+    }
+
+    private static boolean isConscryptEngineSocket(SSLSocket socket) {
+        Class<?> clazz = socket.getClass();
+        while (clazz != Object.class && !"ConscryptEngineSocket".equals(clazz.getSimpleName())) {
+            clazz = clazz.getSuperclass();
+        }
+        return "ConscryptEngineSocket".equals(clazz.getSimpleName());
+    }
+
+    private static String osName() {
+        return System.getProperty("os.name").toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", "");
+    }
+
+    private static boolean isLinux() {
+        return osName().startsWith("linux");
+    }
+
+    private static boolean isWindows() {
+        return osName().startsWith("windows");
+    }
+
+    private static boolean isOsx() {
+        String name = osName();
+        return name.startsWith("macosx") || name.startsWith("osx");
+    }
+
+    private <T> Future<T> runAsync(Callable<T> callable) {
+        return executor.submit(callable);
+    }
+
+    private static SSLContext defaultInit(SSLContext context) throws KeyManagementException {
+        context.init(null, null, null);
+        return context;
+    }
+
+    // Assumes that the negotiated connection will be TLS 1.2
+    private void assumeTlsV1_2Connection() {
+        assumeTrue("TLSv1.2".equals(negotiatedVersion()));
+    }
+
+    /**
+     * Returns the version that a connection between {@code clientVersion} and
+     * {@code serverVersion} should produce.
+     */
+    private String negotiatedVersion() {
+        if (clientVersion.equals("TLSv1.3") && serverVersion.equals("TLSv1.3")) {
+            return "TLSv1.3";
+        } else {
+            return "TLSv1.2";
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/TrustManagerFactoryTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/TrustManagerFactoryTest.java
new file mode 100644
index 0000000..06ec3a2
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/TrustManagerFactoryTest.java
@@ -0,0 +1,320 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.org.conscrypt.Conscrypt;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.Provider;
+import java.security.cert.CertificateException;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXParameters;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import org.bouncycastle.asn1.x509.KeyPurposeId;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import tests.util.ServiceTester;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class TrustManagerFactoryTest {
+    private static final String[] KEY_TYPES = new String[] {"RSA", "DSA", "EC", "EC_RSA"};
+
+    private static TestKeyStore TEST_KEY_STORE;
+
+    // note the rare usage of DSA keys here in addition to RSA
+    private static TestKeyStore getTestKeyStore() throws Exception {
+        if (TEST_KEY_STORE == null) {
+            TEST_KEY_STORE = new TestKeyStore.Builder()
+                                     .keyAlgorithms(KEY_TYPES)
+                                     .aliasPrefix("rsa-dsa-ec")
+                                     .build();
+        }
+        return TEST_KEY_STORE;
+    }
+
+    private static boolean supportsManagerFactoryParameters(TrustManagerFactory tmf) {
+        return (StandardNames.IS_RI && tmf.getAlgorithm().equals("PKIX")
+            && !Conscrypt.isConscrypt(tmf.getProvider()));
+    }
+
+    @Test
+    public void test_TrustManagerFactory_getDefaultAlgorithm() throws Exception {
+        String algorithm = TrustManagerFactory.getDefaultAlgorithm();
+        assertEquals(StandardNames.TRUST_MANAGER_FACTORY_DEFAULT, algorithm);
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+        test_TrustManagerFactory(tmf);
+    }
+
+    private static class UselessManagerFactoryParameters implements ManagerFactoryParameters {}
+
+    private void test_TrustManagerFactory(TrustManagerFactory tmf) throws Exception {
+        assertNotNull(tmf);
+        assertNotNull(tmf.getAlgorithm());
+        assertNotNull(tmf.getProvider());
+
+        // before init
+        try {
+            tmf.getTrustManagers();
+            fail();
+        } catch (IllegalStateException expected) {
+            // Ignored.
+        }
+
+        // init with null ManagerFactoryParameters
+        try {
+            tmf.init((ManagerFactoryParameters) null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignored.
+        }
+
+        // init with useless ManagerFactoryParameters
+        try {
+            tmf.init(new UselessManagerFactoryParameters());
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignored.
+        }
+
+        // init with PKIXParameters ManagerFactoryParameters
+        try {
+            PKIXParameters pp = new PKIXParameters(getTestKeyStore().keyStore);
+            CertPathTrustManagerParameters cptmp = new CertPathTrustManagerParameters(pp);
+            tmf.init(cptmp);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {
+            // Ignored.
+        }
+
+        // init with PKIXBuilderParameters ManagerFactoryParameters
+        X509CertSelector xcs = new X509CertSelector();
+        PKIXBuilderParameters pbp = new PKIXBuilderParameters(getTestKeyStore().keyStore, xcs);
+        CertPathTrustManagerParameters cptmp = new CertPathTrustManagerParameters(pbp);
+        if (supportsManagerFactoryParameters(tmf)) {
+            tmf.init(cptmp);
+            test_TrustManagerFactory_getTrustManagers(tmf);
+        } else {
+            try {
+                tmf.init(cptmp);
+                fail();
+            } catch (InvalidAlgorithmParameterException expected) {
+                // Ignored.
+            }
+        }
+
+        // init with null for default KeyStore
+        tmf.init((KeyStore) null);
+        test_TrustManagerFactory_getTrustManagers(tmf);
+
+        // init with specific key store
+        tmf.init(getTestKeyStore().keyStore);
+        test_TrustManagerFactory_getTrustManagers(tmf);
+    }
+
+    private void test_TrustManagerFactory_getTrustManagers(TrustManagerFactory tmf)
+            throws Exception {
+        TrustManager[] trustManagers = tmf.getTrustManagers();
+        assertNotNull(trustManagers);
+        assertTrue(trustManagers.length > 0);
+        for (TrustManager trustManager : trustManagers) {
+            assertNotNull(trustManager);
+            if (trustManager instanceof X509TrustManager) {
+                test_X509TrustManager(tmf.getProvider(), (X509TrustManager) trustManager);
+            }
+        }
+    }
+
+    private void test_X509TrustManager(Provider p, X509TrustManager tm) throws Exception {
+        for (String keyType : KEY_TYPES) {
+            X509Certificate[] issuers = tm.getAcceptedIssuers();
+            assertNotNull(issuers);
+            assertTrue(issuers.length > 1);
+            assertNotSame(issuers, tm.getAcceptedIssuers());
+            boolean defaultTrustManager
+                    // RI de-duplicates certs from TrustedCertificateEntry and PrivateKeyEntry
+                    = issuers.length >
+                    (StandardNames.IS_RI && !Conscrypt.isConscrypt(p) ? 1 : 2) * KEY_TYPES.length;
+
+            String keyAlgName = TestKeyStore.keyAlgorithm(keyType);
+            String sigAlgName = TestKeyStore.signatureAlgorithm(keyType);
+            PrivateKeyEntry pke = getTestKeyStore().getPrivateKey(keyAlgName, sigAlgName);
+            X509Certificate[] chain = (X509Certificate[]) pke.getCertificateChain();
+            if (defaultTrustManager) {
+                try {
+                    tm.checkClientTrusted(chain, keyType);
+                    fail();
+                } catch (CertificateException expected) {
+                    // Ignored.
+                }
+                try {
+                    tm.checkServerTrusted(chain, keyType);
+                    fail();
+                } catch (CertificateException expected) {
+                    // Ignored.
+                }
+            } else {
+                tm.checkClientTrusted(chain, keyType);
+                tm.checkServerTrusted(chain, keyType);
+            }
+        }
+    }
+
+    @Test
+    public void test_TrustManagerFactory_getInstance() throws Exception {
+        ServiceTester.test("TrustManagerFactory").run(new ServiceTester.Test() {
+            @Override
+            public void test(Provider provider, String algorithm) throws Exception {
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+                assertEquals(algorithm, tmf.getAlgorithm());
+                test_TrustManagerFactory(tmf);
+
+                tmf = TrustManagerFactory.getInstance(algorithm, provider);
+                assertEquals(algorithm, tmf.getAlgorithm());
+                assertEquals(provider, tmf.getProvider());
+                test_TrustManagerFactory(tmf);
+
+                tmf = TrustManagerFactory.getInstance(algorithm, provider.getName());
+                assertEquals(algorithm, tmf.getAlgorithm());
+                assertEquals(provider, tmf.getProvider());
+                test_TrustManagerFactory(tmf);
+            }
+        });
+    }
+
+    @Test
+    public void test_TrustManagerFactory_intermediate() throws Exception {
+        // chain should be server/intermediate/root
+        PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+        final X509Certificate[] chain = (X509Certificate[]) pke.getCertificateChain();
+        assertEquals(3, chain.length);
+
+        // keyStore should contain only the intermediate CA so we can
+        // test proper validation even if there are extra certs after
+        // the trusted one (in this case the original root is "extra")
+        final KeyStore keyStore = TestKeyStore.createKeyStore();
+        keyStore.setCertificateEntry("alias", chain[1]);
+
+        ServiceTester.test("TrustManagerFactory").run(new ServiceTester.Test() {
+            @Override
+            public void test(Provider p, String algorithm) throws Exception {
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+                tmf.init(keyStore);
+                TrustManager[] trustManagers = tmf.getTrustManagers();
+                for (TrustManager trustManager : trustManagers) {
+                    if (!(trustManager instanceof X509TrustManager)) {
+                        continue;
+                    }
+                    X509TrustManager tm = (X509TrustManager) trustManager;
+                    tm.checkClientTrusted(chain, "RSA");
+                    tm.checkServerTrusted(chain, "RSA");
+                }
+            }
+        });
+    }
+
+    @Test
+    public void test_TrustManagerFactory_keyOnly() throws Exception {
+        // create a KeyStore containing only a private key with chain.
+        // unlike PKIXParameters(KeyStore), the cert chain of the key should be trusted.
+        KeyStore ks = TestKeyStore.createKeyStore();
+        KeyStore.PrivateKeyEntry pke = getTestKeyStore().getPrivateKey("RSA", "RSA");
+        ks.setKeyEntry("key", pke.getPrivateKey(), "pw".toCharArray(), pke.getCertificateChain());
+
+        String algorithm = TrustManagerFactory.getDefaultAlgorithm();
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
+        tmf.init(ks);
+        X509TrustManager trustManager = (X509TrustManager) tmf.getTrustManagers()[0];
+        trustManager.checkServerTrusted((X509Certificate[]) pke.getCertificateChain(), "RSA");
+    }
+
+    @Test
+    public void test_TrustManagerFactory_extendedKeyUsage() throws Exception {
+        // anyExtendedKeyUsage should work for client or server
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.anyExtendedKeyUsage, false, true, true);
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.anyExtendedKeyUsage, true, true, true);
+
+        // critical clientAuth should work for client
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_clientAuth, false, true, false);
+        test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_clientAuth, true, true, false);
+
+        // critical serverAuth should work for server
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_serverAuth, false, false, true);
+        test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId.id_kp_serverAuth, true, false, true);
+
+        // codeSigning should not work
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_codeSigning, false, false, false);
+        test_TrustManagerFactory_extendedKeyUsage(
+                KeyPurposeId.id_kp_codeSigning, true, false, false);
+    }
+
+    private void test_TrustManagerFactory_extendedKeyUsage(KeyPurposeId keyPurposeId,
+            boolean critical, boolean client, boolean server) throws Exception {
+        String algorithm = "RSA";
+        TestKeyStore intermediateCa = TestKeyStore.getIntermediateCa();
+        TestKeyStore leaf = new TestKeyStore.Builder()
+                                    .keyAlgorithms(algorithm)
+                                    .aliasPrefix("criticalCodeSigning")
+                                    .signer(intermediateCa.getPrivateKey("RSA", "RSA"))
+                                    .rootCa(intermediateCa.getRootCertificate("RSA"))
+                                    .addExtendedKeyUsage(keyPurposeId, critical)
+                                    .build();
+        // leaf.dump("test_TrustManagerFactory_criticalCodeSigning");
+        PrivateKeyEntry privateKeyEntry = leaf.getPrivateKey(algorithm, algorithm);
+        X509Certificate[] chain = (X509Certificate[]) privateKeyEntry.getCertificateChain();
+
+        TestKeyStore rootCa = TestKeyStore.getRootCa();
+        X509TrustManager trustManager = (X509TrustManager) rootCa.trustManagers[0];
+        try {
+            trustManager.checkClientTrusted(chain, algorithm);
+            assertTrue(client);
+        } catch (Exception e) {
+            assertFalse(client);
+        }
+        try {
+            trustManager.checkServerTrusted(chain, algorithm);
+            assertTrue(server);
+        } catch (Exception e) {
+            assertFalse(server);
+        }
+    }
+}
diff --git a/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/X509KeyManagerTest.java b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/X509KeyManagerTest.java
new file mode 100644
index 0000000..96a573d
--- /dev/null
+++ b/repackaged/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/javax/net/ssl/X509KeyManagerTest.java
@@ -0,0 +1,83 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2013 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.X509KeyManager;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class X509KeyManagerTest {
+    /**
+     * Tests whether the key manager will select the right key when the CA is of
+     * one key type and the client is of a possibly different key type.
+     *
+     * <p>There was a bug where EC was being interpreted as EC_EC and only
+     * accepting EC signatures when it should accept any signature type.
+     */
+    @Test
+    public void testChooseClientAlias_Combinations() throws Exception {
+        test_ChooseClientAlias_KeyType("RSA", "RSA", "RSA", true);
+        test_ChooseClientAlias_KeyType("RSA", "EC", "RSA", true);
+        test_ChooseClientAlias_KeyType("RSA", "EC", "EC", false);
+
+        test_ChooseClientAlias_KeyType("EC", "RSA", "EC_RSA", true);
+        test_ChooseClientAlias_KeyType("EC", "EC", "EC_RSA", false);
+
+        test_ChooseClientAlias_KeyType("EC", "EC", "EC_EC", true);
+        test_ChooseClientAlias_KeyType("EC", "RSA", "EC_EC", false);
+
+        test_ChooseClientAlias_KeyType("EC", "RSA", "RSA", false);
+    }
+
+    private void test_ChooseClientAlias_KeyType(String clientKeyType, String caKeyType,
+            String selectedKeyType, boolean succeeds) throws Exception {
+        TestKeyStore ca = new TestKeyStore.Builder().keyAlgorithms(caKeyType).build();
+        TestKeyStore client = new TestKeyStore.Builder()
+                                      .keyAlgorithms(clientKeyType)
+                                      .signer(ca.getPrivateKey(caKeyType, caKeyType))
+                                      .build();
+
+        KeyManagerFactory kmf =
+                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        kmf.init(client.keyStore, client.keyPassword);
+
+        String[] keyTypes = new String[] {selectedKeyType};
+        KeyManager[] managers = kmf.getKeyManagers();
+        for (KeyManager manager : managers) {
+            if (manager instanceof X509KeyManager) {
+                String alias = ((X509KeyManager) manager).chooseClientAlias(keyTypes, null, null);
+                if (succeeds) {
+                    assertNotNull(alias);
+                } else {
+                    assertNull(alias);
+                }
+            }
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/HostProperties.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/HostProperties.java
new file mode 100644
index 0000000..7adf930
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/HostProperties.java
@@ -0,0 +1,295 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2013 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.io.File;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Utilities for interacting with properties of the host being run on.
+ */
+@Internal
+class HostProperties {
+    private static final Logger logger = Logger.getLogger(HostProperties.class.getName());
+
+    private static final String TEMP_DIR_PROPERTY_NAME = "com.android.org.conscrypt.tmpdir";
+
+    static final OperatingSystem OS;
+    static final Architecture ARCH;
+
+    static {
+        OS = getOperatingSystem(System.getProperty("os.name", ""));
+        ARCH = getArchitecture(System.getProperty("os.arch", ""));
+    }
+
+    /**
+     * Enumeration of operating systems.
+     */
+    enum OperatingSystem {
+        AIX,
+        HPUX,
+        OS400,
+        LINUX,
+        OSX,
+        FREEBSD,
+        OPENBSD,
+        NETBSD,
+        SUNOS,
+        WINDOWS,
+        UNKNOWN;
+
+        /**
+         * Returns the value to use when building filenames for this OS.
+         */
+        public String getFileComponent() {
+            return name().toLowerCase();
+        }
+    }
+
+    /**
+     * Enumeration of architectures.
+     */
+    enum Architecture {
+        X86_64,
+        X86_32 {
+            @Override public String getFileComponent() {
+                return "x86";
+            }
+        },
+        ITANIUM_64,
+        SPARC_32,
+        SPARC_64,
+        ARM_32,
+        AARCH_64,
+        PPC_32,
+        PPC_64,
+        PPCLE_64,
+        S390_32,
+        S390_64,
+        UNKNOWN;
+
+        /**
+         * Returns the value to use when building filenames for this architecture.
+         */
+        public String getFileComponent() {
+            return name().toLowerCase();
+        }
+    }
+
+    static boolean isWindows() {
+        return OS == OperatingSystem.WINDOWS;
+    }
+
+    static boolean isOSX() {
+        return OS == OperatingSystem.OSX;
+    }
+
+    static File getTempDir() {
+        File f;
+        try {
+            // First, see if the application specified a temp dir for conscrypt.
+            f = toDirectory(System.getProperty(TEMP_DIR_PROPERTY_NAME));
+            if (f != null) {
+                return f;
+            }
+
+            // Use the Java system property if available.
+            f = toDirectory(System.getProperty("java.io.tmpdir"));
+            if (f != null) {
+                return f;
+            }
+
+            // This shouldn't happen, but just in case ..
+            if (isWindows()) {
+                f = toDirectory(System.getenv("TEMP"));
+                if (f != null) {
+                    return f;
+                }
+
+                String userprofile = System.getenv("USERPROFILE");
+                if (userprofile != null) {
+                    f = toDirectory(userprofile + "\\AppData\\Local\\Temp");
+                    if (f != null) {
+                        return f;
+                    }
+
+                    f = toDirectory(userprofile + "\\Local Settings\\Temp");
+                    if (f != null) {
+                        return f;
+                    }
+                }
+            } else {
+                f = toDirectory(System.getenv("TMPDIR"));
+                if (f != null) {
+                    return f;
+                }
+            }
+        } catch (Exception ignored) {
+            // Environment variable inaccessible
+        }
+
+        // Last resort.
+        if (isWindows()) {
+            f = new File("C:\\Windows\\Temp");
+        } else {
+            f = new File("/tmp");
+        }
+
+        logger.log(Level.WARNING,
+                "Failed to get the temporary directory; falling back to: {0}", f);
+        return f;
+    }
+
+    @SuppressWarnings("ResultOfMethodCallIgnored")
+    private static File toDirectory(String path) {
+        if (path == null) {
+            return null;
+        }
+
+        File f = new File(path);
+        f.mkdirs();
+
+        if (!f.isDirectory()) {
+            return null;
+        }
+
+        try {
+            return f.getAbsoluteFile();
+        } catch (Exception ignored) {
+            return f;
+        }
+    }
+
+    private static String normalize(String value) {
+        return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", "");
+    }
+
+    /**
+     * Normalizes the os.name value into the value used by the Maven os plugin
+     * (https://github.com/trustin/os-maven-plugin). This plugin is used to generate
+     * platform-specific
+     * classifiers for artifacts.
+     */
+    private static OperatingSystem getOperatingSystem(String value) {
+        value = normalize(value);
+        if (value.startsWith("aix")) {
+            return OperatingSystem.AIX;
+        }
+        if (value.startsWith("hpux")) {
+            return OperatingSystem.HPUX;
+        }
+        if (value.startsWith("os400")) {
+            // Avoid the names such as os4000
+            if (value.length() <= 5 || !Character.isDigit(value.charAt(5))) {
+                return OperatingSystem.OS400;
+            }
+        }
+        if (value.startsWith("linux")) {
+            return OperatingSystem.LINUX;
+        }
+        if (value.startsWith("macosx") || value.startsWith("osx")) {
+            return OperatingSystem.OSX;
+        }
+        if (value.startsWith("freebsd")) {
+            return OperatingSystem.FREEBSD;
+        }
+        if (value.startsWith("openbsd")) {
+            return OperatingSystem.OPENBSD;
+        }
+        if (value.startsWith("netbsd")) {
+            return OperatingSystem.NETBSD;
+        }
+        if (value.startsWith("solaris") || value.startsWith("sunos")) {
+            return OperatingSystem.SUNOS;
+        }
+        if (value.startsWith("windows")) {
+            return OperatingSystem.WINDOWS;
+        }
+
+        return OperatingSystem.UNKNOWN;
+    }
+
+    /**
+     * Normalizes the os.arch value into the value used by the Maven os plugin
+     * (https://github.com/trustin/os-maven-plugin). This plugin is used to generate
+     * platform-specific
+     * classifiers for artifacts.
+     */
+    private static Architecture getArchitecture(String value) {
+        value = normalize(value);
+        if (value.matches("^(x8664|amd64|ia32e|em64t|x64)$")) {
+            return Architecture.X86_64;
+        }
+        if (value.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) {
+            return Architecture.X86_32;
+        }
+        if (value.matches("^(ia64|itanium64)$")) {
+            return Architecture.ITANIUM_64;
+        }
+        if (value.matches("^(sparc|sparc32)$")) {
+            return Architecture.SPARC_32;
+        }
+        if (value.matches("^(sparcv9|sparc64)$")) {
+            return Architecture.SPARC_64;
+        }
+        if (value.matches("^(arm|arm32)$")) {
+            return Architecture.ARM_32;
+        }
+        if ("aarch64".equals(value)) {
+            return Architecture.AARCH_64;
+        }
+        if (value.matches("^(ppc|ppc32)$")) {
+            return Architecture.PPC_32;
+        }
+        if ("ppc64".equals(value)) {
+            return Architecture.PPC_64;
+        }
+        if ("ppc64le".equals(value)) {
+            return Architecture.PPCLE_64;
+        }
+        if ("s390".equals(value)) {
+            return Architecture.S390_32;
+        }
+        if ("s390x".equals(value)) {
+            return Architecture.S390_64;
+        }
+
+        return Architecture.UNKNOWN;
+    }
+
+    private HostProperties() {}
+
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Java8PlatformUtil.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Java8PlatformUtil.java
new file mode 100644
index 0000000..65d5d11
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Java8PlatformUtil.java
@@ -0,0 +1,98 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import static javax.net.ssl.StandardConstants.SNI_HOST_NAME;
+
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+
+/**
+ * Utility methods supported on Java 8+.
+ */
+final class Java8PlatformUtil {
+    static void setSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
+        impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
+        impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder());
+        List<SNIServerName> serverNames = params.getServerNames();
+
+        if (serverNames != null) {
+            for (SNIServerName serverName : serverNames) {
+                if (serverName.getType() == SNI_HOST_NAME) {
+                    socket.setHostname(((SNIHostName) serverName).getAsciiName());
+                    break;
+                }
+            }
+        }
+    }
+
+    static void getSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
+        params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
+        params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder());
+        if (impl.getUseSni() && AddressUtils.isValidSniHostname(socket.getHostname())) {
+            params.setServerNames(Collections.singletonList(
+                    (SNIServerName) new SNIHostName(socket.getHostname())));
+        }
+    }
+
+    static void setSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) {
+        impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
+        impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder());
+        List<SNIServerName> serverNames = params.getServerNames();
+
+        if (serverNames != null) {
+            for (SNIServerName serverName : serverNames) {
+                if (serverName.getType() == SNI_HOST_NAME) {
+                    engine.setHostname(((SNIHostName) serverName).getAsciiName());
+                    break;
+                }
+            }
+        }
+    }
+    static void getSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) {
+        params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
+        params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder());
+        if (impl.getUseSni() && AddressUtils.isValidSniHostname(engine.getHostname())) {
+            params.setServerNames(Collections.singletonList(
+                    (SNIServerName) new SNIHostName(engine.getHostname())));
+        }
+    }
+
+    static SSLEngine wrapEngine(ConscryptEngine engine) {
+        return new Java8EngineWrapper(engine);
+    }
+
+    static SSLEngine unwrapEngine(SSLEngine engine) {
+        return Java8EngineWrapper.getDelegate(engine);
+    }
+
+    static SSLSession wrapSSLSession(ExternalSession sslSession) {
+        return new Java8ExtendedSSLSession(sslSession);
+    }
+
+    private Java8PlatformUtil() {}
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Java9PlatformUtil.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Java9PlatformUtil.java
new file mode 100644
index 0000000..9141d06
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Java9PlatformUtil.java
@@ -0,0 +1,98 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.lang.reflect.Method;
+import javax.net.ssl.SSLParameters;
+
+/**
+ * Utility methods supported on Java 9+.
+ */
+final class Java9PlatformUtil {
+    // TODO(nmittler): Remove reflection once we require Java 9 for building.
+    private static final Method SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD;
+    private static final Method SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD;
+
+    static {
+        Class<?> sslParameters = SSLParameters.class;
+        Method getApplicationProtocolsMethod;
+        Method setApplicationProtocolsMethod;
+        try {
+            getApplicationProtocolsMethod = sslParameters.getMethod("getApplicationProtocols");
+            setApplicationProtocolsMethod =
+                    sslParameters.getMethod("setApplicationProtocols", String[].class);
+        } catch (NoSuchMethodException e) {
+            getApplicationProtocolsMethod = null;
+            setApplicationProtocolsMethod = null;
+        }
+
+        SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD = getApplicationProtocolsMethod;
+        SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD = setApplicationProtocolsMethod;
+    }
+
+    static void setSSLParameters(
+            SSLParameters src, SSLParametersImpl dest, AbstractConscryptSocket socket) {
+        Java8PlatformUtil.setSSLParameters(src, dest, socket);
+
+        dest.setApplicationProtocols(getApplicationProtocols(src));
+    }
+
+    static void getSSLParameters(
+            SSLParameters dest, SSLParametersImpl src, AbstractConscryptSocket socket) {
+        Java8PlatformUtil.getSSLParameters(dest, src, socket);
+
+        setApplicationProtocols(dest, src.getApplicationProtocols());
+    }
+
+    static void setSSLParameters(
+            SSLParameters src, SSLParametersImpl dest, ConscryptEngine engine) {
+        Java8PlatformUtil.setSSLParameters(src, dest, engine);
+
+        dest.setApplicationProtocols(getApplicationProtocols(src));
+    }
+
+    static void getSSLParameters(
+            SSLParameters dest, SSLParametersImpl src, ConscryptEngine engine) {
+        Java8PlatformUtil.getSSLParameters(dest, src, engine);
+
+        setApplicationProtocols(dest, src.getApplicationProtocols());
+    }
+
+    private static String[] getApplicationProtocols(SSLParameters params) {
+        if (SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD != null) {
+            try {
+                return (String[]) SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD.invoke(params);
+            } catch (ReflectiveOperationException ignored) {
+                // TODO(nmittler): Should we throw here?
+            }
+        }
+        return EmptyArray.STRING;
+    }
+
+    private static void setApplicationProtocols(SSLParameters params, String[] protocols) {
+        if (SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD != null) {
+            try {
+                SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD.invoke(params, (Object) protocols);
+            } catch (ReflectiveOperationException ignored) {
+                // TODO(nmittler): Should we throw here?
+            }
+        }
+    }
+
+    private Java9PlatformUtil() {}
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeCryptoJni.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeCryptoJni.java
new file mode 100644
index 0000000..4b8f045
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeCryptoJni.java
@@ -0,0 +1,129 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import com.android.org.conscrypt.NativeLibraryLoader.LoadResult;
+
+/**
+ * Helper to initialize the JNI libraries. This version runs when compiled as part of a host OpenJDK
+ * build.
+ */
+final class NativeCryptoJni {
+    private static final String STATIC_LIB_NAME = "conscrypt";
+    private static final String DYNAMIC_LIB_NAME_PREFIX = "conscrypt_openjdk_jni";
+
+    /**
+     * Attempts to load the shared JNI library. First try loading the platform-specific library
+     * name (e.g. conscrypt_openjdk_jni-linux-x86_64). If that doesn't work, try to load the
+     * library via just the prefix (e.g. conscrypt_openjdk_jni).  If not found, try the static
+     * library name.
+     *
+     * The non-suffixed dynamic library name is used by the Android build system, which builds
+     * the appropriate library for the system it's being run on under that name.
+     *
+     * The static library name is needed in order to support Java 8 static linking
+     * (http://openjdk.java.net/jeps/178), where the library name is used to invoke a
+     * library-specific load method (i.e. {@code JNI_OnLoad_conscrypt}).
+     *
+     * @throws UnsatisfiedLinkError if the library failed to load.
+     */
+    static void init() throws UnsatisfiedLinkError {
+        List<LoadResult> results = new ArrayList<LoadResult>();
+        if (!NativeLibraryLoader.loadFirstAvailable(classLoader(), results,
+                platformLibName(), DYNAMIC_LIB_NAME_PREFIX, STATIC_LIB_NAME)) {
+            logResults(results);
+            throwBestError(results);
+        }
+    }
+
+    private NativeCryptoJni() {}
+
+    private static void logResults(List<LoadResult> results) {
+        for (LoadResult result : results) {
+            result.log();
+        }
+    }
+
+    private static void throwBestError(List<LoadResult> results) {
+        Collections.sort(results, ErrorComparator.INSTANCE);
+
+        Throwable bestError = results.get(0).error;
+        for (LoadResult result : results.subList(1, results.size())) {
+            // Suppress all of the other errors, so that they're available to the caller if
+            // desired.
+            bestError.addSuppressed(result.error);
+        }
+
+        if (bestError instanceof Error) {
+            throw (Error) bestError;
+        }
+
+        throw (Error) new UnsatisfiedLinkError(bestError.getMessage()).initCause(bestError);
+    }
+
+    private static ClassLoader classLoader() {
+        return NativeCrypto.class.getClassLoader();
+    }
+
+    private static String platformLibName() {
+        return DYNAMIC_LIB_NAME_PREFIX + "-" + osName() + '-' + archName();
+    }
+
+    private static String osName() {
+        return HostProperties.OS.getFileComponent();
+    }
+
+    private static String archName() {
+        return HostProperties.ARCH.getFileComponent();
+    }
+
+    /**
+     * Sorts the errors in a list in descending order of value. After a list is sorted,
+     * the first element is the most important error.
+     */
+    private static final class ErrorComparator implements Comparator<LoadResult> {
+        static final ErrorComparator INSTANCE = new ErrorComparator();
+
+        @Override
+        public int compare(LoadResult o1, LoadResult o2) {
+            Throwable e1 = o1.error;
+            Throwable e2 = o2.error;
+
+            // First, sort by error type.
+            int value1 = e1 instanceof UnsatisfiedLinkError ? 1 : 0;
+            int value2 = e2 instanceof UnsatisfiedLinkError ? 1 : 0;
+            if (value1 != value2) {
+                // Order so that the UnsatisfiedLinkError is first.
+                return value2 - value1;
+            }
+
+            // Both are either link errors or not. Compare the message. Treat messages in
+            // the form "no <libName> in java.library.path" as lower value, since there may be
+            // a more interesting message for a library that was found.
+            String m1 = e1.getMessage();
+            String m2 = e2.getMessage();
+            value1 = m1 != null && m1.contains("java.library.path") ? 0 : 1;
+            value2 = m2 != null && m2.contains("java.library.path") ? 0 : 1;
+            return value2 - value1;
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeLibraryLoader.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeLibraryLoader.java
new file mode 100644
index 0000000..aa9c95f
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeLibraryLoader.java
@@ -0,0 +1,423 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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.
+ */
+
+/*
+ * Copyright 2014 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package com.android.org.conscrypt;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Helper class to load JNI resources.
+ */
+final class NativeLibraryLoader {
+    private static final Logger logger = Logger.getLogger(NativeLibraryLoader.class.getName());
+
+    private static final String WORK_DIR_PROPERTY_NAME = "com.android.org.conscrypt.native.workdir";
+    private static final String DELETE_LIB_PROPERTY_NAME =
+            "com.android.org.conscrypt.native.deleteLibAfterLoading";
+    private static final String NATIVE_RESOURCE_HOME = "META-INF/native/";
+    private static final File WORKDIR;
+    private static final boolean DELETE_NATIVE_LIB_AFTER_LOADING;
+
+    static {
+        File workdir = getWorkDir();
+        if (workdir == null) {
+            workdir = HostProperties.getTempDir();
+        }
+        WORKDIR = workdir;
+        log("-D{0}: {1}", WORK_DIR_PROPERTY_NAME, WORKDIR);
+
+        DELETE_NATIVE_LIB_AFTER_LOADING =
+                Boolean.valueOf(System.getProperty(DELETE_LIB_PROPERTY_NAME, "true"));
+    }
+
+    private static File getWorkDir() {
+        String dirName = System.getProperty(WORK_DIR_PROPERTY_NAME);
+        if (dirName == null) {
+            // Application didn't specify a workdir.
+            return null;
+        }
+
+        File f = new File(dirName);
+        // Create the directory if it doesn't already exist.
+        if (!f.mkdirs() && !f.exists()) {
+            // Unable to create the directory.
+            log("Unable to find or create working directory: {0}", dirName);
+            return null;
+        }
+
+        try {
+            f = f.getAbsoluteFile();
+        } catch (Exception ignored) {
+            // Good to have an absolute path, but it's OK.
+        }
+        return f;
+    }
+
+    /**
+     * Loads the first available library in the collection with the specified
+     * {@link ClassLoader}.
+     */
+    static boolean loadFirstAvailable(
+            ClassLoader loader, List<LoadResult> results, String... names) {
+        for (String name : names) {
+            if (load(name, loader, results)) {
+                // Successfully loaded
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * A result of a single attempt to load a library.
+     */
+    static final class LoadResult {
+        final String name;
+        final boolean absolute;
+        final boolean loaded;
+        final boolean usingHelperClassloader;
+        final Throwable error;
+
+        private static LoadResult newSuccessResult(
+                String name, boolean absolute, boolean usingHelperClassloader) {
+            return new LoadResult(name, absolute, true, usingHelperClassloader, null);
+        }
+
+        private static LoadResult newFailureResult(
+                String name, boolean absolute, boolean usingHelperClassloader, Throwable error) {
+            return new LoadResult(name, absolute, false, usingHelperClassloader, error);
+        }
+
+        private LoadResult(String name, boolean absolute, boolean loaded,
+                boolean usingHelperClassloader, Throwable error) {
+            this.name = name;
+            this.absolute = absolute;
+            this.loaded = loaded;
+            this.usingHelperClassloader = usingHelperClassloader;
+            this.error = error;
+        }
+
+        void log() {
+            if (error != null) {
+                NativeLibraryLoader.log(
+                        "Unable to load the library {0} (using helper classloader={1})", name,
+                        usingHelperClassloader, error);
+            } else {
+                NativeLibraryLoader.log(
+                        "Successfully loaded library {0}  (using helper classloader={1})", name,
+                        usingHelperClassloader);
+            }
+        }
+    }
+
+    /**
+     * Load the given library with the specified {@link ClassLoader}
+     */
+    private static boolean load(String name, ClassLoader loader, List<LoadResult> results) {
+        // Try loading from the fully-qualified classpath resource first. Otherwise just try
+        // loading the non-absolute library name directly.
+        return loadFromWorkdir(name, loader, results) || loadLibrary(loader, name, false, results);
+    }
+
+    private static boolean loadFromWorkdir(
+            String name, ClassLoader loader, List<LoadResult> results) {
+        String libname = System.mapLibraryName(name);
+        String path = NATIVE_RESOURCE_HOME + libname;
+
+        URL url = loader.getResource(path);
+        if (url == null && HostProperties.isOSX()) {
+            if (path.endsWith(".jnilib")) {
+                url = loader.getResource(NATIVE_RESOURCE_HOME + "lib" + name + ".dynlib");
+            } else {
+                url = loader.getResource(NATIVE_RESOURCE_HOME + "lib" + name + ".jnilib");
+            }
+        }
+
+        if (url == null) {
+            return false;
+        }
+
+        int index = libname.lastIndexOf('.');
+        String prefix = libname.substring(0, index);
+        String suffix = libname.substring(index, libname.length());
+        File tmpFile = null;
+        try {
+            // Create a temporary file.
+            tmpFile = Platform.createTempFile(prefix, suffix, WORKDIR);
+            if (tmpFile.isFile() && tmpFile.canRead() && !Platform.canExecuteExecutable(tmpFile)) {
+                throw new IOException(MessageFormat.format("{0} exists but cannot be executed even "
+                                + "when execute permissions set; check volume for "
+                                + "\"noexec\" flag; use -D{1}=[path] to set native "
+                                + "working directory separately.",
+                        tmpFile.getPath(), WORK_DIR_PROPERTY_NAME));
+            }
+
+            // Copy the library from classpath to tmpFile
+            copyLibrary(url, tmpFile);
+
+            return loadLibrary(loader, tmpFile.getPath(), true, results);
+        } catch (IOException e) {
+            // Convert to an UnsatisfiedLinkError.
+            Throwable error = new UnsatisfiedLinkError(
+                    MessageFormat.format("Failed creating temp file ({0})",
+                            tmpFile)).initCause(e);
+            results.add(LoadResult.newFailureResult(name, true, false, error));
+            return false;
+        } finally {
+            // After we load the library it is safe to delete the file.
+            // We delete the file immediately to free up resources as soon as possible,
+            // and if this fails fallback to deleting on JVM exit.
+            if (tmpFile != null) {
+                boolean deleted = false;
+                if (DELETE_NATIVE_LIB_AFTER_LOADING) {
+                    deleted = tmpFile.delete();
+                }
+                if (!deleted) {
+                    tmpFile.deleteOnExit();
+                }
+            }
+        }
+    }
+
+    /**
+     * Copies the given shared library file from classpath to a temporary file.
+     *
+     * @param classpathUrl the URL of the library on classpath
+     * @param tmpFile the destination temporary file.
+     */
+    private static void copyLibrary(URL classpathUrl, File tmpFile) throws IOException {
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = classpathUrl.openStream();
+            out = new FileOutputStream(tmpFile);
+
+            byte[] buffer = new byte[8192];
+            int length;
+            while ((length = in.read(buffer)) > 0) {
+                out.write(buffer, 0, length);
+            }
+            out.flush();
+        } finally {
+            closeQuietly(in);
+            closeQuietly(out);
+        }
+    }
+
+    /**
+     * Loading the native library into the specified {@link ClassLoader}.
+     * @param loader - The {@link ClassLoader} where the native library will be loaded into
+     * @param name - The native library path or name
+     * @param absolute - Whether the native library will be loaded by path or by name
+     * @return {@code true} if the library was successfully loaded.
+     */
+    private static boolean loadLibrary(final ClassLoader loader, final String name,
+            final boolean absolute, List<LoadResult> results) {
+        try {
+            // Make sure the helper belongs to the target ClassLoader.
+            final Class<?> newHelper = tryToLoadClass(loader, NativeLibraryUtil.class);
+            LoadResult result = loadLibraryFromHelperClassloader(newHelper, name, absolute);
+            results.add(result);
+            if (result.loaded) {
+                // Successfully loaded the library.
+                return true;
+            }
+        } catch (Exception ignore) {
+            // Failed loading the helper in the provided classloader - ignore.
+        }
+
+        // Fallback to loading from the local classloader.
+        LoadResult result = loadLibraryFromCurrentClassloader(name, absolute);
+        results.add(result);
+        return result.loaded;
+    }
+
+    /**
+     * Attempts to load the library by reflectively using the {@link NativeLibraryUtil} helper
+     * from its classloader.
+     *
+     * @param helper The {@link NativeLibraryUtil} helper class
+     * @param name the name of the library to load.
+     * @param absolute true if {@code name} is an absolute path to the file.
+     * @return the result of the load operation.
+     */
+    private static LoadResult loadLibraryFromHelperClassloader(
+            final Class<?> helper, final String name, final boolean absolute) {
+        return AccessController.doPrivileged(new PrivilegedAction<LoadResult>() {
+            @Override
+            public LoadResult run() {
+                try {
+                    // Invoke the helper to load the native library, if succeed, then the native
+                    // library belongs to the specified ClassLoader.
+                    Method method = helper.getMethod("loadLibrary", String.class, boolean.class);
+                    method.setAccessible(true);
+                    method.invoke(null, name, absolute);
+                    return LoadResult.newSuccessResult(name, absolute, true);
+                } catch (InvocationTargetException e) {
+                    return LoadResult.newFailureResult(name, absolute, true, e.getCause());
+                } catch (Throwable e) {
+                    return LoadResult.newFailureResult(name, absolute, true, e);
+                }
+            }
+        });
+    }
+
+    /**
+     * Attempts to load the library using the {@link NativeLibraryUtil} helper from the current
+     * classloader.
+     *
+     * @param name the name of the library to load.
+     * @param absolute true if {@code name} is an absolute path
+     * @return the result of the load operation.
+     */
+    private static LoadResult loadLibraryFromCurrentClassloader(String name, boolean absolute) {
+        try {
+            NativeLibraryUtil.loadLibrary(name, absolute);
+            return LoadResult.newSuccessResult(name, absolute, false);
+        } catch (Throwable e) {
+            return LoadResult.newFailureResult(name, absolute, false, e);
+        }
+    }
+
+    /**
+     * Try to load the helper {@link Class} into specified {@link ClassLoader}.
+     * @param loader - The {@link ClassLoader} where to load the helper {@link Class}
+     * @param helper - The helper {@link Class}
+     * @return A new helper Class defined in the specified ClassLoader.
+     * @throws ClassNotFoundException Helper class not found or loading failed
+     */
+    private static Class<?> tryToLoadClass(final ClassLoader loader, final Class<?> helper)
+            throws ClassNotFoundException {
+        try {
+            return loader.loadClass(helper.getName());
+        } catch (ClassNotFoundException e) {
+            // The helper class is NOT found in target ClassLoader, we have to define the helper
+            // class.
+            final byte[] classBinary = classToByteArray(helper);
+            return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                @Override
+                public Class<?> run() {
+                    try {
+                        // Define the helper class in the target ClassLoader,
+                        //  then we can call the helper to load the native library.
+                        Method defineClass = ClassLoader.class.getDeclaredMethod(
+                                "defineClass", String.class, byte[].class, int.class, int.class);
+                        defineClass.setAccessible(true);
+                        return (Class<?>) defineClass.invoke(
+                                loader, helper.getName(), classBinary, 0, classBinary.length);
+                    } catch (Exception e) {
+                        throw new IllegalStateException("Define class failed!", e);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Load the helper {@link Class} as a byte array, to be redefined in specified {@link
+     * ClassLoader}.
+     * @param clazz - The helper {@link Class} provided by this bundle
+     * @return The binary content of helper {@link Class}.
+     * @throws ClassNotFoundException Helper class not found or loading failed
+     */
+    private static byte[] classToByteArray(Class<?> clazz) throws ClassNotFoundException {
+        String fileName = clazz.getName();
+        int lastDot = fileName.lastIndexOf('.');
+        if (lastDot > 0) {
+            fileName = fileName.substring(lastDot + 1);
+        }
+        URL classUrl = clazz.getResource(fileName + ".class");
+        if (classUrl == null) {
+            throw new ClassNotFoundException(clazz.getName());
+        }
+        byte[] buf = new byte[1024];
+        ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+        InputStream in = null;
+        try {
+            in = classUrl.openStream();
+            for (int r; (r = in.read(buf)) != -1;) {
+                out.write(buf, 0, r);
+            }
+            return out.toByteArray();
+        } catch (IOException ex) {
+            throw new ClassNotFoundException(clazz.getName(), ex);
+        } finally {
+            closeQuietly(in);
+            closeQuietly(out);
+        }
+    }
+
+    private static void closeQuietly(Closeable c) {
+        if (c != null) {
+            try {
+                c.close();
+            } catch (IOException ignore) {
+                // ignore
+            }
+        }
+    }
+
+    private NativeLibraryLoader() {
+        // Utility
+    }
+
+    private static void log(String format, Object arg) {
+        logger.log(Level.FINE, format, arg);
+    }
+
+    private static void log(String format, Object arg1, Object arg2) {
+        logger.log(Level.FINE, format, new Object[] {arg1, arg2});
+    }
+
+    private static void log(String format, Object arg1, Object arg2, Throwable t) {
+        debug(MessageFormat.format(format, arg1, arg2), t);
+    }
+
+    private static void debug(String message, Throwable t) {
+        logger.log(Level.FINE, message, t);
+    }
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeLibraryUtil.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeLibraryUtil.java
new file mode 100644
index 0000000..2ebf789
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/NativeLibraryUtil.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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.
+ */
+
+/*
+ * Copyright 2017 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package com.android.org.conscrypt;
+
+/**
+ * A Utility to Call the {@link System#load(String)} or {@link System#loadLibrary(String)}.
+ * Because the {@link System#load(String)} and {@link System#loadLibrary(String)} are both
+ * CallerSensitive, it will load the native library into its caller's {@link ClassLoader}.
+ * In OSGi environment, we need this helper to delegate the calling to {@link System#load(String)}
+ * and it should be as simple as possible. It will be injected into the native library's
+ * ClassLoader when it is undefined. And therefore, when the defined new helper is invoked,
+ * the native library would be loaded into the native library's ClassLoader, not the
+ * caller's ClassLoader.
+ */
+final class NativeLibraryUtil {
+    /**
+     * Delegate the calling to {@link System#load(String)} or {@link System#loadLibrary(String)}.
+     * @param libName - The native library path or name
+     * @param absolute - Whether the native library will be loaded by path or by name
+     */
+    public static void loadLibrary(String libName, boolean absolute) {
+        if (absolute) {
+            System.load(libName);
+        } else {
+            System.loadLibrary(libName);
+        }
+    }
+
+    private NativeLibraryUtil() {}
+}
diff --git a/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java
new file mode 100644
index 0000000..7916ee0
--- /dev/null
+++ b/repackaged/openjdk/src/main/java/com/android/org/conscrypt/Platform.java
@@ -0,0 +1,782 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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.
+ */
+
+/*
+ * Copyright 2013 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import static java.nio.file.attribute.PosixFilePermission.GROUP_EXECUTE;
+import static java.nio.file.attribute.PosixFilePermission.OTHERS_EXECUTE;
+import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.nio.channels.SocketChannel;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.security.AccessController;
+import java.security.AlgorithmParameters;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedTrustManager;
+import javax.net.ssl.X509TrustManager;
+import com.android.org.conscrypt.ct.CTLogStore;
+import com.android.org.conscrypt.ct.CTPolicy;
+import sun.security.x509.AlgorithmId;
+
+/**
+ * Platform-specific methods for OpenJDK.
+ *
+ * Uses reflection to implement Java 8 SSL features for backwards compatibility.
+ */
+final class Platform {
+    private static final int JAVA_VERSION = javaVersion0();
+    private static final Method GET_CURVE_NAME_METHOD;
+
+    static {
+
+        Method getCurveNameMethod = null;
+        try {
+            getCurveNameMethod = ECParameterSpec.class.getDeclaredMethod("getCurveName");
+            getCurveNameMethod.setAccessible(true);
+        } catch (Exception ignored) {
+        }
+        GET_CURVE_NAME_METHOD = getCurveNameMethod;
+    }
+
+    private Platform() {}
+
+    static void setup() {}
+
+
+    /**
+     * Approximates the behavior of File.createTempFile without depending on SecureRandom.
+     */
+    static File createTempFile(String prefix, String suffix, File directory)
+        throws IOException {
+        if (directory == null) {
+            throw new NullPointerException();
+        }
+        long time = System.currentTimeMillis();
+        prefix = new File(prefix).getName();
+        IOException suppressed = null;
+        for (int i = 0; i < 10000; i++) {
+            String tempName = String.format(Locale.US, "%s%d%04d%s", prefix, time, i, suffix);
+            File tempFile = new File(directory, tempName);
+            if (!tempName.equals(tempFile.getName())) {
+                // The given prefix or suffix contains path separators.
+                throw new IOException("Unable to create temporary file: " + tempFile);
+            }
+            try {
+                if (tempFile.createNewFile()) {
+                    return tempFile.getCanonicalFile();
+                }
+            } catch (IOException e) {
+                // This may just be a transient error; store it just in case.
+                suppressed = e;
+            }
+        }
+        if (suppressed != null) {
+            throw suppressed;
+        } else {
+            throw new IOException("Unable to create temporary file");
+        }
+    }
+
+    /**
+     * Default name used in the {@link java.security.Security JCE system} by {@code OpenSSLProvider}
+     * if the default constructor is used.
+     */
+    static String getDefaultProviderName() {
+        return "Conscrypt";
+    }
+
+    static boolean provideTrustManagerByDefault() {
+        return true;
+    }
+
+    static boolean canExecuteExecutable(File file) throws IOException {
+        // If we can already execute, there is nothing to do.
+        if (file.canExecute()) {
+            return true;
+        }
+
+        // On volumes, with noexec set, even files with the executable POSIX permissions will
+        // fail to execute. The File#canExecute() method honors this behavior, probably via
+        // parsing the noexec flag when initializing the UnixFileStore, though the flag is not
+        // exposed via a public API.  To find out if library is being loaded off a volume with
+        // noexec, confirm or add executable permissions, then check File#canExecute().
+
+        Set<PosixFilePermission> existingFilePermissions =
+                Files.getPosixFilePermissions(file.toPath());
+        Set<PosixFilePermission> executePermissions =
+                EnumSet.of(OWNER_EXECUTE, GROUP_EXECUTE, OTHERS_EXECUTE);
+        if (existingFilePermissions.containsAll(executePermissions)) {
+            return false;
+        }
+
+        Set<PosixFilePermission> newPermissions = EnumSet.copyOf(existingFilePermissions);
+        newPermissions.addAll(executePermissions);
+        Files.setPosixFilePermissions(file.toPath(), newPermissions);
+        return file.canExecute();
+    }
+
+    static FileDescriptor getFileDescriptor(Socket s) {
+        try {
+            SocketChannel channel = s.getChannel();
+            if (channel != null) {
+                Field f_fd = channel.getClass().getDeclaredField("fd");
+                f_fd.setAccessible(true);
+                return (FileDescriptor) f_fd.get(channel);
+            }
+        } catch (Exception e) {
+            // Try socket class below...
+        }
+
+        try {
+            Field f_impl = Socket.class.getDeclaredField("impl");
+            f_impl.setAccessible(true);
+            Object socketImpl = f_impl.get(s);
+            Field f_fd = SocketImpl.class.getDeclaredField("fd");
+            f_fd.setAccessible(true);
+            return (FileDescriptor) f_fd.get(socketImpl);
+        } catch (Exception e) {
+            throw new RuntimeException("Can't get FileDescriptor from socket", e);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static FileDescriptor getFileDescriptorFromSSLSocket(AbstractConscryptSocket socket) {
+        return getFileDescriptor(socket);
+    }
+
+    @SuppressWarnings("unused")
+    static String getCurveName(ECParameterSpec spec) {
+        if (GET_CURVE_NAME_METHOD != null) {
+            try {
+                return (String) GET_CURVE_NAME_METHOD.invoke(spec);
+            } catch (Exception ignored) {
+                // Ignored
+            }
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    static void setCurveName(@SuppressWarnings("unused") ECParameterSpec spec,
+            @SuppressWarnings("unused") String curveName) {
+        // This doesn't appear to be needed.
+    }
+
+    @SuppressWarnings("unused")
+    static void setSocketWriteTimeout(@SuppressWarnings("unused") Socket s,
+            @SuppressWarnings("unused") long timeoutMillis) throws SocketException {
+        // TODO: figure this out on the RI
+    }
+
+    static void setSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
+        if (JAVA_VERSION >= 9) {
+            Java9PlatformUtil.setSSLParameters(params, impl, socket);
+        } else if (JAVA_VERSION >= 8) {
+            Java8PlatformUtil.setSSLParameters(params, impl, socket);
+        } else {
+            impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
+        }
+    }
+
+    static void getSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
+        if (JAVA_VERSION >= 9) {
+            Java9PlatformUtil.getSSLParameters(params, impl, socket);
+        } else if (JAVA_VERSION >= 8) {
+            Java8PlatformUtil.getSSLParameters(params, impl, socket);
+        } else {
+            params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
+        }
+    }
+
+    static void setSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) {
+        if (JAVA_VERSION >= 9) {
+            Java9PlatformUtil.setSSLParameters(params, impl, engine);
+        } else if (JAVA_VERSION >= 8) {
+            Java8PlatformUtil.setSSLParameters(params, impl, engine);
+        } else {
+            impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
+        }
+    }
+
+    static void getSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) {
+        if (JAVA_VERSION >= 9) {
+            Java9PlatformUtil.getSSLParameters(params, impl, engine);
+        } else if (JAVA_VERSION >= 8) {
+            Java8PlatformUtil.getSSLParameters(params, impl, engine);
+        } else {
+            params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static void setEndpointIdentificationAlgorithm(
+            SSLParameters params, String endpointIdentificationAlgorithm) {
+        params.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm);
+    }
+
+    @SuppressWarnings("unused")
+    static String getEndpointIdentificationAlgorithm(SSLParameters params) {
+        return params.getEndpointIdentificationAlgorithm();
+    }
+
+    @SuppressWarnings("unused")
+    static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            AbstractConscryptSocket socket) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkClientTrusted(chain, authType, socket);
+        } else {
+            tm.checkClientTrusted(chain, authType);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            AbstractConscryptSocket socket) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkServerTrusted(chain, authType, socket);
+        } else {
+            tm.checkServerTrusted(chain, authType);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            ConscryptEngine engine) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkClientTrusted(chain, authType, engine);
+        } else {
+            tm.checkClientTrusted(chain, authType);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            ConscryptEngine engine) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkServerTrusted(chain, authType, engine);
+        } else {
+            tm.checkServerTrusted(chain, authType);
+        }
+    }
+
+    /**
+     * Wraps an old AndroidOpenSSL key instance. This is not needed on RI.
+     */
+    @SuppressWarnings("unused")
+    static OpenSSLKey wrapRsaKey(@SuppressWarnings("unused") PrivateKey javaKey) {
+        return null;
+    }
+
+    /**
+     * Logs to the system EventLog system.
+     */
+    @SuppressWarnings("unused")
+    static void logEvent(@SuppressWarnings("unused") String message) {}
+
+    /**
+     * For unbundled versions, SNI is always enabled by default.
+     */
+    @SuppressWarnings("unused")
+    static boolean isSniEnabledByDefault() {
+        return true;
+    }
+
+    static SSLEngine wrapEngine(ConscryptEngine engine) {
+        if (JAVA_VERSION >= 8) {
+            return Java8PlatformUtil.wrapEngine(engine);
+        }
+        return engine;
+    }
+
+    static SSLEngine unwrapEngine(SSLEngine engine) {
+        if (JAVA_VERSION >= 8) {
+            return Java8PlatformUtil.unwrapEngine(engine);
+        }
+        return engine;
+    }
+
+    static ConscryptEngineSocket createEngineSocket(SSLParametersImpl sslParameters)
+            throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8EngineSocket(sslParameters);
+        }
+        return new ConscryptEngineSocket(sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(String hostname, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8EngineSocket(hostname, port, sslParameters);
+        }
+        return new ConscryptEngineSocket(hostname, port, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(InetAddress address, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8EngineSocket(address, port, sslParameters);
+        }
+        return new ConscryptEngineSocket(address, port, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(String hostname, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8EngineSocket(hostname, port, clientAddress, clientPort, sslParameters);
+        }
+        return new ConscryptEngineSocket(hostname, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(InetAddress address, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8EngineSocket(address, port, clientAddress, clientPort, sslParameters);
+        }
+        return new ConscryptEngineSocket(address, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(Socket socket, String hostname, int port,
+            boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8EngineSocket(socket, hostname, port, autoClose, sslParameters);
+        }
+        return new ConscryptEngineSocket(socket, hostname, port, autoClose, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(SSLParametersImpl sslParameters)
+            throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8FileDescriptorSocket(sslParameters);
+        }
+        return new ConscryptFileDescriptorSocket(sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(String hostname, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8FileDescriptorSocket(hostname, port, sslParameters);
+        }
+        return new ConscryptFileDescriptorSocket(hostname, port, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(InetAddress address, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8FileDescriptorSocket(address, port, sslParameters);
+        }
+        return new ConscryptFileDescriptorSocket(address, port, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(String hostname, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8FileDescriptorSocket(
+                    hostname, port, clientAddress, clientPort, sslParameters);
+        }
+        return new ConscryptFileDescriptorSocket(
+                hostname, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(InetAddress address, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8FileDescriptorSocket(
+                    address, port, clientAddress, clientPort, sslParameters);
+        }
+        return new ConscryptFileDescriptorSocket(
+                address, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(Socket socket, String hostname,
+            int port, boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
+        if (JAVA_VERSION >= 8) {
+            return new Java8FileDescriptorSocket(socket, hostname, port, autoClose, sslParameters);
+        }
+        return new ConscryptFileDescriptorSocket(socket, hostname, port, autoClose, sslParameters);
+    }
+
+    /**
+     * Currently we don't wrap anything from the RI.
+     */
+    @SuppressWarnings("unused")
+    static SSLSocketFactory wrapSocketFactoryIfNeeded(OpenSSLSocketFactoryImpl factory) {
+        return factory;
+    }
+
+    /**
+     * Convert from platform's GCMParameterSpec to our internal version.
+     */
+    @SuppressWarnings("unused")
+    static GCMParameters fromGCMParameterSpec(AlgorithmParameterSpec params) {
+        if (params instanceof GCMParameterSpec) {
+            GCMParameterSpec gcmParams = (GCMParameterSpec) params;
+            return new GCMParameters(gcmParams.getTLen(), gcmParams.getIV());
+        }
+        return null;
+    }
+
+    /**
+     * Convert from an opaque AlgorithmParameters to the platform's GCMParameterSpec.
+     */
+    static AlgorithmParameterSpec fromGCMParameters(AlgorithmParameters params) {
+        try {
+            return params.getParameterSpec(GCMParameterSpec.class);
+        } catch (InvalidParameterSpecException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Creates a platform version of {@code GCMParameterSpec}.
+     */
+    @SuppressWarnings("unused")
+    static AlgorithmParameterSpec toGCMParameterSpec(int tagLenInBits, byte[] iv) {
+        return new GCMParameterSpec(tagLenInBits, iv);
+    }
+
+    /*
+     * CloseGuard functions.
+     */
+
+    @SuppressWarnings("unused")
+    static Object closeGuardGet() {
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    static void closeGuardOpen(@SuppressWarnings("unused") Object guardObj,
+            @SuppressWarnings("unused") String message) {}
+
+    @SuppressWarnings("unused")
+    static void closeGuardClose(@SuppressWarnings("unused") Object guardObj) {}
+
+    @SuppressWarnings("unused")
+    static void closeGuardWarnIfOpen(@SuppressWarnings("unused") Object guardObj) {}
+
+    /*
+     * BlockGuard functions.
+     */
+
+    @SuppressWarnings("unused")
+    static void blockGuardOnNetwork() {}
+
+    /**
+     * OID to Algorithm Name mapping.
+     */
+    @SuppressWarnings("unused")
+    static String oidToAlgorithmName(String oid) {
+        try {
+            return AlgorithmId.get(oid).getName();
+        } catch (Exception e) {
+            return oid;
+        } catch (IllegalAccessError e) {
+            // This can happen under JPMS because AlgorithmId isn't exported by java.base
+            return oid;
+        }
+    }
+
+    /*
+     * Pre-Java-8 backward compatibility.
+     */
+
+    @SuppressWarnings("unused")
+    static SSLSession wrapSSLSession(ExternalSession sslSession) {
+        if (JAVA_VERSION >= 8) {
+            return Java8PlatformUtil.wrapSSLSession(sslSession);
+        }
+        return new Java7ExtendedSSLSession(sslSession);
+    }
+
+    public static String getOriginalHostNameFromInetAddress(InetAddress addr) {
+        try {
+            Method getHolder = InetAddress.class.getDeclaredMethod("holder");
+            getHolder.setAccessible(true);
+
+            Method getOriginalHostName = Class.forName("java.net.InetAddress$InetAddressHolder")
+                                                 .getDeclaredMethod("getOriginalHostName");
+            getOriginalHostName.setAccessible(true);
+
+            String originalHostName = (String) getOriginalHostName.invoke(getHolder.invoke(addr));
+            if (originalHostName == null) {
+                return addr.getHostAddress();
+            }
+            return originalHostName;
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Failed to get originalHostName", e);
+        } catch (ClassNotFoundException ignore) {
+            // passthrough and return addr.getHostAddress()
+        } catch (IllegalAccessException ignore) {
+        } catch (NoSuchMethodException ignore) {
+        }
+
+        return addr.getHostAddress();
+    }
+
+    @SuppressWarnings("unused")
+    static String getHostStringFromInetSocketAddress(InetSocketAddress addr) {
+        return addr.getHostString();
+    }
+
+    // OpenJDK always has X509ExtendedTrustManager
+    static boolean supportsX509ExtendedTrustManager() {
+        return true;
+    }
+
+    /**
+     * Check if SCT verification is required for a given hostname.
+     *
+     * SCT Verification is enabled using {@code Security} properties.
+     * The "conscrypt.ct.enable" property must be true, as well as a per domain property.
+     * The reverse notation of the domain name, prefixed with "conscrypt.ct.enforce."
+     * is used as the property name.
+     * Basic globbing is also supported.
+     *
+     * For example, for the domain foo.bar.com, the following properties will be
+     * looked up, in order of precedence.
+     * - conscrypt.ct.enforce.com.bar.foo
+     * - conscrypt.ct.enforce.com.bar.*
+     * - conscrypt.ct.enforce.com.*
+     * - conscrypt.ct.enforce.*
+     */
+    static boolean isCTVerificationRequired(String hostname) {
+        if (hostname == null) {
+            return false;
+        }
+
+        String property = Security.getProperty("conscrypt.ct.enable");
+        if (property == null || !Boolean.valueOf(property.toLowerCase())) {
+            return false;
+        }
+
+        List<String> parts = Arrays.asList(hostname.split("\\."));
+        Collections.reverse(parts);
+
+        boolean enable = false;
+        StringBuilder propertyName = new StringBuilder("conscrypt.ct.enforce");
+        // The loop keeps going on even once we've found a match
+        // This allows for finer grained settings on subdomains
+        for (String part : parts) {
+            property = Security.getProperty(propertyName + ".*");
+            if (property != null) {
+                enable = Boolean.valueOf(property.toLowerCase());
+            }
+
+            propertyName.append(".").append(part);
+        }
+
+        property = Security.getProperty(propertyName.toString());
+        if (property != null) {
+            enable = Boolean.valueOf(property.toLowerCase());
+        }
+        return enable;
+    }
+
+    static boolean supportsConscryptCertStore() {
+        return false;
+    }
+
+    static KeyStore getDefaultCertKeyStore() throws KeyStoreException {
+        // Start with an empty KeyStore.  In the worst case, we'll end up returning it.
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        try {
+            ks.load(null, null);
+        } catch (CertificateException ignored) {
+        } catch (NoSuchAlgorithmException ignored) {
+        } catch (IOException ignored) {
+            // We're not loading anything, so ignore it
+        }
+        // Find the highest-priority non-Conscrypt provider that provides a PKIX
+        // TrustManagerFactory implementation and ask it for its trusted CAs.  This is most
+        // likely the OpenJDK-provided provider, in which case the platform default properties
+        // for configuring CA certs will be used, but we'll accept any provider that can give
+        // us at least one cert.
+        Provider[] providers = Security.getProviders("TrustManagerFactory.PKIX");
+        for (Provider p : providers) {
+            if (Conscrypt.isConscrypt(p)) {
+                // We need to skip any Conscrypt provider we find because this method is called
+                // when we're trying to determine the default set of CA certs for one of our
+                // TrustManagers, so trying to construct a TrustManager from this provider
+                // would result in calling this method again and recursing infinitely.
+                continue;
+            }
+            try {
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", p);
+                tmf.init((KeyStore) null);
+                TrustManager[] tms = tmf.getTrustManagers();
+                if (tms.length > 0) {
+                    // Aliases are irrelevant for our purposes, so just number the certs
+                    int certNum = 1;
+                    for (TrustManager tm : tms) {
+                        if (tm instanceof X509TrustManager) {
+                            X509TrustManager xtm = (X509TrustManager) tm;
+                            for (X509Certificate cert : xtm.getAcceptedIssuers()) {
+                                ks.setCertificateEntry(Integer.toString(certNum++), cert);
+                            }
+                        }
+                    }
+                    if (certNum > 1) {
+                        // We've loaded at least one certificate, so we're done.
+                        break;
+                    }
+                }
+            } catch (NoSuchAlgorithmException ignored) {
+                // This TrustManagerFactory didn't work, try another one
+            }
+        }
+        return ks;
+    }
+
+    static ConscryptCertStore newDefaultCertStore() {
+        return null;
+    }
+
+    static CertBlacklist newDefaultBlacklist() {
+        return null;
+    }
+
+    static CTLogStore newDefaultLogStore() {
+        return null;
+    }
+
+    static CTPolicy newDefaultPolicy(CTLogStore logStore) {
+        return null;
+    }
+
+    private static boolean isAndroid() {
+        boolean android;
+        try {
+            Class.forName("android.app.Application", false, getSystemClassLoader());
+            android = true;
+        } catch (Throwable ignored) {
+            // Failed to load the class uniquely available in Android.
+            android = false;
+        }
+        return android;
+    }
+
+    static int javaVersion() {
+        return JAVA_VERSION;
+    }
+
+    private static int javaVersion0() {
+        final int majorVersion;
+
+        if (isAndroid()) {
+            majorVersion = 6;
+        } else {
+            majorVersion = majorVersionFromJavaSpecificationVersion();
+        }
+
+        return majorVersion;
+    }
+
+    private static int majorVersionFromJavaSpecificationVersion() {
+        return majorVersion(System.getProperty("java.specification.version", "1.6"));
+    }
+
+    private static int majorVersion(final String javaSpecVersion) {
+        final String[] components = javaSpecVersion.split("\\.", -1);
+        final int[] version = new int[components.length];
+        for (int i = 0; i < components.length; i++) {
+            version[i] = Integer.parseInt(components[i]);
+        }
+
+        if (version[0] == 1) {
+            assert version[1] >= 6;
+            return version[1];
+        } else {
+            return version[0];
+        }
+    }
+
+    private static ClassLoader getSystemClassLoader() {
+        if (System.getSecurityManager() == null) {
+            return ClassLoader.getSystemClassLoader();
+        } else {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                @Override
+                public ClassLoader run() {
+                    return ClassLoader.getSystemClassLoader();
+                }
+            });
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/AbstractSessionContextTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/AbstractSessionContextTest.java
new file mode 100644
index 0000000..e4520d8
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/AbstractSessionContextTest.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.security.cert.Certificate;
+import javax.net.ssl.SSLSession;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractSessionContextTest<T extends AbstractSessionContext> {
+    private T context;
+
+    @Before
+    public void setup() {
+        context = newContext();
+    }
+
+    abstract T newContext();
+    abstract int size(T context);
+    private static NativeSslSession[] toArray(NativeSslSession... sessions) {
+        return sessions;
+    }
+
+    abstract NativeSslSession getCachedSession(T context, NativeSslSession s);
+
+    @Test
+    public void testSimpleAddition() {
+        NativeSslSession a = newSession("a");
+        NativeSslSession b = newSession("b");
+
+        context.cacheSession(a);
+        assertSessionContextContents(toArray(a), toArray(b));
+
+        context.cacheSession(b);
+        assertSessionContextContents(toArray(a, b), toArray());
+    }
+
+    @Test
+    public void testTrimToSize() {
+        NativeSslSession a = newSession("a");
+        NativeSslSession b = newSession("b");
+        NativeSslSession c = newSession("c");
+        NativeSslSession d = newSession("d");
+
+        context.cacheSession(a);
+        context.cacheSession(b);
+        context.cacheSession(c);
+        context.cacheSession(d);
+        assertSessionContextContents(toArray(a, b, c, d), toArray());
+
+        context.setSessionCacheSize(2);
+        assertSessionContextContents(toArray(c, d), toArray(a, b));
+    }
+
+    @Test
+    public void testImplicitRemovalOfOldest() {
+        context.setSessionCacheSize(2);
+        NativeSslSession a = newSession("a");
+        NativeSslSession b = newSession("b");
+        NativeSslSession c = newSession("c");
+        NativeSslSession d = newSession("d");
+
+        context.cacheSession(a);
+        assertSessionContextContents(toArray(a), toArray(b, c, d));
+
+        context.cacheSession(b);
+        assertSessionContextContents(toArray(a, b), toArray(c, d));
+
+        context.cacheSession(c);
+        assertSessionContextContents(toArray(b, c), toArray(a, d));
+
+        context.cacheSession(d);
+        assertSessionContextContents(toArray(c, d), toArray(a, b));
+    }
+
+    @Test
+    public void testRemoveIfSingleUse() {
+        NativeSslSession multi = new MockSessionBuilder().host("multi").singleUse(false).build();
+        NativeSslSession single = new MockSessionBuilder().host("single").singleUse(true).build();
+
+        context.cacheSession(multi);
+        assertEquals(1, size(context));
+
+        context.cacheSession(single);
+        assertEquals(2, size(context));
+
+        NativeSslSession out = getCachedSession(context, multi);
+        assertEquals(multi, out);
+        assertEquals(2, size(context));
+
+        out = getCachedSession(context, single);
+        assertEquals(single, out);
+        assertEquals(1, size(context));
+
+        assertNull(getCachedSession(context, single));
+    }
+
+    @Test
+    public void testSerializeSession() throws Exception {
+        Certificate mockCert = mock(Certificate.class);
+        when(mockCert.getEncoded()).thenReturn(new byte[] {0x05, 0x06, 0x07, 0x10});
+
+        byte[] encodedBytes = new byte[] {0x01, 0x02, 0x03};
+        NativeSslSession session = new MockSessionBuilder()
+                .id(new byte[] {0x11, 0x09, 0x03, 0x20})
+                .host("ssl.example.com")
+                .encodedBytes(encodedBytes)
+                .build();
+
+        SSLClientSessionCache mockCache = mock(SSLClientSessionCache.class);
+        ClientSessionContext context = new ClientSessionContext();
+        context.setPersistentCache(mockCache);
+
+        context.cacheSession(session);
+        verify(mockCache).putSessionData(any(SSLSession.class), same(encodedBytes));
+    }
+
+    private void assertSessionContextContents(
+            NativeSslSession[] contains, NativeSslSession[] excludes) {
+        assertEquals(contains.length, size(context));
+
+        for (NativeSslSession s : contains) {
+            assertSame(s.getPeerHost(), s, getCachedSession(context, s));
+        }
+        for (NativeSslSession s : excludes) {
+            assertNull(s.getPeerHost(), getCachedSession(context, s));
+        }
+    }
+
+    private NativeSslSession newSession(String host) {
+        return new MockSessionBuilder().host(host).build();
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/AddressUtilsTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/AddressUtilsTest.java
new file mode 100644
index 0000000..bdf1fdd
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/AddressUtilsTest.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for AddressUtils
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AddressUtilsTest extends TestCase {
+    public void test_isValidSniHostname_Success() throws Exception {
+        assertTrue(AddressUtils.isValidSniHostname("www.google.com"));
+    }
+
+    public void test_isValidSniHostname_NotFQDN_Failure() throws Exception {
+        assertFalse(AddressUtils.isValidSniHostname("www"));
+    }
+
+    public void test_isValidSniHostname_Localhost_Success() throws Exception {
+        assertTrue(AddressUtils.isValidSniHostname("LOCALhost"));
+    }
+
+    public void test_isValidSniHostname_IPv4_Failure() throws Exception {
+        assertFalse(AddressUtils.isValidSniHostname("192.168.0.1"));
+    }
+
+    public void test_isValidSniHostname_IPv6_Failure() throws Exception {
+        assertFalse(AddressUtils.isValidSniHostname("2001:db8::1"));
+    }
+
+    public void test_isValidSniHostname_TrailingDot() throws Exception {
+        assertFalse(AddressUtils.isValidSniHostname("www.google.com."));
+    }
+
+    public void test_isValidSniHostname_NullByte() throws Exception {
+        assertFalse(AddressUtils.isValidSniHostname("www\0.google.com"));
+    }
+
+    public void test_isLiteralIpAddress_IPv4_Success() throws Exception {
+        assertTrue(AddressUtils.isLiteralIpAddress("127.0.0.1"));
+        assertTrue(AddressUtils.isLiteralIpAddress("255.255.255.255"));
+        assertTrue(AddressUtils.isLiteralIpAddress("0.0.00.000"));
+        assertTrue(AddressUtils.isLiteralIpAddress("192.009.010.19"));
+        assertTrue(AddressUtils.isLiteralIpAddress("254.249.190.094"));
+    }
+
+    public void test_isLiteralIpAddress_IPv4_ExtraCharacters_Failure() throws Exception {
+        assertFalse(AddressUtils.isLiteralIpAddress("127.0.0.1a"));
+        assertFalse(AddressUtils.isLiteralIpAddress(" 255.255.255.255"));
+        assertFalse(AddressUtils.isLiteralIpAddress("0.0.00.0009"));
+        assertFalse(AddressUtils.isLiteralIpAddress("192.009z.010.19"));
+        assertFalse(AddressUtils.isLiteralIpAddress("254.249..094"));
+        assertFalse(AddressUtils.isLiteralIpAddress("192.168.2.1%1"));
+        assertFalse(AddressUtils.isLiteralIpAddress("192.168.2.1%eth0"));
+    }
+
+    public void test_isLiteralIpAddress_IPv4_NumbersTooLarge_Failure() throws Exception {
+        assertFalse(AddressUtils.isLiteralIpAddress("256.255.255.255"));
+        assertFalse(AddressUtils.isLiteralIpAddress("255.255.255.256"));
+        assertFalse(AddressUtils.isLiteralIpAddress("192.168.1.260"));
+    }
+
+    public void test_isLiteralIpAddress_IPv6_Success() throws Exception {
+        assertTrue(AddressUtils.isLiteralIpAddress("::1"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:Db8::1"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:cdbA:0000:0000:0000:0000:3257:9652"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:cdba:0:0:0:0:3257:9652"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:cdBA::3257:9652"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:cdba::3257:9652%1"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:cdba::3257:9652%eth0"));
+        assertTrue(AddressUtils.isLiteralIpAddress("2001:cdba::3257:9652%int2.3!"));
+    }
+
+    public void test_isLiteralIpAddress_IPv6_Failure() throws Exception {
+        assertFalse(AddressUtils.isLiteralIpAddress(":::1"));
+        assertFalse(AddressUtils.isLiteralIpAddress("::11111"));
+        assertFalse(AddressUtils.isLiteralIpAddress("20011::1111"));
+        assertFalse(AddressUtils.isLiteralIpAddress("2001:db8:::1"));
+        assertFalse(AddressUtils.isLiteralIpAddress("2001:cdba:0000:00000:0000:0000:3257:9652"));
+        assertFalse(AddressUtils.isLiteralIpAddress("2001:cdbA:0000:0000:0000:0000:0000:3257:9652"));
+        assertFalse(AddressUtils.isLiteralIpAddress("2001:cdba:0::0:0:0:3257:9652"));
+        assertFalse(AddressUtils.isLiteralIpAddress("02001:cdba::3257:9652"));
+        assertFalse(AddressUtils.isLiteralIpAddress("2001:cdba::3257:96521"));
+        assertFalse(AddressUtils.isLiteralIpAddress("2001:cdba::3257:9652%"));
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ApplicationProtocolSelectorAdapterTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ApplicationProtocolSelectorAdapterTest.java
new file mode 100644
index 0000000..adfe804
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ApplicationProtocolSelectorAdapterTest.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.when;
+
+import java.nio.charset.Charset;
+import javax.net.ssl.SSLEngine;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ApplicationProtocolSelectorAdapterTest {
+    private static Charset US_ASCII = Charset.forName("US-ASCII");
+    private static final String[] PROTOCOLS = new String[] {"a", "b", "c"};
+    private static final byte[] PROTOCOL_BYTES = SSLUtils.encodeProtocols(PROTOCOLS);
+
+    @Mock private ApplicationProtocolSelector selector;
+
+    @Mock private SSLEngine engine;
+
+    private ApplicationProtocolSelectorAdapter adapter;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        adapter = new ApplicationProtocolSelectorAdapter(engine, selector);
+    }
+
+    @Test
+    public void nullProtocolsShouldNotSelect() {
+        mockSelection("a");
+        assertEquals(-1, select(null));
+    }
+
+    @Test
+    public void emptyProtocolsShouldNotSelect() {
+        mockSelection("a");
+        assertEquals(-1, select(EmptyArray.BYTE));
+    }
+
+    @Test
+    public void selectCorrectProtocol() {
+        for (String protocol : PROTOCOLS) {
+            mockSelection(protocol);
+            assertEquals(protocol, getProtocolAt(select(PROTOCOL_BYTES)));
+        }
+    }
+
+    @Test
+    public void invalidProtocolShouldNotSelect() {
+        mockSelection("d");
+        assertEquals(-1, select(PROTOCOL_BYTES));
+    }
+
+    private int select(byte[] protocols) {
+        return adapter.selectApplicationProtocol(protocols);
+    }
+
+    private void mockSelection(String returnValue) {
+        when(selector.selectApplicationProtocol(same(engine), Matchers.anyListOf(String.class)))
+                .thenReturn(returnValue);
+    }
+
+    private String getProtocolAt(int index) {
+        int len = PROTOCOL_BYTES[index];
+        return new String(PROTOCOL_BYTES, index + 1, len, US_ASCII);
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ClientSessionContextTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ClientSessionContextTest.java
new file mode 100644
index 0000000..a05ba8f
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ClientSessionContextTest.java
@@ -0,0 +1,120 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.MockSessionBuilder.DEFAULT_PORT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.security.KeyManagementException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class ClientSessionContextTest extends AbstractSessionContextTest<ClientSessionContext> {
+
+    @Override
+    ClientSessionContext newContext() {
+        return new ClientSessionContext();
+    }
+
+    @Override
+    NativeSslSession getCachedSession(ClientSessionContext context, NativeSslSession s) {
+        return context.getCachedSession(s.getPeerHost(), DEFAULT_PORT,
+                getDefaultSSLParameters());
+    }
+
+    @Override
+    int size(ClientSessionContext context) {
+        return context.size();
+    }
+
+    private static SSLParametersImpl getDefaultSSLParameters() {
+        try {
+            return SSLParametersImpl.getDefault();
+        } catch (KeyManagementException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    public void testNoMixingOfSingleAndMultiUseSessions() {
+        ClientSessionContext context = newContext();
+
+        NativeSslSession a = new MockSessionBuilder().host("a").singleUse(false).build();
+        NativeSslSession bSingle1 = new MockSessionBuilder()
+                .id(new byte[] {1}).host("b").singleUse(true).build();
+        NativeSslSession bSingle2 = new MockSessionBuilder()
+                .id(new byte[] {2}).host("b").singleUse(true).build();
+        NativeSslSession bMulti = new MockSessionBuilder()
+                .id(new byte[] {3}).host("b").singleUse(false).build();
+
+        context.cacheSession(a);
+        assertEquals(1, size(context));
+
+        context.cacheSession(bSingle1);
+        assertEquals(2, size(context));
+
+        context.cacheSession(bSingle2);
+        assertEquals(3, size(context));
+
+        context.cacheSession(bMulti);
+        assertEquals(2, size(context));
+
+        NativeSslSession out = context.getCachedSession(
+                "b", DEFAULT_PORT, getDefaultSSLParameters());
+        assertEquals(bMulti, out);
+
+        context.cacheSession(bSingle2);
+        assertEquals(2, size(context));
+
+        out = context.getCachedSession("b", DEFAULT_PORT, getDefaultSSLParameters());
+        assertEquals(bSingle2, out);
+
+        out = context.getCachedSession("b", DEFAULT_PORT, getDefaultSSLParameters());
+        assertNull(out);
+    }
+
+    @Test
+    public void testCanRetrieveMultipleSingleUseSessions() {
+        ClientSessionContext context = newContext();
+
+        NativeSslSession single1 = new MockSessionBuilder()
+                .id(new byte[] {1}).host("host").singleUse(true).build();
+        NativeSslSession single2 = new MockSessionBuilder()
+                .id(new byte[] {2}).host("host").singleUse(true).build();
+
+        context.cacheSession(single1);
+        assertEquals(1, size(context));
+
+        context.cacheSession(single2);
+        assertEquals(2, size(context));
+
+        assertSame(single1,
+                context.getCachedSession("host", DEFAULT_PORT, getDefaultSSLParameters()));
+        assertEquals(1, size(context));
+        assertSame(single2,
+                context.getCachedSession("host", DEFAULT_PORT, getDefaultSSLParameters()));
+        assertEquals(0, size(context));
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptEngineTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptEngineTest.java
new file mode 100644
index 0000000..a92b6d8
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptEngineTest.java
@@ -0,0 +1,555 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.getConscryptProvider;
+import static com.android.org.conscrypt.TestUtils.getJdkProvider;
+import static com.android.org.conscrypt.TestUtils.getProtocols;
+import static com.android.org.conscrypt.TestUtils.initSslContext;
+import static com.android.org.conscrypt.TestUtils.newTextMessage;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSession;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class ConscryptEngineTest {
+    private static final int MESSAGE_SIZE = 4096;
+    private static final int LARGE_MESSAGE_SIZE = 16413;
+    private static final String[] CIPHERS = TestUtils.getCommonCipherSuites();
+    private static final String RENEGOTIATION_CIPHER = CIPHERS[CIPHERS.length - 1];
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    @SuppressWarnings("ImmutableEnumChecker")
+    public enum BufferType {
+        HEAP_ALLOCATOR(BufferAllocator.unpooled()) {
+            @Override
+            ByteBuffer newBuffer(int size) {
+                return ByteBuffer.allocate(size);
+            }
+        },
+        HEAP_NO_ALLOCATOR(null) {
+            @Override
+            ByteBuffer newBuffer(int size) {
+                return ByteBuffer.allocate(size);
+            }
+        },
+        DIRECT(null) {
+            @Override
+            ByteBuffer newBuffer(int size) {
+                return ByteBuffer.allocateDirect(size);
+            }
+        };
+
+        abstract ByteBuffer newBuffer(int size);
+
+        BufferType(BufferAllocator allocator) {
+            this.allocator = allocator;
+        }
+
+        private final BufferAllocator allocator;
+    }
+
+    private enum ClientAuth {
+        NONE {
+            @Override
+            void apply(SSLEngine engine) {
+                engine.setWantClientAuth(false);
+                engine.setNeedClientAuth(false);
+            }
+        },
+        OPTIONAL {
+            @Override
+            void apply(SSLEngine engine) {
+                engine.setWantClientAuth(true);
+                engine.setNeedClientAuth(false);
+            }
+        },
+        REQUIRED {
+            @Override
+            void apply(SSLEngine engine) {
+                engine.setWantClientAuth(false);
+                engine.setNeedClientAuth(true);
+            }
+        };
+
+        abstract void apply(SSLEngine engine);
+    }
+
+    @Parameters(name = "{0}")
+    public static Iterable<BufferType> data() {
+        return Arrays.asList(
+                BufferType.HEAP_ALLOCATOR, BufferType.HEAP_NO_ALLOCATOR, BufferType.DIRECT);
+    }
+
+    @Parameter public BufferType bufferType;
+
+    private SSLEngine clientEngine;
+    private SSLEngine serverEngine;
+
+    @Test
+    public void closingOutboundBeforeHandshakeShouldCloseAll() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+        assertFalse(clientEngine.isInboundDone());
+        assertFalse(clientEngine.isOutboundDone());
+        assertFalse(serverEngine.isInboundDone());
+        assertFalse(serverEngine.isOutboundDone());
+
+        clientEngine.closeOutbound();
+        serverEngine.closeOutbound();
+
+        assertTrue(clientEngine.isInboundDone());
+        assertTrue(clientEngine.isOutboundDone());
+        assertTrue(serverEngine.isInboundDone());
+        assertTrue(serverEngine.isOutboundDone());
+    }
+
+    @Test
+    public void closingOutboundAfterHandshakeShouldOnlyCloseOutbound() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+        doHandshake(true);
+
+        assertFalse(clientEngine.isInboundDone());
+        assertFalse(clientEngine.isOutboundDone());
+        assertFalse(serverEngine.isInboundDone());
+        assertFalse(serverEngine.isOutboundDone());
+
+        clientEngine.closeOutbound();
+        serverEngine.closeOutbound();
+
+        // After closing the outbound direction, a shutdown alert should still be pending
+        assertFalse(clientEngine.isOutboundDone());
+        assertFalse(serverEngine.isOutboundDone());
+
+        ByteBuffer drain =
+                bufferType.newBuffer(Math.max(clientEngine.getSession().getPacketBufferSize(),
+                        serverEngine.getSession().getPacketBufferSize()));
+        clientEngine.wrap(ByteBuffer.wrap(new byte[0]), drain);
+        drain.clear();
+        serverEngine.wrap(ByteBuffer.wrap(new byte[0]), drain);
+
+        assertTrue(clientEngine.isOutboundDone());
+        assertTrue(serverEngine.isOutboundDone());
+
+        // The inbound directions should still be open
+        assertFalse(clientEngine.isInboundDone());
+        assertFalse(serverEngine.isInboundDone());
+    }
+
+    @Test
+    public void closingInboundShouldOnlyCloseInbound() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+        doHandshake(true);
+
+        assertFalse(clientEngine.isInboundDone());
+        assertFalse(clientEngine.isOutboundDone());
+        assertFalse(serverEngine.isInboundDone());
+        assertFalse(serverEngine.isOutboundDone());
+
+        clientEngine.closeInbound();
+        serverEngine.closeInbound();
+
+        assertTrue(clientEngine.isInboundDone());
+        assertFalse(clientEngine.isOutboundDone());
+        assertTrue(serverEngine.isInboundDone());
+        assertFalse(serverEngine.isOutboundDone());
+    }
+
+    @Test
+    public void mutualAuthWithSameCertsShouldSucceed() throws Exception {
+        doMutualAuthHandshake(TestKeyStore.getServer(), TestKeyStore.getServer(), ClientAuth.NONE);
+    }
+
+    @Test
+    public void mutualAuthWithDifferentCertsShouldSucceed() throws Exception {
+        doMutualAuthHandshake(TestKeyStore.getClient(), TestKeyStore.getServer(), ClientAuth.NONE);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void mutualAuthWithUntrustedServerShouldFail() throws Exception {
+        doMutualAuthHandshake(
+                TestKeyStore.getClientCA2(), TestKeyStore.getServer(), ClientAuth.NONE);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void mutualAuthWithUntrustedClientShouldFail() throws Exception {
+        doMutualAuthHandshake(TestKeyStore.getClient(), TestKeyStore.getClient(), ClientAuth.NONE);
+    }
+
+    @Test
+    public void optionalClientAuthShouldSucceed() throws Exception {
+        doMutualAuthHandshake(
+                TestKeyStore.getClient(), TestKeyStore.getServer(), ClientAuth.OPTIONAL);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void optionalClientAuthShouldFail() throws Exception {
+        doMutualAuthHandshake(
+                TestKeyStore.getClient(), TestKeyStore.getClient(), ClientAuth.OPTIONAL);
+    }
+
+    @Test
+    public void requiredClientAuthShouldSucceed() throws Exception {
+        doMutualAuthHandshake(
+                TestKeyStore.getServer(), TestKeyStore.getServer(), ClientAuth.REQUIRED);
+    }
+
+    @Test(expected = SSLHandshakeException.class)
+    public void requiredClientAuthShouldFail() throws Exception {
+        doMutualAuthHandshake(
+                TestKeyStore.getClient(), TestKeyStore.getClient(), ClientAuth.REQUIRED);
+    }
+
+    @Test
+    public void exchangeMessages() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+        doHandshake(true);
+
+        ByteBuffer message = newMessage(MESSAGE_SIZE);
+        byte[] messageBytes = toArray(message);
+
+        // Wrap the original message and create the encrypted data.
+        final int numMessages = 100;
+        ByteBuffer[] encryptedBuffers = new ByteBuffer[numMessages];
+        for (int i = 0; i < numMessages; ++i) {
+            List<ByteBuffer> wrapped = wrap(message.duplicate(), clientEngine);
+            // Small message, we should only have 1 buffer created.
+            assertEquals(1, wrapped.size());
+            encryptedBuffers[i] = wrapped.get(0);
+        }
+
+        // Unwrap the all of the encrypted messages.
+        byte[] actualBytes = unwrap(encryptedBuffers, serverEngine);
+        assertEquals(MESSAGE_SIZE * numMessages, actualBytes.length);
+        for (int i = 0; i < numMessages; ++i) {
+            int offset = i * MESSAGE_SIZE;
+            byte[] actualMessageBytes =
+                    Arrays.copyOfRange(actualBytes, offset, offset + MESSAGE_SIZE);
+            assertArrayEquals(messageBytes, actualMessageBytes);
+        }
+    }
+
+    @Test
+    public void exchangeLargeMessage() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+        doHandshake(true);
+
+        ByteBuffer inputBuffer = newMessage(LARGE_MESSAGE_SIZE);
+        exchangeMessage(inputBuffer, clientEngine, serverEngine);
+    }
+
+    @Test
+    public void alpnWithProtocolListShouldSucceed() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+
+        // Configure ALPN protocols
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        String[] serverAlpnProtocols = new String[]{"spdy/2", "foo", "bar"};
+
+        Conscrypt.setApplicationProtocols(clientEngine, clientAlpnProtocols);
+        Conscrypt.setApplicationProtocols(serverEngine, serverAlpnProtocols);
+
+        doHandshake(true);
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(clientEngine));
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(serverEngine));
+    }
+
+    @Test
+    public void alpnWithProtocolListShouldFail() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+
+        // Configure ALPN protocols
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        String[] serverAlpnProtocols = new String[]{"h2", "bar", "baz"};
+
+        Conscrypt.setApplicationProtocols(clientEngine, clientAlpnProtocols);
+        Conscrypt.setApplicationProtocols(serverEngine, serverAlpnProtocols);
+
+        doHandshake(true);
+        assertNull(Conscrypt.getApplicationProtocol(clientEngine));
+        assertNull(Conscrypt.getApplicationProtocol(serverEngine));
+    }
+
+    @Test
+    public void alpnWithServerProtocolSelectorShouldSucceed() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+
+        // Configure client protocols.
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        Conscrypt.setApplicationProtocols(clientEngine, clientAlpnProtocols);
+
+        // Configure server selector
+        ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class);
+        when(selector.selectApplicationProtocol(same(serverEngine), Matchers.anyListOf(String.class)))
+                .thenReturn("spdy/2");
+        Conscrypt.setApplicationProtocolSelector(serverEngine, selector);
+
+        doHandshake(true);
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(clientEngine));
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(serverEngine));
+    }
+
+    @Test
+    public void alpnWithServerProtocolSelectorShouldFail() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+
+        // Configure client protocols.
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        Conscrypt.setApplicationProtocols(clientEngine, clientAlpnProtocols);
+
+        // Configure server selector
+        ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class);
+        when(selector.selectApplicationProtocol(same(serverEngine), Matchers.anyListOf(String.class)))
+                .thenReturn("h2");
+        Conscrypt.setApplicationProtocolSelector(serverEngine, selector);
+
+        doHandshake(true);
+        assertNull(Conscrypt.getApplicationProtocol(clientEngine));
+        assertNull(Conscrypt.getApplicationProtocol(serverEngine));
+    }
+
+    /**
+     * BoringSSL server doesn't support renegotiation. BoringSSL clients do not support
+     * initiating a renegotiation, only processing a renegotiation initiated by the
+     * (non-BoringSSL) server. For this reason we test a server-initiated renegotiation with
+     * a Conscrypt client and a JDK server.
+     */
+    @Test
+    public void serverInitiatedRenegotiationShouldSucceed() throws Exception {
+        setupClientEngine(getConscryptProvider(), TestKeyStore.getClient());
+        setupServerEngine(getJdkProvider(), TestKeyStore.getServer());
+
+        // Perform the initial handshake.
+        doHandshake(true);
+
+        // Send a message from client->server.
+        exchangeMessage(newMessage(MESSAGE_SIZE), clientEngine, serverEngine);
+
+        // Trigger a renegotiation from the server and send a message back from Server->Client
+        serverEngine.setEnabledCipherSuites(new String[] {RENEGOTIATION_CIPHER});
+        serverEngine.beginHandshake();
+        doHandshake(false);
+
+        exchangeMessage(newMessage(MESSAGE_SIZE), serverEngine, clientEngine);
+    }
+
+    @Test
+    public void savedSessionWorksAfterClose() throws Exception {
+        setupEngines(TestKeyStore.getClient(), TestKeyStore.getServer());
+        doHandshake(true);
+
+        SSLSession session = clientEngine.getSession();
+        String cipherSuite = session.getCipherSuite();
+
+        clientEngine.closeOutbound();
+        clientEngine.closeInbound();
+
+        assertEquals(cipherSuite, session.getCipherSuite());
+    }
+
+    private void doMutualAuthHandshake(
+            TestKeyStore clientKs, TestKeyStore serverKs, ClientAuth clientAuth) throws Exception {
+        setupEngines(clientKs, serverKs);
+        clientAuth.apply(serverEngine);
+        doHandshake(true);
+        assertEquals(HandshakeStatus.NOT_HANDSHAKING, clientEngine.getHandshakeStatus());
+        assertEquals(HandshakeStatus.NOT_HANDSHAKING, serverEngine.getHandshakeStatus());
+    }
+
+    private void doHandshake(boolean beginHandshake) throws SSLException {
+        ByteBuffer clientApplicationBuffer =
+                bufferType.newBuffer(clientEngine.getSession().getApplicationBufferSize());
+        ByteBuffer clientPacketBuffer =
+                bufferType.newBuffer(clientEngine.getSession().getPacketBufferSize());
+        ByteBuffer serverApplicationBuffer =
+                bufferType.newBuffer(serverEngine.getSession().getApplicationBufferSize());
+        ByteBuffer serverPacketBuffer =
+                bufferType.newBuffer(serverEngine.getSession().getPacketBufferSize());
+        TestUtils.doEngineHandshake(clientEngine, serverEngine, clientApplicationBuffer,
+                clientPacketBuffer, serverApplicationBuffer, serverPacketBuffer, beginHandshake);
+    }
+
+    private void setupEngines(TestKeyStore clientKeyStore, TestKeyStore serverKeyStore) throws SSLException {
+        setupClientEngine(getConscryptProvider(), clientKeyStore);
+        setupServerEngine(getConscryptProvider(), serverKeyStore);
+    }
+
+    private void setupClientEngine(Provider provider, TestKeyStore clientKeyStore)
+            throws SSLException {
+        clientEngine = newEngine(provider, clientKeyStore, true);
+    }
+
+    private void setupServerEngine(Provider provider, TestKeyStore serverKeyStore)
+            throws SSLException {
+        serverEngine = newEngine(provider, serverKeyStore, false);
+    }
+
+    private SSLEngine newEngine(
+            Provider provider, TestKeyStore keyStore, boolean client) {
+        SSLContext serverContext = newContext(provider, keyStore);
+        SSLEngine engine = serverContext.createSSLEngine();
+        engine.setEnabledCipherSuites(CIPHERS);
+        engine.setUseClientMode(client);
+        if (Conscrypt.isConscrypt(engine)) {
+            Conscrypt.setBufferAllocator(engine, bufferType.allocator);
+        }
+        return engine;
+    }
+
+    private void exchangeMessage(ByteBuffer inputBuffer, SSLEngine src, SSLEngine dest)
+            throws IOException {
+        byte[] messageBytes = toArray(inputBuffer);
+
+        // Encrypt the input message.
+        List<ByteBuffer> encryptedBufferList = wrap(inputBuffer, src);
+
+        // Unwrap the all of the encrypted messages.
+        ByteBuffer[] encryptedBuffers =
+                encryptedBufferList.toArray(new ByteBuffer[encryptedBufferList.size()]);
+        byte[] actualBytes = unwrap(encryptedBuffers, dest);
+        assertArrayEquals(messageBytes, actualBytes);
+    }
+
+    private List<ByteBuffer> wrap(ByteBuffer input, SSLEngine engine) throws SSLException {
+        // Encrypt the input message.
+        List<ByteBuffer> wrapped = new ArrayList<ByteBuffer>();
+        while (input.hasRemaining()) {
+            ByteBuffer encryptedBuffer =
+                    bufferType.newBuffer(engine.getSession().getPacketBufferSize());
+            SSLEngineResult wrapResult = engine.wrap(input, encryptedBuffer);
+            assertEquals(SSLEngineResult.Status.OK, wrapResult.getStatus());
+            encryptedBuffer.flip();
+            wrapped.add(encryptedBuffer);
+        }
+        return wrapped;
+    }
+
+    private byte[] unwrap(ByteBuffer[] encryptedBuffers, SSLEngine engine) throws IOException {
+        ByteArrayOutputStream cleartextStream = new ByteArrayOutputStream();
+        int decryptedBufferSize = 8192;
+        final ByteBuffer encryptedBuffer = combine(encryptedBuffers);
+        final ByteBuffer decryptedBuffer = bufferType.newBuffer(decryptedBufferSize);
+        while (encryptedBuffer.hasRemaining()) {
+            if (!decryptedBuffer.hasRemaining()) {
+                decryptedBuffer.clear();
+            }
+            int prevPos = decryptedBuffer.position();
+            SSLEngineResult unwrapResult = engine.unwrap(encryptedBuffer, decryptedBuffer);
+            SSLEngineResult.Status status = unwrapResult.getStatus();
+            switch (status) {
+                case BUFFER_OVERFLOW:
+                case OK: {
+                    break;
+                }
+                default: { throw new RuntimeException("Unexpected SSLEngine status: " + status); }
+            }
+            int newPos = decryptedBuffer.position();
+            int bytesProduced = unwrapResult.bytesProduced();
+            assertEquals(bytesProduced, newPos - prevPos);
+
+            // Add any generated bytes to the output stream.
+            if (bytesProduced > 0 || status == Status.BUFFER_OVERFLOW) {
+                byte[] decryptedBytes = new byte[unwrapResult.bytesProduced()];
+
+                // Read the chunk that was just written to the output array.
+                int limit = decryptedBuffer.limit();
+                decryptedBuffer.limit(newPos);
+                decryptedBuffer.position(prevPos);
+                decryptedBuffer.get(decryptedBytes);
+
+                // Restore the position and limit.
+                decryptedBuffer.limit(limit);
+
+                // Write the decrypted bytes to the stream.
+                cleartextStream.write(decryptedBytes);
+            }
+        }
+
+        return cleartextStream.toByteArray();
+    }
+
+    private ByteBuffer combine(ByteBuffer[] buffers) {
+        int size = 0;
+        for (ByteBuffer buffer : buffers) {
+            size += buffer.remaining();
+        }
+        ByteBuffer combined = bufferType.newBuffer(size);
+        for (ByteBuffer buffer : buffers) {
+            combined.put(buffer);
+        }
+        combined.flip();
+        return combined;
+    }
+
+    private ByteBuffer newMessage(int size) {
+        ByteBuffer buffer = bufferType.newBuffer(size);
+        buffer.put(newTextMessage(size));
+        buffer.flip();
+        return buffer;
+    }
+
+    private static byte[] toArray(ByteBuffer buffer) {
+        int pos = buffer.position();
+        byte[] bytes = new byte[buffer.remaining()];
+        buffer.get(bytes);
+        buffer.position(pos);
+        return bytes;
+    }
+
+    private static SSLContext newContext(Provider provider, TestKeyStore keyStore) {
+        try {
+            SSLContext ctx = SSLContext.getInstance(getProtocols()[0], provider);
+            return initSslContext(ctx, keyStore);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptSocketTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptSocketTest.java
new file mode 100644
index 0000000..2ffbbf9
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptSocketTest.java
@@ -0,0 +1,649 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.openTestFile;
+import static com.android.org.conscrypt.TestUtils.readTestFile;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Mockito;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class ConscryptSocketTest {
+    private static final long TIMEOUT_SECONDS = 5;
+    private static final char[] EMPTY_PASSWORD = new char[0];
+
+    @BeforeClass
+    public static void installConscrypt() {
+        TestUtils.installConscryptAsDefaultProvider();
+    }
+
+    @AfterClass
+    public static void removeConscrypt() {
+        Security.removeProvider(TestUtils.getConscryptProvider().getName());
+    }
+
+    /**
+     * Factories for underlying sockets.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum UnderlyingSocketType {
+        NONE {
+            @Override
+            Socket newClientSocket(
+                    OpenSSLContextImpl context, ServerSocket server, SSLSocketFactory factory) {
+                return null;
+            }
+
+            @Override
+            Socket newServerSocket(OpenSSLContextImpl context, ServerSocket server,
+                    SSLSocketFactory factory) throws IOException {
+                return server.accept();
+            }
+        },
+        PLAIN {
+            @Override
+            Socket newClientSocket(OpenSSLContextImpl context, ServerSocket server,
+                    SSLSocketFactory factory) throws IOException {
+                return new Socket(server.getInetAddress(), server.getLocalPort());
+            }
+
+            @Override
+            Socket newServerSocket(OpenSSLContextImpl context, ServerSocket server,
+                    SSLSocketFactory factory) throws IOException {
+                return server.accept();
+            }
+        },
+        SSL {
+            @Override
+            Socket newClientSocket(OpenSSLContextImpl context, ServerSocket server,
+                    SSLSocketFactory factory) throws IOException {
+                SSLSocket sslSocket = (SSLSocket) factory.createSocket(
+                        server.getInetAddress(), server.getLocalPort());
+                sslSocket.setUseClientMode(true);
+                return sslSocket;
+            }
+
+            @Override
+            Socket newServerSocket(OpenSSLContextImpl context, ServerSocket server,
+                    SSLSocketFactory factory) throws IOException {
+                SSLSocket sslSocket =
+                        (SSLSocket) factory.createSocket(server.accept(), null, -1, true);
+                sslSocket.setUseClientMode(false);
+                return sslSocket;
+            }
+        };
+
+        abstract Socket newClientSocket(OpenSSLContextImpl context, ServerSocket server,
+                SSLSocketFactory factory) throws IOException;
+        abstract Socket newServerSocket(OpenSSLContextImpl context, ServerSocket server,
+                SSLSocketFactory factory) throws IOException;
+    }
+
+    /**
+     * Various factories for SSL server sockets.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum SocketType {
+        FILE_DESCRIPTOR(false) {
+            @Override
+            void assertSocketType(Socket socket) {
+                assertTrue("Unexpected socket type: " + socket.getClass().getName(),
+                        socket instanceof ConscryptFileDescriptorSocket);
+            }
+        },
+        ENGINE(true) {
+            @Override
+            void assertSocketType(Socket socket) {
+                assertTrue("Unexpected socket type: " + socket.getClass().getName(),
+                        socket instanceof ConscryptEngineSocket);
+            }
+        };
+
+        private final boolean useEngineSocket;
+
+        SocketType(boolean useEngineSocket) {
+            this.useEngineSocket = useEngineSocket;
+        }
+
+        AbstractConscryptSocket newClientSocket(OpenSSLContextImpl context, ServerSocket server,
+                UnderlyingSocketType underlyingSocketType) throws IOException {
+            SSLSocketFactory factory = socketFactory(context);
+            Socket underlying = underlyingSocketType.newClientSocket(context, server, factory);
+            if (underlying != null) {
+                return newClientSocket(context, server, underlying);
+            }
+            return init(factory.createSocket(server.getInetAddress(), server.getLocalPort()), true);
+        }
+
+        AbstractConscryptSocket newClientSocket(OpenSSLContextImpl context, ServerSocket server,
+                Socket underlying) throws IOException {
+            SSLSocketFactory factory = socketFactory(context);
+            return init(factory.createSocket(underlying, server.getInetAddress().getHostName(),
+                                server.getLocalPort(), true),
+                    true);
+        }
+
+        AbstractConscryptSocket newServerSocket(OpenSSLContextImpl context, ServerSocket server,
+                UnderlyingSocketType underlyingSocketType) throws IOException {
+            SSLSocketFactory factory = socketFactory(context);
+            Socket underlying = underlyingSocketType.newServerSocket(context, server, factory);
+            return init(socketFactory(context).createSocket(underlying, null, -1, true), false);
+        }
+
+        abstract void assertSocketType(Socket socket);
+
+        private SSLSocketFactory socketFactory(OpenSSLContextImpl context) {
+            SSLSocketFactory factory = context.engineGetSocketFactory();
+            Conscrypt.setUseEngineSocket(factory, useEngineSocket);
+            return factory;
+        }
+
+        private AbstractConscryptSocket init(Socket socket, boolean useClientMode) {
+            assertSocketType(socket);
+            AbstractConscryptSocket sslSocket = (AbstractConscryptSocket) socket;
+            sslSocket.setUseClientMode(useClientMode);
+            return sslSocket;
+        }
+    }
+
+    @Parameters(name = "{0} wrapping {1}")
+    public static Object[][] data() {
+        return new Object[][] {
+            {SocketType.FILE_DESCRIPTOR, UnderlyingSocketType.NONE},
+            {SocketType.FILE_DESCRIPTOR, UnderlyingSocketType.PLAIN},
+            // Not supported: {SocketType.FILE_DESCRIPTOR, UnderlyingSocketType.SSL},
+            {SocketType.ENGINE, UnderlyingSocketType.NONE},
+            {SocketType.ENGINE, UnderlyingSocketType.PLAIN},
+            {SocketType.ENGINE, UnderlyingSocketType.SSL}};
+    }
+
+    @Parameter
+    public SocketType socketType;
+
+    @Parameter(1)
+    public UnderlyingSocketType underlyingSocketType;
+
+    private X509Certificate ca;
+    private X509Certificate cert;
+    private X509Certificate certEmbedded;
+    private PrivateKey certKey;
+
+    private Field contextSSLParameters;
+    private ExecutorService executor;
+
+    @Before
+    public void setUp() throws Exception {
+        contextSSLParameters = OpenSSLContextImpl.class.getDeclaredField("sslParameters");
+        contextSSLParameters.setAccessible(true);
+
+        ca = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("ca-cert.pem"));
+        cert = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("cert.pem"));
+        certEmbedded =
+                OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("cert-ct-embedded.pem"));
+        certKey = OpenSSLKey.fromPrivateKeyPemInputStream(openTestFile("cert-key.pem"))
+                          .getPrivateKey();
+        executor = Executors.newCachedThreadPool();
+    }
+
+    @After
+    public void teardown() throws Exception {
+        executor.shutdown();
+        executor.awaitTermination(5, TimeUnit.SECONDS);
+    }
+
+    abstract class Hooks implements HandshakeCompletedListener {
+        KeyManager[] keyManagers;
+        TrustManager[] trustManagers;
+        String[] alpnProtocols;
+
+        abstract AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException;
+
+        OpenSSLContextImpl createContext() throws IOException {
+            OpenSSLContextImpl context = OpenSSLContextImpl.getPreferred();
+            try {
+                context.engineInit(keyManagers, trustManagers, null);
+            } catch (KeyManagementException e) {
+                throw new IOException(e);
+            }
+            return context;
+        }
+
+        boolean isHandshakeCompleted = false;
+        @Override
+        public void handshakeCompleted(HandshakeCompletedEvent event) {
+            isHandshakeCompleted = true;
+        }
+
+        SSLParametersImpl getContextSSLParameters(OpenSSLContextImpl context)
+                throws IllegalAccessException {
+            return (SSLParametersImpl) contextSSLParameters.get(context);
+        }
+    }
+
+    class ClientHooks extends Hooks {
+        String hostname = "example.com";
+
+        @Override
+        public OpenSSLContextImpl createContext() throws IOException {
+            OpenSSLContextImpl context = super.createContext();
+            try {
+                SSLParametersImpl sslParameters = getContextSSLParameters(context);
+                sslParameters.setCTVerificationEnabled(true);
+            } catch (IllegalAccessException e) {
+                throw new IOException(e);
+            }
+            return context;
+        }
+
+        @Override
+        AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException {
+            AbstractConscryptSocket socket =
+                    socketType.newClientSocket(createContext(), listener, underlyingSocketType);
+            socket.setHostname(hostname);
+            if (alpnProtocols != null) {
+                Conscrypt.setApplicationProtocols(socket, alpnProtocols);
+            }
+            return socket;
+        }
+    }
+
+    class ServerHooks extends Hooks {
+        byte[] sctTLSExtension;
+        byte[] ocspResponse;
+        ApplicationProtocolSelector alpnProtocolSelector;
+
+        @Override
+        public OpenSSLContextImpl createContext() throws IOException {
+            OpenSSLContextImpl context = super.createContext();
+            try {
+                SSLParametersImpl sslParameters = getContextSSLParameters(context);
+                sslParameters.setSCTExtension(sctTLSExtension);
+                sslParameters.setOCSPResponse(ocspResponse);
+                return context;
+            } catch (IllegalAccessException e) {
+                throw new IOException(e);
+            }
+        }
+
+        @Override
+        AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException {
+            AbstractConscryptSocket socket =
+                    socketType.newServerSocket(createContext(), listener, underlyingSocketType);
+            if (alpnProtocols != null) {
+                Conscrypt.setApplicationProtocols(socket, alpnProtocols);
+            }
+            if (alpnProtocolSelector != null) {
+                Conscrypt.setApplicationProtocolSelector(socket, alpnProtocolSelector);
+            }
+            return socket;
+        }
+    }
+
+    class TestConnection {
+        ServerHooks serverHooks;
+        ClientHooks clientHooks;
+
+        AbstractConscryptSocket client;
+        AbstractConscryptSocket server;
+
+        Exception clientException;
+        Exception serverException;
+
+        TestConnection(X509Certificate[] chain, PrivateKey key) throws Exception {
+            clientHooks = new ClientHooks();
+            serverHooks = new ServerHooks();
+            setCertificates(chain, key);
+        }
+
+        private void setCertificates(X509Certificate[] chain, PrivateKey key) throws Exception {
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(null, null);
+            ks.setKeyEntry("default", key, EMPTY_PASSWORD, chain);
+            ks.setCertificateEntry("CA", chain[chain.length - 1]);
+
+            TrustManagerFactory tmf =
+                    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(ks);
+            TrustManager[] tms = tmf.getTrustManagers();
+
+            KeyManagerFactory kmf =
+                    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, EMPTY_PASSWORD);
+            KeyManager[] kms = kmf.getKeyManagers();
+
+            clientHooks.trustManagers = tms;
+            serverHooks.keyManagers = kms;
+            serverHooks.trustManagers = tms;
+        }
+
+        private <T> T getOrThrowCause(Future<T> future, long timeout, TimeUnit timeUnit)
+                throws Exception {
+            try {
+                return future.get(timeout, timeUnit);
+            } catch (ExecutionException e) {
+                if (e.getCause() instanceof Exception) {
+                    throw(Exception) e.getCause();
+                } else {
+                    throw e;
+                }
+            }
+        }
+
+        void doHandshake() throws Exception {
+            ServerSocket listener = newServerSocket();
+            Future<AbstractConscryptSocket> clientFuture = handshake(listener, clientHooks);
+            Future<AbstractConscryptSocket> serverFuture = handshake(listener, serverHooks);
+
+            try {
+                client = getOrThrowCause(clientFuture, TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            } catch (Exception e) {
+                clientException = e;
+            }
+            try {
+                server = getOrThrowCause(serverFuture, TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            } catch (Exception e) {
+                serverException = e;
+            }
+        }
+
+        Future<AbstractConscryptSocket> handshake(final ServerSocket listener, final Hooks hooks) {
+            return executor.submit(new Callable<AbstractConscryptSocket>() {
+                @Override
+                public AbstractConscryptSocket call() throws Exception {
+                    AbstractConscryptSocket socket = hooks.createSocket(listener);
+                    socket.addHandshakeCompletedListener(hooks);
+
+                    socket.startHandshake();
+
+                    return socket;
+                }
+            });
+        }
+    }
+
+    @Test
+    public void test_handshake() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+        connection.doHandshake();
+
+        assertTrue(connection.clientHooks.isHandshakeCompleted);
+        assertTrue(connection.serverHooks.isHandshakeCompleted);
+    }
+
+    @Test
+    public void alpnWithProtocolListShouldSucceed() throws Exception {
+        TestConnection c = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        // Configure ALPN protocols
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        String[] serverAlpnProtocols = new String[]{"spdy/2", "foo", "bar"};
+
+        c.clientHooks.alpnProtocols = clientAlpnProtocols;
+        c.serverHooks.alpnProtocols = serverAlpnProtocols;
+
+        c.doHandshake();
+
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(c.client));
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(c.server));
+    }
+
+    @Test
+    public void alpnWithProtocolListShouldFail() throws Exception {
+        TestConnection c = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        // Configure ALPN protocols
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        String[] serverAlpnProtocols = new String[]{"h2", "bar", "baz"};
+
+        c.clientHooks.alpnProtocols = clientAlpnProtocols;
+        c.serverHooks.alpnProtocols = serverAlpnProtocols;
+
+        c.doHandshake();
+
+        assertNull(Conscrypt.getApplicationProtocol(c.client));
+        assertNull(Conscrypt.getApplicationProtocol(c.server));
+    }
+
+    @Test
+    public void alpnWithServerProtocolSelectorShouldSucceed() throws Exception {
+        TestConnection c = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        // Configure client ALPN protocols
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        c.clientHooks.alpnProtocols = clientAlpnProtocols;
+
+        // Configure server selector
+        ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class);
+        when(selector.selectApplicationProtocol(any(SSLSocket.class), anyListOf(String.class)))
+                .thenReturn("spdy/2");
+        c.serverHooks.alpnProtocolSelector = selector;
+
+        c.doHandshake();
+
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(c.client));
+        assertEquals("spdy/2", Conscrypt.getApplicationProtocol(c.server));
+    }
+
+    @Test
+    public void alpnWithServerProtocolSelectorShouldFail() throws Exception {
+        TestConnection c = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        // Configure client ALPN protocols
+        String[] clientAlpnProtocols = new String[]{"http/1.1", "foo", "spdy/2"};
+        c.clientHooks.alpnProtocols = clientAlpnProtocols;
+
+        // Configure server selector
+        ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class);
+        when(selector.selectApplicationProtocol(any(SSLSocket.class), anyListOf(String.class)))
+                .thenReturn("h2");
+        c.serverHooks.alpnProtocolSelector = selector;
+
+        c.doHandshake();
+
+        assertNull(Conscrypt.getApplicationProtocol(c.client));
+        assertNull(Conscrypt.getApplicationProtocol(c.server));
+    }
+
+    @Test
+    public void test_handshakeWithEmbeddedSCT() throws Exception {
+        TestConnection connection =
+                new TestConnection(new X509Certificate[] {certEmbedded, ca}, certKey);
+
+        connection.doHandshake();
+
+        assertTrue(connection.clientHooks.isHandshakeCompleted);
+        assertTrue(connection.serverHooks.isHandshakeCompleted);
+    }
+
+    @Test
+    public void test_handshakeWithSCTFromOCSPResponse() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        connection.serverHooks.ocspResponse = readTestFile("ocsp-response.der");
+
+        connection.doHandshake();
+
+        assertTrue(connection.clientHooks.isHandshakeCompleted);
+        assertTrue(connection.serverHooks.isHandshakeCompleted);
+    }
+
+    @Test
+    public void test_handshakeWithSCTFromTLSExtension() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        connection.serverHooks.sctTLSExtension = readTestFile("ct-signed-timestamp-list");
+
+        connection.doHandshake();
+
+        assertTrue(connection.clientHooks.isHandshakeCompleted);
+        assertTrue(connection.serverHooks.isHandshakeCompleted);
+    }
+
+    @Ignore("TODO(nathanmittler): Fix or remove")
+    @Test
+    public void test_handshake_failsWithMissingSCT() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        connection.doHandshake();
+        assertThat(connection.clientException, instanceOf(SSLHandshakeException.class));
+        assertThat(connection.clientException.getCause(), instanceOf(CertificateException.class));
+    }
+
+    @Ignore("TODO(nathanmittler): Fix or remove")
+    @Test
+    public void test_handshake_failsWithInvalidSCT() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        connection.serverHooks.sctTLSExtension = readTestFile("ct-signed-timestamp-list-invalid");
+
+        connection.doHandshake();
+        assertThat(connection.clientException, instanceOf(SSLHandshakeException.class));
+        assertThat(connection.clientException.getCause(), instanceOf(CertificateException.class));
+    }
+
+    @Test
+    @SuppressWarnings("deprecation")
+    public void setAlpnProtocolWithNullShouldSucceed() throws Exception {
+        ServerSocket listening = newServerSocket();
+        OpenSSLSocketImpl clientSocket = null;
+        try {
+            Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
+            clientSocket = (OpenSSLSocketImpl) socketType.newClientSocket(
+                    new ClientHooks().createContext(), listening, underlying);
+
+            // Both versions should succeed.
+            clientSocket.setAlpnProtocols((byte[]) null);
+            clientSocket.setAlpnProtocols((String[]) null);
+        } finally {
+            if (clientSocket != null) {
+                clientSocket.close();
+            }
+            listening.close();
+        }
+    }
+
+    // http://b/27250522
+    @Test
+    public void test_setSoTimeout_doesNotCreateSocketImpl() throws Exception {
+        ServerSocket listening = newServerSocket();
+        try {
+            Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
+            Socket socket = socketType.newClientSocket(
+                    new ClientHooks().createContext(), listening, underlying);
+            socketType.assertSocketType(socket);
+            socket.setSoTimeout(1000);
+            socket.close();
+
+            Field f = Socket.class.getDeclaredField("created");
+            f.setAccessible(true);
+            assertFalse(f.getBoolean(socket));
+        } finally {
+            listening.close();
+        }
+    }
+
+    @Test
+    public void test_setEnabledProtocols_FiltersSSLv3_HandshakeException() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+
+        connection.clientHooks = new ClientHooks() {
+            @Override
+            public AbstractConscryptSocket createSocket(ServerSocket listener) throws IOException {
+                AbstractConscryptSocket socket = super.createSocket(listener);
+                socket.setEnabledProtocols(new String[] {"SSLv3"});
+                assertEquals(
+                        "SSLv3 should be filtered out", 0, socket.getEnabledProtocols().length);
+                return socket;
+            }
+        };
+
+        connection.doHandshake();
+        assertThat(connection.clientException, instanceOf(SSLHandshakeException.class));
+        assertTrue(
+                connection.clientException.getMessage().contains("SSLv3 is no longer supported"));
+        assertThat(connection.serverException, instanceOf(SSLHandshakeException.class));
+
+        assertFalse(connection.clientHooks.isHandshakeCompleted);
+        assertFalse(connection.serverHooks.isHandshakeCompleted);
+    }
+
+    @Test
+    public void savedSessionWorksAfterClose() throws Exception {
+        TestConnection connection = new TestConnection(new X509Certificate[] {cert, ca}, certKey);
+        connection.doHandshake();
+
+        SSLSession session = connection.client.getSession();
+        String cipherSuite = session.getCipherSuite();
+
+        connection.client.close();
+
+        assertEquals(cipherSuite, session.getCipherSuite());
+    }
+
+    private static ServerSocket newServerSocket() throws IOException {
+        return new ServerSocket(0, 50, TestUtils.getLoopbackAddress());
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptTest.java
new file mode 100644
index 0000000..91c4f24
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptTest.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2018 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class ConscryptTest {
+
+    /**
+     * This confirms that the version machinery is working.
+     */
+    @Test
+    public void testVersionIsSensible() {
+        Conscrypt.Version version = Conscrypt.version();
+        assertNotNull(version);
+        // The version object should be a singleton
+        assertSame(version, Conscrypt.version());
+
+        assertTrue("Major version: " + version.major(), 1 <= version.major());
+        assertTrue("Minor version: " + version.minor(), 0 <= version.minor());
+        assertTrue("Patch version: " + version.patch(), 0 <= version.patch());
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/DuckTypedPSKKeyManagerTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/DuckTypedPSKKeyManagerTest.java
new file mode 100644
index 0000000..8d03c21
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/DuckTypedPSKKeyManagerTest.java
@@ -0,0 +1,321 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.Socket;
+import java.security.Key;
+import java.util.Arrays;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import junit.framework.TestCase;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DuckTypedPSKKeyManagerTest extends TestCase {
+    private SSLSocket mSSLSocket;
+    private SSLEngine mSSLEngine;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        SSLContext sslContext = SSLContext.getDefault();
+        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+        mSSLSocket = (SSLSocket) sslSocketFactory.createSocket();
+        mSSLEngine = sslContext.createSSLEngine();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            if (mSSLSocket != null) {
+                try {
+                    mSSLSocket.close();
+                } catch (Exception ignored) {}
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testDuckTypingFailsWhenOneMethodMissing() throws Exception {
+        try {
+            DuckTypedPSKKeyManager.getInstance(new AlmostPSKKeyManager());
+            fail();
+        } catch (NoSuchMethodException expected) {}
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testDuckTypingFailsWhenOneMethodReturnTypeIncompatible() throws Exception {
+        try {
+            assertNotNull(DuckTypedPSKKeyManager.getInstance(
+                    new KeyManagerOfferingAllPSKKeyManagerMethodsWithIncompatibleReturnTypes()));
+        fail();
+        } catch (NoSuchMethodException expected) {}
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testDuckTypingSucceedsWhenAllMethodsPresentWithExactReturnTypes() throws Exception {
+        assertNotNull(DuckTypedPSKKeyManager.getInstance(
+                new KeyManagerOfferingAllPSKKeyManagerMethodsWithExactReturnTypes()));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testDuckTypingSucceedsWhenAllMethodsPresentWithDifferentButCompatibleReturnTypes()
+            throws Exception {
+        assertNotNull(DuckTypedPSKKeyManager.getInstance(
+                new KeyManagerOfferingAllPSKKeyManagerMethodsWithCompatibleReturnTypes()));
+    }
+
+    public void testMethodInvocationDelegation() throws Exception {
+        // IMPLEMENTATION NOTE: We create a DuckTypedPSKKeyManager wrapping a Reflection Proxy,
+        // invoke each method of the PSKKeyManager interface on the DuckTypedPSKKeyManager instance,
+        // and assert that invocations on the Proxy are as expected and that values returned by the
+        // Proxy are returned to us.
+
+        MockInvocationHandler mockInvocationHandler = new MockInvocationHandler();
+        @SuppressWarnings("deprecation")
+        PSKKeyManager delegate = (PSKKeyManager) Proxy.newProxyInstance(
+                DuckTypedPSKKeyManager.class.getClassLoader(), new Class<?>[] {PSKKeyManager.class},
+                mockInvocationHandler);
+        @SuppressWarnings("deprecation")
+        PSKKeyManager pskKeyManager = DuckTypedPSKKeyManager.getInstance(delegate);
+        String identityHint = "hint";
+        String identity = "identity";
+
+        mockInvocationHandler.returnValue = identityHint;
+        assertSame(identityHint, pskKeyManager.chooseServerKeyIdentityHint(mSSLSocket));
+        assertEquals("chooseServerKeyIdentityHint",
+                mockInvocationHandler.lastInvokedMethod.getName());
+        assertEquals(Arrays.asList(new Class<?>[] {Socket.class}),
+                Arrays.asList(mockInvocationHandler.lastInvokedMethod.getParameterTypes()));
+        assertEquals(1, mockInvocationHandler.lastInvokedMethodArgs.length);
+        assertSame(mSSLSocket, mockInvocationHandler.lastInvokedMethodArgs[0]);
+
+        mockInvocationHandler.returnValue = identityHint;
+        assertSame(identityHint, pskKeyManager.chooseServerKeyIdentityHint(mSSLEngine));
+        assertEquals("chooseServerKeyIdentityHint",
+                mockInvocationHandler.lastInvokedMethod.getName());
+        assertEquals(Arrays.asList(new Class<?>[] {SSLEngine.class}),
+                Arrays.asList(mockInvocationHandler.lastInvokedMethod.getParameterTypes()));
+        assertEquals(1, mockInvocationHandler.lastInvokedMethodArgs.length);
+        assertSame(mSSLEngine, mockInvocationHandler.lastInvokedMethodArgs[0]);
+
+        mockInvocationHandler.returnValue = identity;
+        assertSame(identity, pskKeyManager.chooseClientKeyIdentity(identityHint, mSSLSocket));
+        assertEquals("chooseClientKeyIdentity", mockInvocationHandler.lastInvokedMethod.getName());
+        assertEquals(Arrays.asList(new Class<?>[] {String.class, Socket.class}),
+                Arrays.asList(mockInvocationHandler.lastInvokedMethod.getParameterTypes()));
+        assertEquals(2, mockInvocationHandler.lastInvokedMethodArgs.length);
+        assertSame(identityHint, mockInvocationHandler.lastInvokedMethodArgs[0]);
+        assertSame(mSSLSocket, mockInvocationHandler.lastInvokedMethodArgs[1]);
+
+        mockInvocationHandler.returnValue = identity;
+        assertSame(identity, pskKeyManager.chooseClientKeyIdentity(identityHint, mSSLEngine));
+        assertEquals("chooseClientKeyIdentity", mockInvocationHandler.lastInvokedMethod.getName());
+        assertEquals(Arrays.asList(new Class<?>[] {String.class, SSLEngine.class}),
+                Arrays.asList(mockInvocationHandler.lastInvokedMethod.getParameterTypes()));
+        assertEquals(2, mockInvocationHandler.lastInvokedMethodArgs.length);
+        assertSame(identityHint, mockInvocationHandler.lastInvokedMethodArgs[0]);
+        assertSame(mSSLEngine, mockInvocationHandler.lastInvokedMethodArgs[1]);
+
+        SecretKey key = new SecretKeySpec("arbitrary".getBytes("UTF-8"), "RAW");
+        mockInvocationHandler.returnValue = key;
+        assertSame(key, pskKeyManager.getKey(identityHint, identity, mSSLSocket));
+        assertEquals("getKey", mockInvocationHandler.lastInvokedMethod.getName());
+        assertEquals(Arrays.asList(new Class<?>[] {String.class, String.class, Socket.class}),
+                Arrays.asList(mockInvocationHandler.lastInvokedMethod.getParameterTypes()));
+        assertEquals(3, mockInvocationHandler.lastInvokedMethodArgs.length);
+        assertSame(identityHint, mockInvocationHandler.lastInvokedMethodArgs[0]);
+        assertSame(identity, mockInvocationHandler.lastInvokedMethodArgs[1]);
+        assertSame(mSSLSocket, mockInvocationHandler.lastInvokedMethodArgs[2]);
+
+        mockInvocationHandler.returnValue = key;
+        assertSame(key, pskKeyManager.getKey(identityHint, identity, mSSLEngine));
+        assertEquals("getKey", mockInvocationHandler.lastInvokedMethod.getName());
+        assertEquals(Arrays.asList(new Class<?>[] {String.class, String.class, SSLEngine.class}),
+                Arrays.asList(mockInvocationHandler.lastInvokedMethod.getParameterTypes()));
+        assertEquals(3, mockInvocationHandler.lastInvokedMethodArgs.length);
+        assertSame(identityHint, mockInvocationHandler.lastInvokedMethodArgs[0]);
+        assertSame(identity, mockInvocationHandler.lastInvokedMethodArgs[1]);
+        assertSame(mSSLEngine, mockInvocationHandler.lastInvokedMethodArgs[2]);
+    }
+
+    public void testMethodInvocationDelegationWithDifferentButCompatibleReturnType()
+            throws Exception {
+        // Check that nothing blows up when we invoke getKey which is declared to return
+        // SecretKeySpec rather than SecretKey as declared in the PSKKeyManager interface.
+        @SuppressWarnings("deprecation")
+        PSKKeyManager pskKeyManager = DuckTypedPSKKeyManager.getInstance(
+                new KeyManagerOfferingAllPSKKeyManagerMethodsWithCompatibleReturnTypes());
+        pskKeyManager.getKey(null, "", mSSLSocket);
+        pskKeyManager.getKey(null, "", mSSLEngine);
+    }
+
+    /**
+     * {@link KeyManager} which implements all methods of {@link PSKKeyManager} except for one.
+     */
+    @SuppressWarnings("unused")
+    private static class AlmostPSKKeyManager implements KeyManager {
+        public String chooseServerKeyIdentityHint(Socket socket) {
+            return null;
+        }
+
+        public String chooseServerKeyIdentityHint(SSLEngine engine) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, Socket socket) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+            return null;
+        }
+
+        public SecretKey getKey(String identityHint, String identity, Socket socket) {
+            return null;
+        }
+
+        // Missing method from the PSKKeyManager interface:
+        // SecretKey getKey(String identityHint, String identity, SSLEngine engine);
+    }
+
+    /**
+     * {@link KeyManager} which exposes all methods of the {@link PSKKeyManager} interface but does
+     * not implement the interface.
+     */
+    @SuppressWarnings("unused")
+    private static class KeyManagerOfferingAllPSKKeyManagerMethodsWithExactReturnTypes
+            implements KeyManager {
+        public String chooseServerKeyIdentityHint(Socket socket) {
+            return null;
+        }
+
+        public String chooseServerKeyIdentityHint(SSLEngine engine) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, Socket socket) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+            return null;
+        }
+
+        public SecretKey getKey(String identityHint, String identity, Socket socket) {
+            return null;
+        }
+
+        public SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
+            return null;
+        }
+    }
+
+    /**
+     * {@link KeyManager} which exposes all methods of the {@link PSKKeyManager} interface but does
+     * not implement the interface. Additionally, the return types of some methods are different
+     * but compatible with the {@code PSKKeyManager} interface.
+     */
+    @SuppressWarnings("unused")
+    private static class KeyManagerOfferingAllPSKKeyManagerMethodsWithCompatibleReturnTypes
+            implements KeyManager {
+        public String chooseServerKeyIdentityHint(Socket socket) {
+            return null;
+        }
+
+        public String chooseServerKeyIdentityHint(SSLEngine engine) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, Socket socket) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+            return null;
+        }
+
+        // PSKKeyManager's return type: SecretKey
+        public SecretKeySpec getKey(String identityHint, String identity, Socket socket) {
+            return null;
+        }
+
+        // PSKKeyManager's return type: SecretKey
+        public SecretKeySpec getKey(String identityHint, String identity, SSLEngine engine) {
+            return null;
+        }
+    }
+
+    /**
+     * {@link KeyManager} which exposes all methods of the {@link PSKKeyManager} interface but does
+     * not implement the interface. Additionally, the return types of some methods are incompatible
+     * with the {@code PSKKeyManager} interface.
+     */
+    @SuppressWarnings("unused")
+    private static class KeyManagerOfferingAllPSKKeyManagerMethodsWithIncompatibleReturnTypes
+            implements KeyManager {
+        public String chooseServerKeyIdentityHint(Socket socket) {
+            return null;
+        }
+
+        public String chooseServerKeyIdentityHint(SSLEngine engine) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, Socket socket) {
+            return null;
+        }
+
+        public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+            return null;
+        }
+
+        public SecretKey getKey(String identityHint, String identity, Socket socket) {
+            return null;
+        }
+
+        // PSKKeyManager's return type: SecretKey
+        public Key getKey(String identityHint, String identity, SSLEngine engine) {
+            return null;
+        }
+    }
+
+    static class MockInvocationHandler implements InvocationHandler {
+        Object returnValue;
+        Method lastInvokedMethod;
+        Object[] lastInvokedMethodArgs;
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            lastInvokedMethod = method;
+            lastInvokedMethodArgs = args;
+            return returnValue;
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/FileClientSessionCacheTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/FileClientSessionCacheTest.java
new file mode 100644
index 0000000..38d2b99
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/FileClientSessionCacheTest.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt;
+
+import java.io.File;
+import java.io.IOException;
+import junit.framework.TestCase;
+import com.android.org.conscrypt.javax.net.ssl.FakeSSLSession;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FileClientSessionCacheTest extends TestCase {
+
+    public void testMaxSize() throws IOException, InterruptedException {
+        String tmpDir = System.getProperty("java.io.tmpdir");
+        if (tmpDir == null) {
+            fail("Please set 'java.io.tmpdir' system property.");
+        }
+        File cacheDir = new File(tmpDir
+                + "/" + FileClientSessionCacheTest.class.getName() + "/cache");
+        final SSLClientSessionCache cache
+                = FileClientSessionCache.usingDirectory(cacheDir);
+        Thread[] threads = new Thread[10];
+        final int iterations = FileClientSessionCache.MAX_SIZE * 10;
+        for (int i = 0; i < threads.length; i++) {
+            final int id = i;
+            threads[i] = new Thread() {
+                @Override
+                public void run() {
+                    for (int i = 0; i < iterations; i++) {
+                        cache.putSessionData(new FakeSSLSession(id + "" + i), new byte[10]);
+                    }
+                }
+            };
+        }
+        for (Thread thread : threads) {
+            thread.start();
+        }
+        for (Thread thread : threads) {
+            thread.join();
+        }
+        assertEquals(FileClientSessionCache.MAX_SIZE, cacheDir.list().length);
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/MockSessionBuilder.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/MockSessionBuilder.java
new file mode 100644
index 0000000..f8a4a6d
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/MockSessionBuilder.java
@@ -0,0 +1,86 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.UTF_8;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Utility class for constructing mock sessions.
+ */
+final class MockSessionBuilder {
+    static final String DEFAULT_CIPHER_SUITE = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
+    static final int DEFAULT_PORT = 443;
+
+    private byte[] id;
+    private boolean valid = true;
+    private boolean singleUse = false;
+    private String host;
+    private int port = DEFAULT_PORT;
+    private String cipherSuite = DEFAULT_CIPHER_SUITE;
+    private byte[] encodedBytes = EmptyArray.BYTE;
+
+    MockSessionBuilder id(byte[] id) {
+        this.id = id;
+        return this;
+    }
+
+    MockSessionBuilder host(String host) {
+        this.host = host;
+        return this;
+    }
+
+    MockSessionBuilder port(int port) {
+        this.port = port;
+        return this;
+    }
+
+    MockSessionBuilder valid(boolean valid) {
+        this.valid = valid;
+        return this;
+    }
+
+    MockSessionBuilder cipherSuite(String cipherSuite) {
+        this.cipherSuite = cipherSuite;
+        return this;
+    }
+
+    MockSessionBuilder encodedBytes(byte[] encodedBytes) {
+        this.encodedBytes = encodedBytes;
+        return this;
+    }
+
+    MockSessionBuilder singleUse(boolean singleUse) {
+        this.singleUse = singleUse;
+        return this;
+    }
+
+    NativeSslSession build() {
+        NativeSslSession session = mock(NativeSslSession.class);
+        byte[] id = this.id == null ? host.getBytes(UTF_8) : this.id;
+        when(session.getId()).thenReturn(id);
+        when(session.isValid()).thenReturn(valid);
+        when(session.isSingleUse()).thenReturn(singleUse);
+        when(session.getProtocol()).thenReturn(TestUtils.getProtocols()[0]);
+        when(session.getPeerHost()).thenReturn(host);
+        when(session.getPeerPort()).thenReturn(port);
+        when(session.getCipherSuite()).thenReturn(cipherSuite);
+        when(session.toBytes()).thenReturn(encodedBytes);
+        return session;
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeCryptoTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeCryptoTest.java
new file mode 100644
index 0000000..e6c43f4
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeCryptoTest.java
@@ -0,0 +1,3140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.NativeConstants.SSL_MODE_CBC_RECORD_SPLITTING;
+import static com.android.org.conscrypt.NativeConstants.SSL_MODE_ENABLE_FALSE_START;
+import static com.android.org.conscrypt.NativeConstants.SSL_OP_CIPHER_SERVER_PREFERENCE;
+import static com.android.org.conscrypt.NativeConstants.SSL_OP_NO_TICKET;
+import static com.android.org.conscrypt.NativeConstants.SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+import static com.android.org.conscrypt.NativeConstants.SSL_VERIFY_NONE;
+import static com.android.org.conscrypt.NativeConstants.SSL_VERIFY_PEER;
+import static com.android.org.conscrypt.NativeConstants.TLS1_1_VERSION;
+import static com.android.org.conscrypt.NativeConstants.TLS1_2_VERSION;
+import static com.android.org.conscrypt.NativeConstants.TLS1_VERSION;
+import static com.android.org.conscrypt.TestUtils.openTestFile;
+import static com.android.org.conscrypt.TestUtils.readTestFile;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+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.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECPrivateKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLProtocolException;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.NativeCrypto.SSLHandshakeCallbacks;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+import com.android.org.conscrypt.io.IoUtils;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class NativeCryptoTest {
+    private static final long NULL = 0;
+    private static final FileDescriptor INVALID_FD = new FileDescriptor();
+    private static final SSLHandshakeCallbacks DUMMY_CB =
+            new TestSSLHandshakeCallbacks(null, 0, null);
+
+    private static final long TIMEOUT_SECONDS = 5;
+
+    private static OpenSSLKey SERVER_PRIVATE_KEY;
+    private static OpenSSLX509Certificate[] SERVER_CERTIFICATES_HOLDER;
+    private static long[] SERVER_CERTIFICATE_REFS;
+    private static byte[][] ENCODED_SERVER_CERTIFICATES;
+    private static OpenSSLKey CLIENT_PRIVATE_KEY;
+    private static OpenSSLX509Certificate[] CLIENT_CERTIFICATES_HOLDER;
+    private static long[] CLIENT_CERTIFICATE_REFS;
+    private static byte[][] ENCODED_CLIENT_CERTIFICATES;
+    private static byte[][] CA_PRINCIPALS;
+    private static OpenSSLKey CHANNEL_ID_PRIVATE_KEY;
+    private static byte[] CHANNEL_ID;
+    private static Method m_Platform_getFileDescriptor;
+
+    @BeforeClass
+    public static void getPlatformMethods() throws Exception {
+        Class<?> c_Platform = TestUtils.conscryptClass("Platform");
+        m_Platform_getFileDescriptor =
+                c_Platform.getDeclaredMethod("getFileDescriptor", Socket.class);
+        m_Platform_getFileDescriptor.setAccessible(true);
+    }
+
+    private static OpenSSLKey getServerPrivateKey() {
+        initCerts();
+        return SERVER_PRIVATE_KEY;
+    }
+
+    private static long[] getServerCertificateRefs() {
+        initCerts();
+        return SERVER_CERTIFICATE_REFS;
+    }
+
+    private static byte[][] getEncodedServerCertificates() {
+        initCerts();
+        return ENCODED_SERVER_CERTIFICATES;
+    }
+
+    private static OpenSSLKey getClientPrivateKey() {
+        initCerts();
+        return CLIENT_PRIVATE_KEY;
+    }
+
+    private static long[] getClientCertificateRefs() {
+        initCerts();
+        return CLIENT_CERTIFICATE_REFS;
+    }
+
+    private static byte[][] getEncodedClientCertificates() {
+        initCerts();
+        return ENCODED_CLIENT_CERTIFICATES;
+    }
+
+    private static byte[][] getCaPrincipals() {
+        initCerts();
+        return CA_PRINCIPALS;
+    }
+
+    /**
+     * Lazily create shared test certificates.
+     */
+    private static synchronized void initCerts() {
+        if (SERVER_PRIVATE_KEY != null) {
+            return;
+        }
+
+        try {
+            PrivateKeyEntry serverPrivateKeyEntry =
+                    TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+            SERVER_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(serverPrivateKeyEntry.getPrivateKey());
+            SERVER_CERTIFICATES_HOLDER =
+                    encodeCertificateList(serverPrivateKeyEntry.getCertificateChain());
+            SERVER_CERTIFICATE_REFS = getCertificateReferences(SERVER_CERTIFICATES_HOLDER);
+            ENCODED_SERVER_CERTIFICATES = getEncodedCertificates(SERVER_CERTIFICATES_HOLDER);
+
+            PrivateKeyEntry clientPrivateKeyEntry =
+                    TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
+            CLIENT_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(clientPrivateKeyEntry.getPrivateKey());
+            CLIENT_CERTIFICATES_HOLDER =
+                    encodeCertificateList(clientPrivateKeyEntry.getCertificateChain());
+            CLIENT_CERTIFICATE_REFS = getCertificateReferences(CLIENT_CERTIFICATES_HOLDER);
+            ENCODED_CLIENT_CERTIFICATES = getEncodedCertificates(CLIENT_CERTIFICATES_HOLDER);
+
+            KeyStore ks = TestKeyStore.getClient().keyStore;
+            String caCertAlias = ks.aliases().nextElement();
+            X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias);
+            X500Principal principal = certificate.getIssuerX500Principal();
+            CA_PRINCIPALS = new byte[][] {principal.getEncoded()};
+            initChannelIdKey();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static long[] getCertificateReferences(OpenSSLX509Certificate[] certs) {
+        final long[] certRefs = new long[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            certRefs[i] = certs[i].getContext();
+        }
+        return certRefs;
+    }
+
+    private static byte[][] getEncodedCertificates(OpenSSLX509Certificate[] certs) {
+        try {
+            final byte[][] encoded = new byte[certs.length][];
+            for (int i = 0; i < certs.length; i++) {
+                encoded[i] = certs[i].getEncoded();
+            }
+            return encoded;
+        } catch (CertificateEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static OpenSSLX509Certificate[] encodeCertificateList(Certificate[] chain)
+            throws CertificateEncodingException {
+        final OpenSSLX509Certificate[] openSslCerts = new OpenSSLX509Certificate[chain.length];
+        for (int i = 0; i < chain.length; i++) {
+            openSslCerts[i] = OpenSSLX509Certificate.fromCertificate(chain[i]);
+        }
+        return openSslCerts;
+    }
+
+    private static synchronized void initChannelIdKey() throws Exception {
+        if (CHANNEL_ID_PRIVATE_KEY != null) {
+            return;
+        }
+
+        // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1
+        OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1");
+        BigInteger s = new BigInteger(
+                "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16);
+        CHANNEL_ID_PRIVATE_KEY =
+                new OpenSSLECPrivateKey(new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec()))
+                        .getOpenSSLKey();
+
+        // Channel ID is the concatenation of the X and Y coordinates of the public key.
+        CHANNEL_ID = new BigInteger(
+                "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b"
+                        + "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77",
+                16).toByteArray();
+    }
+
+    private static RSAPrivateCrtKey generateRsaKey() throws Exception {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        kpg.initialize(512);
+
+        KeyPair keyPair = kpg.generateKeyPair();
+        return (RSAPrivateCrtKey) keyPair.getPrivate();
+    }
+
+    private static NativeRef.EVP_PKEY getRsaPkey(RSAPrivateCrtKey privKey) throws Exception {
+        return new NativeRef.EVP_PKEY(NativeCrypto.EVP_PKEY_new_RSA(
+                privKey.getModulus().toByteArray(), privKey.getPublicExponent().toByteArray(),
+                privKey.getPrivateExponent().toByteArray(), privKey.getPrimeP().toByteArray(),
+                privKey.getPrimeQ().toByteArray(), privKey.getPrimeExponentP().toByteArray(),
+                privKey.getPrimeExponentQ().toByteArray(),
+                privKey.getCrtCoefficient().toByteArray()));
+    }
+
+    public static void assertEqualSessions(long expected, long actual) {
+        assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected),
+                NativeCrypto.SSL_SESSION_session_id(actual));
+    }
+    public static void assertEqualByteArrays(byte[] expected, byte[] actual) {
+        assertEquals(Arrays.toString(expected), Arrays.toString(actual));
+    }
+
+    public static void assertEqualPrincipals(byte[][] expected, byte[][] actual) {
+        assertEqualByteArrays(expected, actual);
+    }
+
+    public static void assertEqualCertificateChains(long[] expected, long[] actual) {
+        assertEquals(expected.length, actual.length);
+        for (int i = 0; i < expected.length; i++) {
+            NativeCrypto.X509_cmp(expected[i], null, actual[i], null);
+        }
+    }
+
+    public static void assertEqualByteArrays(byte[][] expected, byte[][] actual) {
+        assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_cmp_BothNullParameters() throws Exception {
+        NativeCrypto.EVP_PKEY_cmp(null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_cmp_withNullShouldThrow() throws Exception {
+        RSAPrivateCrtKey privKey1 = generateRsaKey();
+        NativeRef.EVP_PKEY pkey1 = getRsaPkey(privKey1);
+        assertNotSame(NULL, pkey1);
+        NativeCrypto.EVP_PKEY_cmp(pkey1, null);
+    }
+
+    @Test
+    public void test_EVP_PKEY_cmp() throws Exception {
+        RSAPrivateCrtKey privKey1 = generateRsaKey();
+
+        NativeRef.EVP_PKEY pkey1 = getRsaPkey(privKey1);
+        assertNotSame(NULL, pkey1);
+
+        NativeRef.EVP_PKEY pkey1_copy = getRsaPkey(privKey1);
+        assertNotSame(NULL, pkey1_copy);
+
+        NativeRef.EVP_PKEY pkey2 = getRsaPkey(generateRsaKey());
+        assertNotSame(NULL, pkey2);
+
+        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));
+    }
+
+    @Test
+    public void test_SSL_CTX_new() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        assertTrue(c != NULL);
+        long c2 = NativeCrypto.SSL_CTX_new();
+        assertTrue(c != c2);
+        NativeCrypto.SSL_CTX_free(c, null);
+        NativeCrypto.SSL_CTX_free(c2, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_SSL_CTX_free_NullArgument() throws Exception {
+        NativeCrypto.SSL_CTX_free(NULL, null);
+    }
+
+    @Test
+    public void test_SSL_CTX_free() throws Exception {
+        NativeCrypto.SSL_CTX_free(NativeCrypto.SSL_CTX_new(), null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_CTX_set_session_id_context_NullContextArgument() throws Exception {
+        NativeCrypto.SSL_CTX_set_session_id_context(NULL, null, new byte[0]);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_CTX_set_session_id_context_withNullShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        try {
+            NativeCrypto.SSL_CTX_set_session_id_context(c, null, null);
+        } finally {
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void test_SSL_CTX_set_session_id_context_withInvalidIdShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        try {
+            NativeCrypto.SSL_CTX_set_session_id_context(c, null, new byte[33]);
+        } finally {
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void test_SSL_CTX_set_session_id_context() throws Exception {
+        byte[] empty = new byte[0];
+
+        long c = NativeCrypto.SSL_CTX_new();
+        try {
+            NativeCrypto.SSL_CTX_set_session_id_context(c, null, empty);
+            NativeCrypto.SSL_CTX_set_session_id_context(c, null, new byte[32]);
+        } finally {
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void test_SSL_new() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        assertTrue(s != NULL);
+        assertTrue((NativeCrypto.SSL_get_options(s, null) & SSL_OP_NO_TICKET) != 0);
+
+        long s2 = NativeCrypto.SSL_new(c, null);
+        assertTrue(s != s2);
+        NativeCrypto.SSL_free(s2, null);
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void setLocalCertsAndPrivateKey_withNullSSLShouldThrow() throws Exception {
+        NativeCrypto.setLocalCertsAndPrivateKey(
+                NULL, null, getEncodedServerCertificates(), getServerPrivateKey().getNativeRef());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void setLocalCertsAndPrivateKey_withNullCertificatesShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.setLocalCertsAndPrivateKey(s, null, null, getServerPrivateKey().getNativeRef());
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void setLocalCertsAndPrivateKey_withNullKeyShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.setLocalCertsAndPrivateKey(s, null, getEncodedServerCertificates(), null);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void setLocalCertsAndPrivateKey() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        NativeCrypto.setLocalCertsAndPrivateKey(
+                s, null, getEncodedServerCertificates(), getServerPrivateKey().getNativeRef());
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set1_tls_channel_id_withNullChannelShouldThrow() throws Exception {
+        NativeCrypto.SSL_set1_tls_channel_id(NULL, null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set1_tls_channel_id_withNullKeyShouldThrow() throws Exception {
+        initChannelIdKey();
+
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_set1_tls_channel_id(s, null, null);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void test_SSL_use_PrivateKey_for_tls_channel_id() throws Exception {
+        initChannelIdKey();
+
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        // Use the key natively. This works because the initChannelIdKey method ensures that the
+        // key is backed by OpenSSL.
+        NativeCrypto.SSL_set1_tls_channel_id(s, null, CHANNEL_ID_PRIVATE_KEY.getNativeRef());
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_get_mode_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_get_mode(NULL, null);
+    }
+
+    @Test
+    public void test_SSL_get_mode() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        assertTrue(NativeCrypto.SSL_get_mode(s, null) != 0);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_mode_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_mode(NULL, null, 0);
+    }
+
+    @Test
+    public void test_SSL_set_mode_and_clear_mode() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        // check SSL_MODE_ENABLE_FALSE_START on by default for BoringSSL
+        assertEquals(SSL_MODE_ENABLE_FALSE_START,
+                NativeCrypto.SSL_get_mode(s, null) & SSL_MODE_ENABLE_FALSE_START);
+        // check SSL_MODE_CBC_RECORD_SPLITTING off by default
+        assertEquals(0, NativeCrypto.SSL_get_mode(s, null) & SSL_MODE_CBC_RECORD_SPLITTING);
+
+        // set SSL_MODE_ENABLE_FALSE_START on
+        NativeCrypto.SSL_set_mode(s, null, SSL_MODE_ENABLE_FALSE_START);
+        assertTrue((NativeCrypto.SSL_get_mode(s, null) & SSL_MODE_ENABLE_FALSE_START) != 0);
+        // clear SSL_MODE_ENABLE_FALSE_START off
+        NativeCrypto.SSL_clear_mode(s, null, SSL_MODE_ENABLE_FALSE_START);
+        assertTrue((NativeCrypto.SSL_get_mode(s, null) & SSL_MODE_ENABLE_FALSE_START) == 0);
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_get_options_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_get_options(NULL, null);
+    }
+
+    @Test
+    public void test_SSL_get_options() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        assertTrue(NativeCrypto.SSL_get_options(s, null) != 0);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_options_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_options(NULL, null, 0);
+    }
+
+    @Test
+    public void test_SSL_set_options() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        assertTrue((NativeCrypto.SSL_get_options(s, null) & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0);
+        NativeCrypto.SSL_set_options(s, null, SSL_OP_CIPHER_SERVER_PREFERENCE);
+        assertTrue((NativeCrypto.SSL_get_options(s, null) & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_clear_options_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_clear_options(NULL, null, 0);
+    }
+
+    @Test
+    public void test_SSL_clear_options() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        assertTrue((NativeCrypto.SSL_get_options(s, null) & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0);
+        NativeCrypto.SSL_set_options(s, null, SSL_OP_CIPHER_SERVER_PREFERENCE);
+        assertTrue((NativeCrypto.SSL_get_options(s, null) & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0);
+        NativeCrypto.SSL_clear_options(s, null, SSL_OP_CIPHER_SERVER_PREFERENCE);
+        assertTrue((NativeCrypto.SSL_get_options(s, null) & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_protocol_versions_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_protocol_versions(NULL, null, 0, 0);
+    }
+
+    @Test
+    public void SSL_set_protocol_versions() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        assertEquals(1, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_VERSION, TLS1_1_VERSION));
+        assertEquals(1, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_2_VERSION, TLS1_2_VERSION));
+        assertEquals(0, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_2_VERSION + 413, TLS1_1_VERSION));
+        assertEquals(0, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_1_VERSION, TLS1_2_VERSION + 413));
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_cipher_lists_withNullSslShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_cipher_lists(NULL, null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_cipher_lists_withNullCiphersShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_set_cipher_lists(s, null, null);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_SSL_set_cipher_lists_withNullCipherShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_set_cipher_lists(s, null, new String[] {null});
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void SSL_set_cipher_lists_withEmptyCiphersShouldSucceed() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        // Explicitly checking that the empty list is allowed.
+        // b/21816861
+        NativeCrypto.SSL_set_cipher_lists(s, null, new String[] {});
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test
+    public void SSL_set_cipher_lists_withIllegalCipherShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        // see OpenSSL ciphers man page
+        String[] illegals = new String[] {// empty
+                "",
+                // never standardized
+                "EXP1024-DES-CBC-SHA",
+                // IDEA
+                "IDEA-CBC-SHA", "IDEA-CBC-MD5"};
+
+        for (String illegal : illegals) {
+            try {
+                NativeCrypto.SSL_set_cipher_lists(s, null, new String[] {illegal});
+                fail("Exception now thrown for illegal cipher: " + illegal);
+            } catch (IllegalArgumentException expected) {
+                // Expected.
+            }
+        }
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test
+    public void SSL_set_cipher_lists_withValidCiphersShouldSucceed() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        List<String> ciphers = new ArrayList<String>(NativeCrypto.SUPPORTED_TLS_1_2_CIPHER_SUITES_SET);
+        NativeCrypto.SSL_set_cipher_lists(s, null, ciphers.toArray(new String[ciphers.size()]));
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_verify_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_verify(NULL, null, 0);
+    }
+
+    @Test
+    public void test_SSL_set_verify() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        NativeCrypto.SSL_set_verify(s, null, SSL_VERIFY_NONE);
+        NativeCrypto.SSL_set_verify(s, null, SSL_VERIFY_PEER);
+        NativeCrypto.SSL_set_verify(s, null, SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
+        NativeCrypto.SSL_set_verify(s, null, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    private static final boolean DEBUG = false;
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class Hooks {
+        String negotiatedCipherSuite;
+        private OpenSSLKey channelIdPrivateKey;
+        boolean pskEnabled;
+        byte[] pskKey;
+        List<String> enabledCipherSuites;
+
+        /**
+         * @throws SSLException if an error occurs creating the context.
+         */
+        public long getContext() throws SSLException {
+            return NativeCrypto.SSL_CTX_new();
+        }
+
+        public long beforeHandshake(long context) throws SSLException {
+            long s = NativeCrypto.SSL_new(context, null);
+            // Limit cipher suites to a known set so authMethod is known.
+            List<String> cipherSuites = new ArrayList<String>();
+            if (enabledCipherSuites == null) {
+                cipherSuites.add("ECDHE-RSA-AES128-SHA");
+                if (pskEnabled) {
+                    // In TLS-PSK the client indicates that PSK key exchange is desired by offering
+                    // at least one PSK cipher suite.
+                    cipherSuites.add(0, "PSK-AES128-CBC-SHA");
+                }
+            } else {
+                cipherSuites.addAll(enabledCipherSuites);
+            }
+            // Protocol list is included for determining whether to send TLS_FALLBACK_SCSV
+            NativeCrypto.setEnabledCipherSuites(s, null,
+                    cipherSuites.toArray(new String[cipherSuites.size()]),
+                    new String[] {"TLSv1.2"});
+
+            if (channelIdPrivateKey != null) {
+                NativeCrypto.SSL_set1_tls_channel_id(s, null, channelIdPrivateKey.getNativeRef());
+            }
+            return s;
+        }
+        public void configureCallbacks(
+                @SuppressWarnings("unused") TestSSLHandshakeCallbacks callbacks) {}
+        public void clientCertificateRequested(@SuppressWarnings("unused") long s)
+                throws CertificateEncodingException, SSLException {}
+        public void afterHandshake(long session, long ssl, long context, Socket socket,
+                FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+            if (session != NULL) {
+                negotiatedCipherSuite = NativeCrypto.SSL_SESSION_cipher(session);
+                NativeCrypto.SSL_SESSION_free(session);
+            }
+            if (ssl != NULL) {
+                try {
+                    NativeCrypto.SSL_shutdown(ssl, null, fd, callback);
+                } catch (IOException e) {
+                    // Expected.
+                }
+                NativeCrypto.SSL_free(ssl, null);
+            }
+            if (context != NULL) {
+                NativeCrypto.SSL_CTX_free(context, null);
+            }
+            if (socket != null) {
+                socket.close();
+            }
+        }
+    }
+
+    static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks {
+        private final Socket socket;
+        private final long sslNativePointer;
+        private final Hooks hooks;
+
+        TestSSLHandshakeCallbacks(Socket socket, long sslNativePointer, Hooks hooks) {
+            this.socket = socket;
+            this.sslNativePointer = sslNativePointer;
+            this.hooks = hooks;
+        }
+
+        private long[] certificateChainRefs;
+        private String authMethod;
+        private boolean verifyCertificateChainCalled;
+
+        @Override
+        public void verifyCertificateChain(byte[][] certs, String authMethod)
+                throws CertificateException {
+            certificateChainRefs = new long[certs.length];
+            for (int i = 0; i < certs.length; ++i) {
+                byte[] cert = certs[i];
+                try {
+                    certificateChainRefs[i] = NativeCrypto.d2i_X509(cert);
+                } catch (ParsingException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+            this.authMethod = authMethod;
+            this.verifyCertificateChainCalled = true;
+        }
+
+        private byte[] keyTypes;
+        private int[] signatureAlgs;
+        private byte[][] asn1DerEncodedX500Principals;
+        private boolean clientCertificateRequestedCalled;
+
+        @Override
+        public void clientCertificateRequested(
+                byte[] keyTypes, int[] signatureAlgs, byte[][] asn1DerEncodedX500Principals)
+                throws CertificateEncodingException, SSLException {
+            if (DEBUG) {
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
+                        + " clientCertificateRequested"
+                        + " keyTypes=" + Arrays.toString(keyTypes)
+                        + " asn1DerEncodedX500Principals="
+                        + Arrays.toString(asn1DerEncodedX500Principals));
+            }
+            this.keyTypes = keyTypes;
+            this.signatureAlgs = signatureAlgs;
+            this.asn1DerEncodedX500Principals = asn1DerEncodedX500Principals;
+            this.clientCertificateRequestedCalled = true;
+            if (hooks != null) {
+                hooks.clientCertificateRequested(sslNativePointer);
+            }
+        }
+
+        private boolean handshakeCompletedCalled;
+
+        @Override
+        public void onSSLStateChange(int type, int val) {
+            if (DEBUG) {
+                System.out.println(
+                        "ssl=0x" + Long.toString(sslNativePointer, 16) + " onSSLStateChange");
+            }
+            this.handshakeCompletedCalled = true;
+        }
+
+        Socket getSocket() {
+            return socket;
+        }
+
+        private boolean clientPSKKeyRequestedInvoked;
+        private String clientPSKKeyRequestedIdentityHint;
+        private int clientPSKKeyRequestedResult;
+        private byte[] clientPSKKeyRequestedResultKey;
+        private byte[] clientPSKKeyRequestedResultIdentity;
+
+        @Override
+        public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key) {
+            if (DEBUG) {
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
+                        + " clientPSKKeyRequested"
+                        + " identityHint=" + identityHint + " identity capacity=" + identity.length
+                        + " key capacity=" + key.length);
+            }
+            clientPSKKeyRequestedInvoked = true;
+            clientPSKKeyRequestedIdentityHint = identityHint;
+            if (clientPSKKeyRequestedResultKey != null) {
+                System.arraycopy(clientPSKKeyRequestedResultKey, 0, key, 0,
+                        clientPSKKeyRequestedResultKey.length);
+            }
+            if (clientPSKKeyRequestedResultIdentity != null) {
+                System.arraycopy(clientPSKKeyRequestedResultIdentity, 0, identity, 0,
+                        Math.min(clientPSKKeyRequestedResultIdentity.length, identity.length));
+            }
+            return clientPSKKeyRequestedResult;
+        }
+
+        private boolean serverPSKKeyRequestedInvoked;
+        private int serverPSKKeyRequestedResult;
+        private byte[] serverPSKKeyRequestedResultKey;
+        private String serverPSKKeyRequestedIdentityHint;
+        private String serverPSKKeyRequestedIdentity;
+
+        @Override
+        public int serverPSKKeyRequested(String identityHint, String identity, byte[] key) {
+            if (DEBUG) {
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
+                        + " serverPSKKeyRequested"
+                        + " identityHint=" + identityHint + " identity=" + identity
+                        + " key capacity=" + key.length);
+            }
+            serverPSKKeyRequestedInvoked = true;
+            serverPSKKeyRequestedIdentityHint = identityHint;
+            serverPSKKeyRequestedIdentity = identity;
+            if (serverPSKKeyRequestedResultKey != null) {
+                System.arraycopy(serverPSKKeyRequestedResultKey, 0, key, 0,
+                        serverPSKKeyRequestedResultKey.length);
+            }
+            return serverPSKKeyRequestedResult;
+        }
+
+        private boolean onNewSessionEstablishedInvoked;
+        private boolean onNewSessionEstablishedSaveSession;
+        private long onNewSessionEstablishedSessionNativePointer;
+
+        @Override
+        public void onNewSessionEstablished(long sslSessionNativePtr) {
+            if (DEBUG) {
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
+                        + " onNewSessionCreated"
+                        + " ssl=0x" + Long.toString(sslSessionNativePtr, 16));
+            }
+            onNewSessionEstablishedInvoked = true;
+
+            if (onNewSessionEstablishedSaveSession) {
+                NativeCrypto.SSL_SESSION_up_ref(sslSessionNativePtr);
+                onNewSessionEstablishedSessionNativePointer = sslSessionNativePtr;
+            }
+        }
+
+        @Override
+        public long serverSessionRequested(byte[] id) {
+            // TODO(nathanmittler): Implement server-side caching for TLS < 1.3
+            return 0;
+        }
+    }
+
+    static class ClientHooks extends Hooks {
+        private String pskIdentity;
+
+        @Override
+        public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) {
+            super.configureCallbacks(callbacks);
+            if (pskEnabled) {
+                if (pskIdentity != null) {
+                    // Create a NULL-terminated modified UTF-8 representation of pskIdentity.
+                    byte[] b;
+                    try {
+                        b = pskIdentity.getBytes("UTF-8");
+                    } catch (UnsupportedEncodingException e) {
+                        throw new RuntimeException("UTF-8 encoding not supported", e);
+                    }
+                    callbacks.clientPSKKeyRequestedResultIdentity = Arrays.copyOf(b, b.length + 1);
+                }
+                callbacks.clientPSKKeyRequestedResultKey = pskKey;
+                callbacks.clientPSKKeyRequestedResult = (pskKey != null) ? pskKey.length : 0;
+            }
+        }
+
+        @Override
+        public long beforeHandshake(long c) throws SSLException {
+            long s = super.beforeHandshake(c);
+            if (pskEnabled) {
+                NativeCrypto.set_SSL_psk_client_callback_enabled(s, null, true);
+            }
+            return s;
+        }
+    }
+
+    static class ServerHooks extends Hooks {
+        private final OpenSSLKey privateKey;
+        private final byte[][] certificates;
+        private boolean channelIdEnabled;
+        private byte[] channelIdAfterHandshake;
+        private Throwable channelIdAfterHandshakeException;
+
+        private String pskIdentityHint;
+
+        public ServerHooks() {
+            this(null, null);
+        }
+
+        ServerHooks(OpenSSLKey privateKey, byte[][] certificates) {
+            this.privateKey = privateKey;
+            this.certificates = certificates;
+        }
+
+        @Override
+        public long beforeHandshake(long c) throws SSLException {
+            long s = super.beforeHandshake(c);
+            if (privateKey != null && certificates != null) {
+                NativeCrypto.setLocalCertsAndPrivateKey(s, null, certificates, privateKey.getNativeRef());
+            }
+            if (channelIdEnabled) {
+                NativeCrypto.SSL_enable_tls_channel_id(s, null);
+            }
+            if (pskEnabled) {
+                NativeCrypto.set_SSL_psk_server_callback_enabled(s, null, true);
+                NativeCrypto.SSL_use_psk_identity_hint(s, null, pskIdentityHint);
+            }
+            NativeCrypto.SSL_set_verify(s, null, SSL_VERIFY_NONE);
+            return s;
+        }
+
+        @Override
+        public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) {
+            super.configureCallbacks(callbacks);
+            if (pskEnabled) {
+                callbacks.serverPSKKeyRequestedResultKey = pskKey;
+                callbacks.serverPSKKeyRequestedResult = (pskKey != null) ? pskKey.length : 0;
+            }
+        }
+
+        @Override
+        public void afterHandshake(long session, long ssl, long context, Socket socket,
+                FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+            if (channelIdEnabled) {
+                try {
+                    channelIdAfterHandshake = NativeCrypto.SSL_get_tls_channel_id(ssl, null);
+                } catch (Exception e) {
+                    channelIdAfterHandshakeException = e;
+                }
+            }
+            super.afterHandshake(session, ssl, context, socket, fd, callback);
+        }
+
+        @Override
+        public void clientCertificateRequested(long s) {
+            fail("Server asked for client certificates");
+        }
+    }
+
+    public static Future<TestSSLHandshakeCallbacks> handshake(final ServerSocket listener,
+            final int timeout, final boolean client, final Hooks hooks, final byte[] alpnProtocols,
+            final ApplicationProtocolSelectorAdapter alpnSelector) {
+        ExecutorService executor = Executors.newSingleThreadExecutor();
+        Future<TestSSLHandshakeCallbacks> future =
+                executor.submit(new Callable<TestSSLHandshakeCallbacks>() {
+                    @Override
+                    public TestSSLHandshakeCallbacks call() throws Exception {
+                        @SuppressWarnings("resource")
+                        // Socket needs to remain open after the handshake
+                        Socket socket = (client ? new Socket(listener.getInetAddress(),
+                                                          listener.getLocalPort())
+                                                : listener.accept());
+                        if (timeout == -1) {
+                            return new TestSSLHandshakeCallbacks(socket, 0, null);
+                        }
+                        FileDescriptor fd =
+                                (FileDescriptor) m_Platform_getFileDescriptor.invoke(
+                                        null, socket);
+                        long c = hooks.getContext();
+                        long s = hooks.beforeHandshake(c);
+                        TestSSLHandshakeCallbacks callback =
+                                new TestSSLHandshakeCallbacks(socket, s, hooks);
+                        hooks.configureCallbacks(callback);
+                        if (DEBUG) {
+                            System.out.println("ssl=0x" + Long.toString(s, 16) + " handshake"
+                                    + " context=0x" + Long.toString(c, 16) + " socket=" + socket
+                                    + " fd=0x" + Long.toString(System.identityHashCode(fd), 16)
+                                    + " timeout=" + timeout + " client=" + client);
+                        }
+                        long session = NULL;
+                        try {
+                            if (client) {
+                                NativeCrypto.SSL_set_connect_state(s, null);
+                            } else {
+                                NativeCrypto.SSL_set_accept_state(s, null);
+                            }
+                            if (alpnProtocols != null) {
+                                NativeCrypto.setApplicationProtocols(s, null, client, alpnProtocols);
+                            }
+                            if (!client && alpnSelector != null) {
+                                NativeCrypto.setApplicationProtocolSelector(s, null, alpnSelector);
+                            }
+                            NativeCrypto.SSL_do_handshake(s, null, fd, callback, timeout);
+                            session = NativeCrypto.SSL_get1_session(s, null);
+                            if (DEBUG) {
+                                System.out.println("ssl=0x" + Long.toString(s, 16)
+                                        + " handshake"
+                                        + " session=0x" + Long.toString(session, 16));
+                            }
+                        } finally {
+                            // Ensure afterHandshake is called to free resources
+                            hooks.afterHandshake(session, s, c, socket, fd, callback);
+                        }
+                        return callback;
+                    }
+                });
+        executor.shutdown();
+        return future;
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_SSL_do_handshake_NULL_SSL() throws Exception {
+        NativeCrypto.SSL_do_handshake(NULL, null, null, null, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_SSL_do_handshake_withNullFdShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        NativeCrypto.SSL_set_connect_state(s, null);
+        try {
+            NativeCrypto.SSL_do_handshake(s, null, null, null, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_SSL_do_handshake_withNullShcShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        NativeCrypto.SSL_set_connect_state(s, null);
+        try {
+            NativeCrypto.SSL_do_handshake(s, null, INVALID_FD, null, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_normal() throws Exception {
+        // normal client and server case
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks();
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback.authMethod);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertFalse(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_reusedSession() throws Exception {
+        // normal client and server case
+        final ServerSocket listener = newServerSocket();
+
+        Future<TestSSLHandshakeCallbacks> client1 = handshake(listener, 0, true, new ClientHooks() {
+            @Override
+            public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) {
+                callbacks.onNewSessionEstablishedSaveSession = true;
+            }
+        }, null, null);
+        Future<TestSSLHandshakeCallbacks> server1 = handshake(listener, 0,
+                false, new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+                    @Override
+                    public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) {
+                        callbacks.onNewSessionEstablishedSaveSession = true;
+                    }
+                }, null, null);
+        TestSSLHandshakeCallbacks clientCallback1 = client1.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback1 = server1.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback1.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback1.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback1.authMethod);
+        assertFalse(serverCallback1.verifyCertificateChainCalled);
+        assertFalse(clientCallback1.clientCertificateRequestedCalled);
+        assertFalse(serverCallback1.clientCertificateRequestedCalled);
+        assertFalse(clientCallback1.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback1.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback1.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback1.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback1.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback1.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback1.handshakeCompletedCalled);
+        assertTrue(serverCallback1.handshakeCompletedCalled);
+
+        final long clientSessionContext =
+                clientCallback1.onNewSessionEstablishedSessionNativePointer;
+        final long serverSessionContext =
+                serverCallback1.onNewSessionEstablishedSessionNativePointer;
+
+        Future<TestSSLHandshakeCallbacks> client2 = handshake(listener, 0, true, new ClientHooks() {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long sslNativePtr = super.beforeHandshake(c);
+                NativeCrypto.SSL_set_session(sslNativePtr, null, clientSessionContext);
+                return sslNativePtr;
+            }
+        }, null, null);
+        Future<TestSSLHandshakeCallbacks> server2 = handshake(listener, 0,
+                false, new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+                    @Override
+                    public long beforeHandshake(long c) throws SSLException {
+                        long sslNativePtr = super.beforeHandshake(c);
+                        NativeCrypto.SSL_set_session(sslNativePtr, null, serverSessionContext);
+                        return sslNativePtr;
+                    }
+                }, null, null);
+        TestSSLHandshakeCallbacks clientCallback2 = client2.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback2 = server2.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback2.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback2.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback2.authMethod);
+        assertFalse(serverCallback2.verifyCertificateChainCalled);
+        assertFalse(clientCallback2.clientCertificateRequestedCalled);
+        assertFalse(serverCallback2.clientCertificateRequestedCalled);
+        assertFalse(clientCallback2.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback2.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback2.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback2.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback2.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback2.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback2.handshakeCompletedCalled);
+        assertTrue(serverCallback2.handshakeCompletedCalled);
+
+        NativeCrypto.SSL_SESSION_free(clientSessionContext);
+        NativeCrypto.SSL_SESSION_free(serverSessionContext);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_optional_client_certificate() throws Exception {
+        // optional client certificate case
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void clientCertificateRequested(long s)
+                    throws CertificateEncodingException, SSLException {
+                super.clientCertificateRequested(s);
+                NativeCrypto.setLocalCertsAndPrivateKey(
+                        s, null, getEncodedClientCertificates(), getClientPrivateKey().getNativeRef());
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
+                NativeCrypto.SSL_set_client_CA_list(s, null, getCaPrincipals());
+                NativeCrypto.SSL_set_verify(s, null, SSL_VERIFY_PEER);
+                return s;
+            }
+        };
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback.authMethod);
+        assertTrue(serverCallback.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getClientCertificateRefs(), serverCallback.certificateChainRefs);
+        assertEquals("ECDHE_RSA", serverCallback.authMethod);
+
+        assertTrue(clientCallback.clientCertificateRequestedCalled);
+        assertNotNull(clientCallback.keyTypes);
+        assertNotNull(clientCallback.signatureAlgs);
+        assertEquals(new HashSet<String>(Arrays.asList("EC", "RSA")),
+                SSLUtils.getSupportedClientKeyTypes(
+                        clientCallback.keyTypes, clientCallback.signatureAlgs));
+        assertEqualPrincipals(getCaPrincipals(), clientCallback.asn1DerEncodedX500Principals);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+
+        assertFalse(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_missing_required_certificate() throws Exception {
+        // required client certificate negative case
+        final ServerSocket listener = newServerSocket();
+        try {
+            Hooks cHooks = new Hooks();
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+                @Override
+                public long beforeHandshake(long c) throws SSLException {
+                    long s = super.beforeHandshake(c);
+                    NativeCrypto.SSL_set_client_CA_list(s, null, getCaPrincipals());
+                    NativeCrypto.SSL_set_verify(
+                            s, null, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
+                    return s;
+                }
+            };
+            @SuppressWarnings("unused")
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 0, true, cHooks, null, null);
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 0, false, sHooks, null, null);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            fail();
+        } catch (ExecutionException expected) {
+            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_client_timeout() throws Exception {
+        // client timeout
+        final ServerSocket listener = newServerSocket();
+        Socket serverSocket = null;
+        try {
+            Hooks cHooks = new Hooks();
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 1, true, cHooks, null, null);
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, -1, false, sHooks, null, null);
+            serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
+            client.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(serverSocket);
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_server_timeout() throws Exception {
+        // server timeout
+        final ServerSocket listener = newServerSocket();
+        Socket clientSocket = null;
+        try {
+            Hooks cHooks = new Hooks();
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, -1, true, cHooks, null, null);
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 1, false, sHooks, null, 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);
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_channel_id_normal() throws Exception {
+        initChannelIdKey();
+
+        // Normal handshake with TLS Channel ID.
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks();
+        cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
+        // TLS Channel ID currently requires ECDHE-based key exchanges.
+        cHooks.enabledCipherSuites = Collections.singletonList("ECDHE-RSA-AES128-SHA");
+        ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        sHooks.channelIdEnabled = true;
+        sHooks.enabledCipherSuites = cHooks.enabledCipherSuites;
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback.authMethod);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertFalse(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+        assertNull(sHooks.channelIdAfterHandshakeException);
+        assertEqualByteArrays(CHANNEL_ID, sHooks.channelIdAfterHandshake);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() throws Exception {
+        initChannelIdKey();
+
+        // Client tries to use TLS Channel ID but the server does not enable/offer the extension.
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks();
+        cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
+        // TLS Channel ID currently requires ECDHE-based key exchanges.
+        cHooks.enabledCipherSuites = Collections.singletonList("ECDHE-RSA-AES128-SHA");
+        ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        sHooks.channelIdEnabled = false;
+        sHooks.enabledCipherSuites = cHooks.enabledCipherSuites;
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback.authMethod);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertFalse(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+        assertNull(sHooks.channelIdAfterHandshakeException);
+        assertNull(sHooks.channelIdAfterHandshake);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws Exception {
+        initChannelIdKey();
+
+        // Client does not use TLS Channel ID when the server has the extension enabled/offered.
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks();
+        cHooks.channelIdPrivateKey = null;
+        // TLS Channel ID currently requires ECDHE-based key exchanges.
+        cHooks.enabledCipherSuites = Collections.singletonList("ECDHE-RSA-AES128-SHA");
+        ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        sHooks.channelIdEnabled = true;
+        sHooks.enabledCipherSuites = cHooks.enabledCipherSuites;
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertTrue(clientCallback.verifyCertificateChainCalled);
+        assertEqualCertificateChains(
+                getServerCertificateRefs(), clientCallback.certificateChainRefs);
+        assertEquals("ECDHE_RSA", clientCallback.authMethod);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertFalse(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.serverPSKKeyRequestedInvoked);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+        assertNull(sHooks.channelIdAfterHandshakeException);
+        assertNull(sHooks.channelIdAfterHandshake);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_psk_normal() throws Exception {
+        // normal TLS-PSK client and server case
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new ClientHooks();
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        sHooks.pskKey = cHooks.pskKey;
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertFalse(clientCallback.verifyCertificateChainCalled);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+        assertTrue(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertTrue(serverCallback.serverPSKKeyRequestedInvoked);
+        assertContains(cHooks.negotiatedCipherSuite, "PSK");
+        assertEquals(cHooks.negotiatedCipherSuite, sHooks.negotiatedCipherSuite);
+        assertNull(clientCallback.clientPSKKeyRequestedIdentityHint);
+        assertNull(serverCallback.serverPSKKeyRequestedIdentityHint);
+        assertEquals("", serverCallback.serverPSKKeyRequestedIdentity);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_psk_with_identity_and_hint() throws Exception {
+        // normal TLS-PSK client and server case where the server provides the client with a PSK
+        // identity hint, and the client provides the server with a PSK identity.
+        final ServerSocket listener = newServerSocket();
+        ClientHooks cHooks = new ClientHooks();
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        sHooks.pskKey = cHooks.pskKey;
+        sHooks.pskIdentityHint = "Some non-ASCII characters: \u00c4\u0332";
+        cHooks.pskIdentity = "More non-ASCII characters: \u00f5\u044b";
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertFalse(clientCallback.verifyCertificateChainCalled);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+        assertTrue(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertTrue(serverCallback.serverPSKKeyRequestedInvoked);
+        assertContains(cHooks.negotiatedCipherSuite, "PSK");
+        assertEquals(cHooks.negotiatedCipherSuite, sHooks.negotiatedCipherSuite);
+        assertEquals(sHooks.pskIdentityHint, clientCallback.clientPSKKeyRequestedIdentityHint);
+        assertEquals(sHooks.pskIdentityHint, serverCallback.serverPSKKeyRequestedIdentityHint);
+        assertEquals(cHooks.pskIdentity, serverCallback.serverPSKKeyRequestedIdentity);
+    }
+
+    @Test
+    @SuppressWarnings("deprecation")
+    public void test_SSL_do_handshake_with_psk_with_identity_and_hint_of_max_length()
+            throws Exception {
+        // normal TLS-PSK client and server case where the server provides the client with a PSK
+        // identity hint, and the client provides the server with a PSK identity.
+        final ServerSocket listener = newServerSocket();
+        ClientHooks cHooks = new ClientHooks();
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        sHooks.pskKey = cHooks.pskKey;
+        sHooks.pskIdentityHint = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+                + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx";
+        cHooks.pskIdentity = "123456789012345678901234567890123456789012345678901234567890"
+                + "12345678901234567890123456789012345678901234567890123456789012345678";
+        assertEquals(PSKKeyManager.MAX_IDENTITY_HINT_LENGTH_BYTES, sHooks.pskIdentityHint.length());
+        assertEquals(PSKKeyManager.MAX_IDENTITY_LENGTH_BYTES, cHooks.pskIdentity.length());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        assertFalse(clientCallback.verifyCertificateChainCalled);
+        assertFalse(serverCallback.verifyCertificateChainCalled);
+        assertFalse(clientCallback.clientCertificateRequestedCalled);
+        assertFalse(serverCallback.clientCertificateRequestedCalled);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+        assertTrue(clientCallback.clientPSKKeyRequestedInvoked);
+        assertFalse(clientCallback.serverPSKKeyRequestedInvoked);
+        assertFalse(serverCallback.clientPSKKeyRequestedInvoked);
+        assertTrue(serverCallback.serverPSKKeyRequestedInvoked);
+        assertContains(cHooks.negotiatedCipherSuite, "PSK");
+        assertEquals(cHooks.negotiatedCipherSuite, sHooks.negotiatedCipherSuite);
+        assertEquals(sHooks.pskIdentityHint, clientCallback.clientPSKKeyRequestedIdentityHint);
+        assertEquals(sHooks.pskIdentityHint, serverCallback.serverPSKKeyRequestedIdentityHint);
+        assertEquals(cHooks.pskIdentity, serverCallback.serverPSKKeyRequestedIdentity);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_psk_key_mismatch() throws Exception {
+        final ServerSocket listener = newServerSocket();
+        ClientHooks cHooks = new ClientHooks();
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        sHooks.pskKey = "1, 2, 3, 3, Testing...".getBytes("UTF-8");
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        try {
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            fail();
+        } catch (ExecutionException expected) {
+            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_psk_with_no_client_key() throws Exception {
+        final ServerSocket listener = newServerSocket();
+        ClientHooks cHooks = new ClientHooks();
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = null;
+        sHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        try {
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            fail();
+        } catch (ExecutionException expected) {
+            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_psk_with_no_server_key() throws Exception {
+        final ServerSocket listener = newServerSocket();
+        ClientHooks cHooks = new ClientHooks();
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        sHooks.pskKey = null;
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        try {
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            fail();
+        } catch (ExecutionException expected) {
+            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("deprecation")
+    public void test_SSL_do_handshake_with_psk_key_too_long() throws Exception {
+        final ServerSocket listener = newServerSocket();
+        ClientHooks cHooks = new ClientHooks() {
+            @Override
+            public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) {
+                super.configureCallbacks(callbacks);
+                callbacks.clientPSKKeyRequestedResult = PSKKeyManager.MAX_KEY_LENGTH_BYTES + 1;
+            }
+        };
+        ServerHooks sHooks = new ServerHooks();
+        cHooks.pskEnabled = true;
+        sHooks.pskEnabled = true;
+        cHooks.pskKey = "1, 2, 3, 4, Testing...".getBytes("UTF-8");
+        sHooks.pskKey = cHooks.pskKey;
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        try {
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            fail();
+        } catch (ExecutionException expected) {
+            assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+        }
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_ocsp_response() throws Exception {
+        final byte[] OCSP_TEST_DATA = new byte[] {1, 2, 3, 4};
+
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks() {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
+                NativeCrypto.SSL_enable_ocsp_stapling(s, null);
+                return s;
+            }
+
+            @Override
+            public void afterHandshake(long session, long ssl, long context, Socket socket,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                assertEqualByteArrays(OCSP_TEST_DATA, NativeCrypto.SSL_get_ocsp_response(ssl, null));
+                super.afterHandshake(session, ssl, context, socket, fd, callback);
+            }
+        };
+
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
+                NativeCrypto.SSL_set_ocsp_response(s, null, OCSP_TEST_DATA);
+                return s;
+            }
+        };
+
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+    }
+
+    @Test
+    public void test_SSL_do_handshake_with_sct_extension() throws Exception {
+        // Fake SCT extension has a length of overall extension (unsigned 16-bit).
+        // Each SCT entry has a length (unsigned 16-bit) and data.
+        final byte[] SCT_TEST_DATA = new byte[] {0, 6, 0, 4, 1, 2, 3, 4};
+
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks() {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
+                NativeCrypto.SSL_enable_signed_cert_timestamps(s, null);
+                return s;
+            }
+
+            @Override
+            public void afterHandshake(long session, long ssl, long context, Socket socket,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                assertEqualByteArrays(
+                        SCT_TEST_DATA, NativeCrypto.SSL_get_signed_cert_timestamp_list(ssl, null));
+                super.afterHandshake(session, ssl, context, socket, fd, callback);
+            }
+        };
+
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
+                NativeCrypto.SSL_set_signed_cert_timestamp_list(s, null, SCT_TEST_DATA);
+                return s;
+            }
+        };
+
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+
+        assertTrue(clientCallback.onNewSessionEstablishedInvoked);
+        assertTrue(serverCallback.onNewSessionEstablishedInvoked);
+        assertTrue(clientCallback.handshakeCompletedCalled);
+        assertTrue(serverCallback.handshakeCompletedCalled);
+    }
+
+    @Test
+    @SuppressWarnings("deprecation")
+    public void test_SSL_use_psk_identity_hint() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_use_psk_identity_hint(s, null, null);
+            NativeCrypto.SSL_use_psk_identity_hint(s, null, "test");
+
+            try {
+                // 800 characters is much longer than the permitted maximum.
+                StringBuilder pskIdentityHint = new StringBuilder();
+                for (int i = 0; i < 160; i++) {
+                    pskIdentityHint.append(" long");
+                }
+                assertTrue(pskIdentityHint.length() > PSKKeyManager.MAX_IDENTITY_HINT_LENGTH_BYTES);
+                NativeCrypto.SSL_use_psk_identity_hint(s, null, pskIdentityHint.toString());
+                fail();
+            } catch (SSLException expected) {
+                // Expected.
+            }
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_session_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_session(NULL, null, NULL);
+    }
+
+    @Test
+    public void test_SSL_set_session() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        NativeCrypto.SSL_set_session(s, null, NULL);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+
+        {
+            final long clientContext = NativeCrypto.SSL_CTX_new();
+            final long serverContext = NativeCrypto.SSL_CTX_new();
+            final ServerSocket listener = newServerSocket();
+            final long[] clientSession = new long[] {NULL};
+            final long[] serverSession = new long[] {NULL};
+            {
+                Hooks cHooks = new Hooks() {
+                    @Override
+                    public long getContext() throws SSLException {
+                        return clientContext;
+                    }
+                    @Override
+                    public void afterHandshake(long session, long s, long c, Socket sock,
+                            FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
+                        clientSession[0] = session;
+                    }
+                };
+                Hooks sHooks = new ServerHooks(
+                        getServerPrivateKey(), getEncodedServerCertificates()) {
+                    @Override
+                    public long getContext() throws SSLException {
+                        return serverContext;
+                    }
+                    @Override
+                    public void afterHandshake(long session, long s, long c, Socket sock,
+                            FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
+                        serverSession[0] = session;
+                    }
+                };
+                Future<TestSSLHandshakeCallbacks> client =
+                        handshake(listener, 0, true, cHooks, null, null);
+                Future<TestSSLHandshakeCallbacks> server =
+                        handshake(listener, 0, false, sHooks, null, null);
+                client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            }
+            assertEqualSessions(clientSession[0], serverSession[0]);
+            {
+                Hooks cHooks = new Hooks() {
+                    @Override
+                    public long getContext() throws SSLException {
+                        return clientContext;
+                    }
+                    @Override
+                    public long beforeHandshake(long c) throws SSLException {
+                        long s = NativeCrypto.SSL_new(clientContext, null);
+                        NativeCrypto.SSL_set_session(s, null, clientSession[0]);
+                        return s;
+                    }
+                    @Override
+                    public void afterHandshake(long session, long s, long c, Socket sock,
+                            FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                        assertEqualSessions(clientSession[0], session);
+                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
+                    }
+                };
+                Hooks sHooks = new ServerHooks(
+                        getServerPrivateKey(), getEncodedServerCertificates()) {
+                    @Override
+                    public long getContext() throws SSLException {
+                        return serverContext;
+                    }
+                    @Override
+                    public void afterHandshake(long session, long s, long c, Socket sock,
+                            FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                        assertEqualSessions(serverSession[0], session);
+                        super.afterHandshake(NULL, s, NULL, sock, fd, callback);
+                    }
+                };
+                Future<TestSSLHandshakeCallbacks> client =
+                        handshake(listener, 0, true, cHooks, null, null);
+                Future<TestSSLHandshakeCallbacks> server =
+                        handshake(listener, 0, false, sHooks, null, null);
+                client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            }
+            NativeCrypto.SSL_SESSION_free(clientSession[0]);
+            NativeCrypto.SSL_SESSION_free(serverSession[0]);
+            NativeCrypto.SSL_CTX_free(serverContext, null);
+            NativeCrypto.SSL_CTX_free(clientContext, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_session_creation_enabled_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_session_creation_enabled(NULL, null, false);
+    }
+
+    @Test
+    public void test_SSL_set_session_creation_enabled() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        NativeCrypto.SSL_set_session_creation_enabled(s, null, false);
+        NativeCrypto.SSL_set_session_creation_enabled(s, null, true);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+
+        final ServerSocket listener = newServerSocket();
+
+        // negative test case for SSL_set_session_creation_enabled(false) on client
+        {
+            Hooks cHooks = new Hooks() {
+                @Override
+                public long beforeHandshake(long c) throws SSLException {
+                    long s = super.beforeHandshake(c);
+                    NativeCrypto.SSL_set_session_creation_enabled(s, null, false);
+                    return s;
+                }
+            };
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 0, true, cHooks, null, null);
+            @SuppressWarnings("unused")
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 0, false, sHooks, null, null);
+            try {
+                client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                fail();
+            } catch (ExecutionException expected) {
+                assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+            }
+            try {
+                server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                fail();
+            } catch (ExecutionException expected) {
+                assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+            }
+        }
+
+        // negative test case for SSL_set_session_creation_enabled(false) on server
+        {
+            Hooks cHooks = new Hooks();
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+                @Override
+                public long beforeHandshake(long c) throws SSLException {
+                    long s = super.beforeHandshake(c);
+                    NativeCrypto.SSL_set_session_creation_enabled(s, null, false);
+                    return s;
+                }
+            };
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 0, true, cHooks, null, null);
+            @SuppressWarnings("unused")
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 0, false, sHooks, null, null);
+            try {
+                client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                fail();
+            } catch (ExecutionException expected) {
+                assertEquals(SSLHandshakeException.class, expected.getCause().getClass());
+            }
+            try {
+                server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+                fail();
+            } catch (ExecutionException expected) {
+                assertEquals(SSLProtocolException.class, expected.getCause().getClass());
+            }
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_tlsext_host_name_withNullSslShouldThrow() throws Exception {
+        NativeCrypto.SSL_set_tlsext_host_name(NULL, null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_set_tlsext_host_name_withNullHostnameShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        try {
+            NativeCrypto.SSL_set_tlsext_host_name(s, null, null);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = SSLException.class)
+    public void SSL_set_tlsext_host_name_withTooLongHostnameShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        try {
+            char[] longHostname = new char[256];
+            Arrays.fill(longHostname, 'w');
+            NativeCrypto.SSL_set_tlsext_host_name(s, null, new String(longHostname));
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void test_SSL_set_tlsext_host_name() throws Exception {
+        final String hostname = "www.android.com";
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+
+        assertNull(NativeCrypto.SSL_get_servername(s, null));
+        NativeCrypto.SSL_set_tlsext_host_name(s, null, hostname);
+        assertEquals(hostname, NativeCrypto.SSL_get_servername(s, null));
+
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+
+        final ServerSocket listener = newServerSocket();
+
+        // normal
+        Hooks cHooks = new Hooks() {
+            @Override
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
+                NativeCrypto.SSL_set_tlsext_host_name(s, null, hostname);
+                return s;
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                assertEquals(hostname, NativeCrypto.SSL_get_servername(s, null));
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void alpnWithProtocolListShouldSucceed() throws Exception {
+        final byte[] clientAlpnProtocols =
+                SSLUtils.encodeProtocols(new String[] {"http/1.1", "foo", "spdy/2"});
+        final byte[] serverAlpnProtocols =
+                SSLUtils.encodeProtocols(new String[] {"spdy/2", "foo", "bar"});
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long ssl, long context, Socket socket,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertEquals("spdy/2", new String(negotiated, "UTF-8"));
+                super.afterHandshake(session, ssl, context, socket, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public void afterHandshake(long session, long ssl, long c, Socket sock,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertEquals("spdy/2", new String(negotiated, "UTF-8"));
+                super.afterHandshake(session, ssl, c, sock, fd, callback);
+            }
+        };
+
+        ServerSocket listener = newServerSocket();
+        Future<TestSSLHandshakeCallbacks> client =
+                handshake(listener, 0, true, cHooks, clientAlpnProtocols, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, serverAlpnProtocols, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void alpnWithProtocolListShouldFail() throws Exception {
+        final byte[] clientAlpnProtocols =
+                SSLUtils.encodeProtocols(new String[] {"http/1.1", "foo", "spdy/2"});
+        final byte[] serverAlpnProtocols =
+                SSLUtils.encodeProtocols(new String[] {"h2", "bar", "baz"});
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long ssl, long context, Socket socket,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertNull(negotiated);
+                super.afterHandshake(session, ssl, context, socket, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public void afterHandshake(long session, long ssl, long c, Socket sock,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertNull(negotiated);
+                super.afterHandshake(session, ssl, c, sock, fd, callback);
+            }
+        };
+
+        ServerSocket listener = newServerSocket();
+        Future<TestSSLHandshakeCallbacks> client =
+                handshake(listener, 0, true, cHooks, clientAlpnProtocols, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, serverAlpnProtocols, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void alpnWithServerProtocolSelectorShouldSucceed() throws Exception {
+        final byte[] clientAlpnProtocols =
+                SSLUtils.encodeProtocols(new String[] {"http/1.1", "foo", "spdy/2"});
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long ssl, long context, Socket socket,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertEquals("spdy/2", new String(negotiated, "UTF-8"));
+                super.afterHandshake(session, ssl, context, socket, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public void afterHandshake(long session, long ssl, long c, Socket sock,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertEquals("spdy/2", new String(negotiated, "UTF-8"));
+                super.afterHandshake(session, ssl, c, sock, fd, callback);
+            }
+        };
+
+        ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class);
+        SSLEngine engine = Mockito.mock(SSLEngine.class);
+        ApplicationProtocolSelectorAdapter adapter = new ApplicationProtocolSelectorAdapter(engine, selector);
+        when(selector.selectApplicationProtocol(same(engine), Matchers.anyListOf(String.class)))
+                .thenReturn("spdy/2");
+
+        ServerSocket listener = newServerSocket();
+        Future<TestSSLHandshakeCallbacks> client =
+                handshake(listener, 0, true, cHooks, clientAlpnProtocols, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, adapter);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void alpnWithServerProtocolSelectorShouldFail() throws Exception {
+        final byte[] clientAlpnProtocols =
+                SSLUtils.encodeProtocols(new String[] {"http/1.1", "foo", "spdy/2"});
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long ssl, long context, Socket socket,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertNull(negotiated);
+                super.afterHandshake(session, ssl, context, socket, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public void afterHandshake(long session, long ssl, long c, Socket sock,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                byte[] negotiated = NativeCrypto.getApplicationProtocol(ssl, null);
+                assertNull(negotiated);
+                super.afterHandshake(session, ssl, c, sock, fd, callback);
+            }
+        };
+
+        ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class);
+        SSLEngine engine = Mockito.mock(SSLEngine.class);
+        ApplicationProtocolSelectorAdapter adapter = new ApplicationProtocolSelectorAdapter(engine, selector);
+        when(selector.selectApplicationProtocol(same(engine), Matchers.anyListOf(String.class)))
+                .thenReturn("h2");
+
+        ServerSocket listener = newServerSocket();
+        Future<TestSSLHandshakeCallbacks> client =
+                handshake(listener, 0, true, cHooks, clientAlpnProtocols, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, adapter);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_SSL_get_servername_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_get_servername(NULL, null);
+    }
+
+    @Test
+    public void SSL_get_servername_shouldReturnNull() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        assertNull(NativeCrypto.SSL_get_servername(s, null));
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+
+        // additional positive testing by test_SSL_set_tlsext_host_name
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_get0_peer_certificates_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_get0_peer_certificates(NULL, null);
+    }
+
+    @Test
+    public void test_SSL_get0_peer_certificates() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                byte[][] cc = NativeCrypto.SSL_get0_peer_certificates(s, null);
+                assertEqualByteArrays(getEncodedServerCertificates(), cc);
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void test_SSL_cipher_names() throws Exception {
+        final ServerSocket listener = newServerSocket();
+        Hooks cHooks = new Hooks();
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        // Both legacy and standard names are accepted.
+        cHooks.enabledCipherSuites = Collections.singletonList("ECDHE-RSA-AES128-GCM-SHA256");
+        sHooks.enabledCipherSuites =
+                Collections.singletonList("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        // The standard name is always reported.
+        assertEquals("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", cHooks.negotiatedCipherSuite);
+        assertEquals("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", sHooks.negotiatedCipherSuite);
+    }
+
+    private final byte[] BYTES = new byte[] {2, -3, 5, 127, 0, -128};
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_read_withNullSslShouldThrow() throws Exception {
+        NativeCrypto.SSL_read(NULL, null, null, null, null, 0, 0, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_read_withNullFdShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_read(s, null, null, DUMMY_CB, null, 0, 0, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_read_withNullCallbacksShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_read(s, null, INVALID_FD, null, null, 0, 0, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_read_withNullBytesShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_read(s, null, INVALID_FD, DUMMY_CB, null, 0, 0, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = SSLException.class)
+    public void SSL_read_beforeHandshakeShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_read(s, null, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void test_SSL_read() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        // normal case
+        {
+            Hooks cHooks = new Hooks() {
+                @Override
+                public void afterHandshake(long session, long s, long c, Socket sock,
+                        FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                    byte[] in = new byte[256];
+                    assertEquals(BYTES.length,
+                            NativeCrypto.SSL_read(s, null, fd, callback, in, 0, BYTES.length, 0));
+                    for (int i = 0; i < BYTES.length; i++) {
+                        assertEquals(BYTES[i], in[i]);
+                    }
+                    super.afterHandshake(session, s, c, sock, fd, callback);
+                }
+            };
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+                @Override
+                public void afterHandshake(long session, long s, long c, Socket sock,
+                        FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                    NativeCrypto.SSL_write(s, null, fd, callback, BYTES, 0, BYTES.length, 0);
+                    super.afterHandshake(session, s, c, sock, fd, callback);
+                }
+            };
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 0, true, cHooks, null, null);
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 0, false, sHooks, null, null);
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        }
+
+        // timeout case
+        try {
+            Hooks cHooks = new Hooks() {
+                @Override
+                public void afterHandshake(long session, long s, long c, Socket sock,
+                        FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                    NativeCrypto.SSL_read(s, null, fd, callback, new byte[1], 0, 1, 1);
+                    fail();
+                }
+            };
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+                @Override
+                public void afterHandshake(long session, long s, long c, Socket sock,
+                        FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                    NativeCrypto.SSL_read(s, null, fd, callback, new byte[1], 0, 1, 0);
+                    super.afterHandshake(session, s, c, sock, fd, callback);
+                }
+            };
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 0, true, cHooks, null, null);
+            @SuppressWarnings("unused")
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 0, false, sHooks, null, null);
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            fail();
+        } catch (ExecutionException expected) {
+            assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_write_withNullSslShouldThrow() throws Exception {
+        NativeCrypto.SSL_write(NULL, null, null, null, null, 0, 0, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_write_withNullFdShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_write(s, null, null, DUMMY_CB, null, 0, 1, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_write_withNullCallbacksShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_write(s, null, INVALID_FD, null, null, 0, 1, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_write_withNullBytesShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_write(s, null, INVALID_FD, DUMMY_CB, null, 0, 1, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test(expected = SSLException.class)
+    public void SSL_write_beforeHandshakeShouldThrow() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            NativeCrypto.SSL_write(s, null, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void SSL_interrupt_withNullShouldSucceed() {
+        // SSL_interrupt is a rare case that tolerates a null SSL argument
+        NativeCrypto.SSL_interrupt(NULL, null);
+    }
+
+    @Test
+    public void SSL_interrupt_withoutHandshakeShouldSucceed() throws Exception {
+        // also works without handshaking
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        NativeCrypto.SSL_interrupt(s, null);
+        NativeCrypto.SSL_free(s, null);
+        NativeCrypto.SSL_CTX_free(c, null);
+    }
+
+    @Test
+    public void test_SSL_interrupt() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                NativeCrypto.SSL_read(s, null, fd, callback, new byte[1], 0, 1, 0);
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates()) {
+            @Override
+            public void afterHandshake(long session, final long s, long c, Socket sock,
+                    FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                new Thread() {
+                    @Override
+                    public void run() {
+                        try {
+                            Thread.sleep(1000);
+                            NativeCrypto.SSL_interrupt(s, null);
+                        } catch (Exception e) {
+                            // Expected.
+                        }
+                    }
+                }.start();
+                assertEquals(-1, NativeCrypto.SSL_read(s, null, fd, callback, new byte[1], 0, 1, 0));
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    private static abstract class SSLSessionWrappedTask {
+        public abstract void run(long sslSession) throws Exception;
+    }
+
+    private void wrapWithSSLSession(SSLSessionWrappedTask task) throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c, null);
+        try {
+            task.run(s);
+        } finally {
+            NativeCrypto.SSL_free(s, null);
+            NativeCrypto.SSL_CTX_free(c, null);
+        }
+    }
+
+    @Test
+    public void SSL_shutdown_withNullFdShouldSucceed() throws Exception {
+        // We tolerate a null FileDescriptor
+        wrapWithSSLSession(new SSLSessionWrappedTask() {
+            @Override
+            public void run(long sslSession) throws Exception {
+                NativeCrypto.SSL_shutdown(sslSession, null, null, DUMMY_CB);
+            }
+        });
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_shutdown_withNullCallbacksShouldThrow() throws Exception {
+        wrapWithSSLSession(new SSLSessionWrappedTask() {
+            @Override
+            public void run(long sslSession) throws Exception {
+                NativeCrypto.SSL_shutdown(sslSession, null, INVALID_FD, null);
+            }
+        });
+    }
+
+    @Test
+    public void SSL_shutdown_withNullSslShouldSucceed() throws Exception {
+        // SSL_shutdown is a rare case that tolerates a null SSL argument
+        NativeCrypto.SSL_shutdown(NULL, null, INVALID_FD, DUMMY_CB);
+    }
+
+    @Test(expected = SocketException.class)
+    public void SSL_shutdown_beforeHandshakeShouldThrow() throws Exception {
+        // handshaking not yet performed
+        wrapWithSSLSession(new SSLSessionWrappedTask() {
+            @Override
+            public void run(long sslSession) throws Exception {
+                NativeCrypto.SSL_shutdown(sslSession, null, INVALID_FD, DUMMY_CB);
+            }
+        });
+
+        // positively tested elsewhere because handshake uses use
+        // SSL_shutdown to ensure SSL_SESSIONs are reused.
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_free_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_free(NULL, null);
+    }
+
+    @Test
+    public void test_SSL_free() throws Exception {
+        long c = NativeCrypto.SSL_CTX_new();
+        NativeCrypto.SSL_free(NativeCrypto.SSL_new(c, null), null);
+        NativeCrypto.SSL_CTX_free(c, null);
+
+        // additional positive testing elsewhere because handshake
+        // uses use SSL_free to cleanup in afterHandshake.
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_SESSION_session_id_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_SESSION_session_id(NULL);
+    }
+
+    @Test
+    public void test_SSL_SESSION_session_id() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                byte[] id = NativeCrypto.SSL_SESSION_session_id(session);
+                assertNotNull(id);
+                assertEquals(32, id.length);
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_SESSION_get_time_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_SESSION_get_time(NULL);
+    }
+
+    @Test
+    public void test_SSL_SESSION_get_time() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        {
+            Hooks cHooks = new Hooks() {
+                @Override
+                public void afterHandshake(long session, long s, long c, Socket sock,
+                        FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
+                    long time = NativeCrypto.SSL_SESSION_get_time(session);
+                    assertTrue(time != 0);
+                    assertTrue(time < System.currentTimeMillis());
+                    super.afterHandshake(session, s, c, sock, fd, callback);
+                }
+            };
+            Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+            Future<TestSSLHandshakeCallbacks> client =
+                    handshake(listener, 0, true, cHooks, null, null);
+            Future<TestSSLHandshakeCallbacks> server =
+                    handshake(listener, 0, false, sHooks, null, null);
+            client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_SESSION_get_version_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_SESSION_get_version(NULL);
+    }
+
+    @Test
+    public void test_SSL_SESSION_get_version() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                String v = NativeCrypto.SSL_SESSION_get_version(session);
+                assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(v));
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void SSL_SESSION_cipher_withNullShouldThrow() throws Exception {
+        NativeCrypto.SSL_SESSION_cipher(NULL);
+    }
+
+    @Test
+    public void test_SSL_SESSION_cipher() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                String nativeCipher = NativeCrypto.SSL_SESSION_cipher(session);
+                String javaCipher = NativeCrypto.cipherSuiteFromJava(nativeCipher);
+                assertTrue(NativeCrypto.SUPPORTED_TLS_1_2_CIPHER_SUITES_SET.contains(javaCipher));
+                // SSL_SESSION_cipher should return a standard name rather than an OpenSSL name.
+                assertTrue(nativeCipher.startsWith("TLS_"));
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    /*
+     * Additional positive testing elsewhere because handshake
+     * uses use SSL_SESSION_free to cleanup in afterHandshake.
+     */
+    @Test(expected = NullPointerException.class)
+    public void SSL_SESSION_free_NullArgument() throws Exception {
+        NativeCrypto.SSL_SESSION_free(NULL);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void i2d_SSL_Session_WithNullSessionShouldThrow() throws Exception {
+        NativeCrypto.i2d_SSL_SESSION(NULL);
+    }
+
+    @Test
+    public void test_i2d_SSL_SESSION() throws Exception {
+        final ServerSocket listener = newServerSocket();
+
+        Hooks cHooks = new Hooks() {
+            @Override
+            public void afterHandshake(long session, long s, long c, Socket sock, FileDescriptor fd,
+                    SSLHandshakeCallbacks callback) throws Exception {
+                byte[] b = NativeCrypto.i2d_SSL_SESSION(session);
+                assertNotNull(b);
+                long session2 = NativeCrypto.d2i_SSL_SESSION(b);
+                assertTrue(session2 != NULL);
+
+                // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840
+                assertTrue(NativeCrypto.SSL_SESSION_cipher(session2) != null);
+                assertEquals(NativeCrypto.SSL_SESSION_cipher(session),
+                        NativeCrypto.SSL_SESSION_cipher(session2));
+
+                NativeCrypto.SSL_SESSION_free(session2);
+                super.afterHandshake(session, s, c, sock, fd, callback);
+            }
+        };
+        Hooks sHooks = new ServerHooks(getServerPrivateKey(), getEncodedServerCertificates());
+        Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
+        Future<TestSSLHandshakeCallbacks> server =
+                handshake(listener, 0, false, sHooks, null, null);
+        client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+        server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void d2i_SSL_SESSION_NullArgument() throws Exception {
+        NativeCrypto.d2i_SSL_SESSION(null);
+    }
+
+    @Test(expected = IOException.class)
+    public void d2i_SSL_SESSION_EmptyArgument() throws Exception {
+        NativeCrypto.d2i_SSL_SESSION(new byte[0]);
+    }
+
+    @Test(expected = IOException.class)
+    public void d2i_SSL_SESSION_InvalidArgument() throws Exception {
+        NativeCrypto.d2i_SSL_SESSION(new byte[1]);
+    }
+
+    @Test
+    public void test_X509_NAME_hashes() {
+        // ensure these hash functions are stable over time since the
+        // /system/etc/security/cacerts CA filenames have to be
+        // consistent with the output.
+        X500Principal name = new X500Principal("CN=localhost");
+        assertEquals(-1372642656, NativeCrypto.X509_NAME_hash(name)); // SHA1
+        assertEquals(-1626170662, NativeCrypto.X509_NAME_hash_old(name)); // MD5
+    }
+
+    @Test
+    public void test_RAND_bytes_Success() throws Exception {
+        byte[] output = new byte[128];
+        NativeCrypto.RAND_bytes(output);
+
+        boolean isZero = true;
+        for (byte anOutput : output) {
+            isZero &= (anOutput == 0);
+        }
+
+        assertFalse("Random output was zero. This is a very low probability event (1 in 2^128) "
+                        + "and probably indicates an error.",
+                isZero);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void RAND_bytes_withNullShouldThrow() throws Exception {
+        NativeCrypto.RAND_bytes(null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_EVP_get_digestbyname_NullArgument() throws Exception {
+        NativeCrypto.EVP_get_digestbyname(null);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void EVP_get_digestbyname_withEmptyShouldThrow() throws Exception {
+        NativeCrypto.EVP_get_digestbyname("");
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void EVP_get_digestbyname_withInvalidDigestShouldThrow() throws Exception {
+        NativeCrypto.EVP_get_digestbyname("foobar");
+    }
+
+    @Test
+    public void test_EVP_get_digestbyname() throws Exception {
+        assertTrue(NativeCrypto.EVP_get_digestbyname("sha256") != NULL);
+    }
+
+    @Test
+    public void test_EVP_DigestSignInit() throws Exception {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        kpg.initialize(512);
+
+        KeyPair kp = kpg.generateKeyPair();
+        RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) kp.getPrivate();
+
+        NativeRef.EVP_PKEY pkey;
+        pkey = new NativeRef.EVP_PKEY(NativeCrypto.EVP_PKEY_new_RSA(
+                privKey.getModulus().toByteArray(), privKey.getPublicExponent().toByteArray(),
+                privKey.getPrivateExponent().toByteArray(), privKey.getPrimeP().toByteArray(),
+                privKey.getPrimeQ().toByteArray(), privKey.getPrimeExponentP().toByteArray(),
+                privKey.getPrimeExponentQ().toByteArray(),
+                privKey.getCrtCoefficient().toByteArray()));
+        assertNotNull(pkey);
+
+        final NativeRef.EVP_MD_CTX ctx = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create());
+        long evpMd = NativeCrypto.EVP_get_digestbyname("sha256");
+        NativeCrypto.EVP_DigestSignInit(ctx, evpMd, pkey);
+
+        try {
+            NativeCrypto.EVP_DigestSignInit(ctx, 0, pkey);
+            fail();
+        } catch (RuntimeException expected) {
+            // Expected.
+        }
+
+        try {
+            NativeCrypto.EVP_DigestSignInit(ctx, evpMd, null);
+            fail();
+        } catch (RuntimeException expected) {
+            // Expected.
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void get_RSA_private_params_NullArgument() throws Exception {
+        NativeCrypto.get_RSA_private_params(null);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void test_get_RSA_private_params() throws Exception {
+        // Test getting params for the wrong kind of key.
+        final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
+        assertFalse(groupCtx == NULL);
+        NativeRef.EC_GROUP group = new NativeRef.EC_GROUP(groupCtx);
+        NativeRef.EVP_PKEY ctx = new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(group));
+        NativeCrypto.get_RSA_private_params(ctx);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void get_RSA_public_params_NullArgument() throws Exception {
+        NativeCrypto.get_RSA_public_params(null);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void test_get_RSA_public_params() throws Exception {
+        // Test getting params for the wrong kind of key.
+        final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
+        assertFalse(groupCtx == NULL);
+        NativeRef.EC_GROUP group = new NativeRef.EC_GROUP(groupCtx);
+        NativeRef.EVP_PKEY ctx = new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(group));
+        NativeCrypto.get_RSA_public_params(ctx);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void RSA_size_NullArgumentFailure() throws Exception {
+        NativeCrypto.RSA_size(null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void RSA_private_encrypt_NullArgumentFailure() throws Exception {
+        NativeCrypto.RSA_private_encrypt(0, new byte[0], new byte[0], null, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void RSA_private_decrypt_NullArgumentFailure() throws Exception {
+        NativeCrypto.RSA_private_decrypt(0, new byte[0], new byte[0], null, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_RSA_public_encrypt_NullArgumentFailure() throws Exception {
+        NativeCrypto.RSA_public_encrypt(0, new byte[0], new byte[0], null, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_RSA_public_decrypt_NullArgumentFailure() throws Exception {
+        NativeCrypto.RSA_public_decrypt(0, new byte[0], new byte[0], null, 0);
+    }
+
+    /*
+     * Test vector generation:
+     * openssl rand -hex 16
+     */
+    private static final byte[] AES_128_KEY = new byte[] {
+            (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2,
+            (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29,
+            (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f,
+    };
+
+    @Test
+    public void testEC_GROUP() throws Exception {
+        /* Test using NIST's P-256 curve */
+        check_EC_GROUP("prime256v1",
+                "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+                "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+                "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+                "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+                "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+                "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1L);
+    }
+
+    private void check_EC_GROUP(String name, String pStr, String aStr, String bStr, String xStr,
+            String yStr, String nStr, long hLong) throws Exception {
+        long groupRef = NativeCrypto.EC_GROUP_new_by_curve_name(name);
+        assertFalse(groupRef == NULL);
+        NativeRef.EC_GROUP group = new NativeRef.EC_GROUP(groupRef);
+
+        // prime
+        BigInteger p = new BigInteger(pStr, 16);
+        // first coefficient
+        BigInteger a = new BigInteger(aStr, 16);
+        // second coefficient
+        BigInteger b = new BigInteger(bStr, 16);
+        // x affine coordinate of generator
+        BigInteger x = new BigInteger(xStr, 16);
+        // y affine coordinate of generator
+        BigInteger y = new BigInteger(yStr, 16);
+        // order of the generator
+        BigInteger n = new BigInteger(nStr, 16);
+        // cofactor of generator
+        BigInteger h = BigInteger.valueOf(hLong);
+
+        byte[][] pab = NativeCrypto.EC_GROUP_get_curve(group);
+        assertEquals(3, pab.length);
+
+        BigInteger p2 = new BigInteger(pab[0]);
+        assertEquals(p, p2);
+
+        BigInteger a2 = new BigInteger(pab[1]);
+        assertEquals(a, a2);
+
+        BigInteger b2 = new BigInteger(pab[2]);
+        assertEquals(b, b2);
+
+        NativeRef.EC_POINT point =
+                new NativeRef.EC_POINT(NativeCrypto.EC_GROUP_get_generator(group));
+
+        byte[][] xy = NativeCrypto.EC_POINT_get_affine_coordinates(group, point);
+        assertEquals(2, xy.length);
+
+        BigInteger x2 = new BigInteger(xy[0]);
+        assertEquals(x, x2);
+
+        BigInteger y2 = new BigInteger(xy[1]);
+        assertEquals(y, y2);
+
+        BigInteger n2 = new BigInteger(NativeCrypto.EC_GROUP_get_order(group));
+        assertEquals(n, n2);
+
+        BigInteger h2 = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(group));
+        assertEquals(h, h2);
+
+        NativeRef.EVP_PKEY key1 = new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(group));
+        NativeRef.EC_GROUP groupTmp = new NativeRef.EC_GROUP(NativeCrypto.EC_KEY_get1_group(key1));
+        assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group),
+                NativeCrypto.EC_GROUP_get_curve_name(groupTmp));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_EC_KEY_get_private_key_NullArgumentFailure() throws Exception {
+        NativeCrypto.EC_KEY_get_private_key(null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void test_EC_KEY_get_public_key_NullArgumentFailure() throws Exception {
+        NativeCrypto.EC_KEY_get_public_key(null);
+    }
+
+    @Test
+    public void test_ECKeyPairGenerator_CurvesAreValid() throws Exception {
+        OpenSSLECKeyPairGenerator.assertCurvesAreValid();
+    }
+
+    @Test
+    public void test_ECDH_compute_key_null_key_Failure() throws Exception {
+        final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
+        assertFalse(groupCtx == NULL);
+        NativeRef.EC_GROUP groupRef = new NativeRef.EC_GROUP(groupCtx);
+        NativeRef.EVP_PKEY pkey1Ref =
+                new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(groupRef));
+        NativeRef.EVP_PKEY pkey2Ref =
+                new NativeRef.EVP_PKEY(NativeCrypto.EC_KEY_generate_key(groupRef));
+
+        byte[] out = new byte[128];
+        int outOffset = 0;
+        // Assert that the method under test works fine with the two
+        // non-null keys
+        NativeCrypto.ECDH_compute_key(out, outOffset, pkey1Ref, pkey2Ref);
+
+        // Assert that it fails when only the first key is null
+        try {
+            NativeCrypto.ECDH_compute_key(out, outOffset, null, pkey2Ref);
+            fail();
+        } catch (NullPointerException expected) {
+            // Expected.
+        }
+
+        // Assert that it fails when only the second key is null
+        try {
+            NativeCrypto.ECDH_compute_key(out, outOffset, pkey1Ref, null);
+            fail();
+        } catch (NullPointerException expected) {
+            // Expected.
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_CipherInit_ex_withNullCtxShouldThrow() throws Exception {
+        final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+        NativeCrypto.EVP_CipherInit_ex(null, evpCipher, null, null, true);
+    }
+
+    @Test
+    public void test_EVP_CipherInit_ex_Null_Failure() throws Exception {
+        final NativeRef.EVP_CIPHER_CTX ctx =
+                new NativeRef.EVP_CIPHER_CTX(NativeCrypto.EVP_CIPHER_CTX_new());
+        final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+
+        /* Initialize encrypting. */
+        NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, true);
+        NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, true);
+
+        /* Initialize decrypting. */
+        NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, false);
+        NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, false);
+    }
+
+    @Test
+    public void test_EVP_CipherInit_ex_Success() throws Exception {
+        final NativeRef.EVP_CIPHER_CTX ctx =
+                new NativeRef.EVP_CIPHER_CTX(NativeCrypto.EVP_CIPHER_CTX_new());
+        final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+        NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true);
+    }
+
+    @Test
+    public void test_EVP_CIPHER_iv_length() throws Exception {
+        long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+        assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb));
+
+        long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc");
+        assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc));
+    }
+
+    @Test
+    public void test_OpenSSLKey_toJava() throws Exception {
+        OpenSSLKey key1;
+
+        BigInteger e = BigInteger.valueOf(65537);
+        key1 = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(1024, e.toByteArray()));
+        assertTrue(key1.getPublicKey() instanceof RSAPublicKey);
+
+        final long groupCtx = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
+        assertFalse(groupCtx == NULL);
+        NativeRef.EC_GROUP group1 = new NativeRef.EC_GROUP(groupCtx);
+        key1 = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group1));
+        assertTrue(key1.getPublicKey() instanceof ECPublicKey);
+    }
+
+    @Test
+    public void test_create_BIO_InputStream() throws Exception {
+        byte[] actual = "Test".getBytes("UTF-8");
+        ByteArrayInputStream is = new ByteArrayInputStream(actual);
+
+        @SuppressWarnings("resource")
+        OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
+        try {
+            byte[] buffer = new byte[1024];
+            int numRead = NativeCrypto.BIO_read(bis.getBioContext(), buffer);
+            assertEquals(actual.length, numRead);
+            assertEquals(Arrays.toString(actual),
+                    Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead)));
+        } finally {
+            bis.release();
+        }
+    }
+
+    @Test
+    public void test_create_BIO_OutputStream() throws Exception {
+        byte[] actual = "Test".getBytes("UTF-8");
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+        long ctx = NativeCrypto.create_BIO_OutputStream(os);
+        try {
+            NativeCrypto.BIO_write(ctx, actual, 0, actual.length);
+            assertEquals(actual.length, os.size());
+            assertEquals(Arrays.toString(actual), Arrays.toString(os.toByteArray()));
+        } finally {
+            NativeCrypto.BIO_free_all(ctx);
+        }
+    }
+
+    @Test
+    public void test_get_ocsp_single_extension() throws Exception {
+        final String OCSP_SCT_LIST_OID = "1.3.6.1.4.1.11129.2.4.5";
+
+        byte[] ocspResponse = readTestFile("ocsp-response.der");
+        byte[] expected = readTestFile("ocsp-response-sct-extension.der");
+        OpenSSLX509Certificate certificate =
+                OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("cert-ct-poisoned.pem"));
+        OpenSSLX509Certificate issuer =
+                OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("ca-cert.pem"));
+
+        byte[] extension = NativeCrypto.get_ocsp_single_extension(
+                ocspResponse, OCSP_SCT_LIST_OID, certificate.getContext(), certificate, issuer.getContext(), issuer);
+
+        assertEqualByteArrays(expected, extension);
+    }
+
+    private static long getRawPkeyCtxForEncrypt() throws Exception {
+        return NativeCrypto.EVP_PKEY_encrypt_init(getRsaPkey(generateRsaKey()));
+    }
+
+    private static NativeRef.EVP_PKEY_CTX getPkeyCtxForEncrypt() throws Exception {
+        return new NativeRef.EVP_PKEY_CTX(getRawPkeyCtxForEncrypt());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_encrypt_NullKeyArgument() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(null, new byte[128], 0, new byte[128], 0, 128);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_encrypt_NullOutputArgument() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(getPkeyCtxForEncrypt(), null, 0, new byte[128], 0, 128);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_encrypt_NullInputArgument() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(getPkeyCtxForEncrypt(), new byte[128], 0, null, 0, 128);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void EVP_PKEY_encrypt_OutputIndexOOBUnder() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(
+                getPkeyCtxForEncrypt(), new byte[128], -1, new byte[128], 0, 128);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void EVP_PKEY_encrypt_OutputIndexOOBOver() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(
+                getPkeyCtxForEncrypt(), new byte[128], 129, new byte[128], 0, 128);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void EVP_PKEY_encrypt_InputIndexOOBUnder() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(
+                getPkeyCtxForEncrypt(), new byte[128], 0, new byte[128], -1, 128);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void EVP_PKEY_encrypt_InputIndexOOBOver() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(
+                getPkeyCtxForEncrypt(), new byte[128], 0, new byte[128], 128, 128);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void EVP_PKEY_encrypt_InputLengthNegative() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(
+                getPkeyCtxForEncrypt(), new byte[128], 0, new byte[128], 0, -1);
+    }
+
+    @Test(expected = ArrayIndexOutOfBoundsException.class)
+    public void EVP_PKEY_encrypt_InputIndexLengthOOB() throws Exception {
+        NativeCrypto.EVP_PKEY_encrypt(
+                getPkeyCtxForEncrypt(), new byte[128], 0, new byte[128], 100, 29);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_CTX_set_rsa_mgf1_md_NullPkeyCtx() throws Exception {
+        NativeCrypto.EVP_PKEY_CTX_set_rsa_mgf1_md(NULL, EvpMdRef.SHA256.EVP_MD);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_CTX_set_rsa_mgf1_md_NullMdCtx() throws Exception {
+        long pkeyCtx = getRawPkeyCtxForEncrypt();
+        NativeRef.EVP_PKEY_CTX holder = new NativeRef.EVP_PKEY_CTX(pkeyCtx);
+        NativeCrypto.EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, NULL);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_CTX_set_rsa_oaep_md_NullPkeyCtx() throws Exception {
+        NativeCrypto.EVP_PKEY_CTX_set_rsa_oaep_md(NULL, EvpMdRef.SHA256.EVP_MD);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void EVP_PKEY_CTX_set_rsa_oaep_md_NullMdCtx() throws Exception {
+        long pkeyCtx = getRawPkeyCtxForEncrypt();
+        new NativeRef.EVP_PKEY_CTX(pkeyCtx);
+        NativeCrypto.EVP_PKEY_CTX_set_rsa_oaep_md(pkeyCtx, NULL);
+    }
+
+    @Test(expected = ParsingException.class)
+    public void d2i_X509_InvalidFailure() throws Exception {
+        NativeCrypto.d2i_X509(new byte[1]);
+    }
+
+    private static void assertContains(String actualValue, String expectedSubstring) {
+        if (actualValue == null) {
+            return;
+        }
+        if (actualValue.contains(expectedSubstring)) {
+            return;
+        }
+        fail("\"" + actualValue + "\" does not contain \"" + expectedSubstring + "\"");
+    }
+
+    private static ServerSocket newServerSocket() throws IOException {
+        return new ServerSocket(0, 50, TestUtils.getLoopbackAddress());
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeRefTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeRefTest.java
new file mode 100644
index 0000000..18a81aa
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeRefTest.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt;
+
+import junit.framework.TestCase;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class NativeRefTest extends TestCase {
+    public void test_zeroContextThrowsNullPointException() {
+        try {
+            new NativeRef(0) {
+                @Override
+                void doFree(long context) {
+                }
+            };
+            fail("Should throw NullPointerException when arguments are NULL");
+        } catch (NullPointerException expected) {
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeSslSessionTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeSslSessionTest.java
new file mode 100644
index 0000000..c80461f
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/NativeSslSessionTest.java
@@ -0,0 +1,627 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License", "www.google.com", 443);
+ * 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class NativeSslSessionTest {
+    /*
+     * Taken from external/boringssl/src/ssl/ssl_test.cc: kOpenSSLSession is a
+     * serialized SSL_SESSION.
+     */
+    private static final byte[] kOpenSSLSession = new byte[] {(byte) 0x30, (byte) 0x82, (byte) 0x05,
+            (byte) 0xAA, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x02,
+            (byte) 0x03, (byte) 0x03, (byte) 0x04, (byte) 0x02, (byte) 0xC0, (byte) 0x2F,
+            (byte) 0x04, (byte) 0x20, (byte) 0x06, (byte) 0xE5, (byte) 0x0D, (byte) 0x67,
+            (byte) 0x76, (byte) 0xAE, (byte) 0x18, (byte) 0x7E, (byte) 0x66, (byte) 0xDE,
+            (byte) 0xA3, (byte) 0x5C, (byte) 0xF0, (byte) 0x2E, (byte) 0x43, (byte) 0x51,
+            (byte) 0x2A, (byte) 0x60, (byte) 0x97, (byte) 0x19, (byte) 0xD3, (byte) 0x60,
+            (byte) 0x5A, (byte) 0xF1, (byte) 0x93, (byte) 0xDD, (byte) 0xCB, (byte) 0x24,
+            (byte) 0x57, (byte) 0x4C, (byte) 0x90, (byte) 0x90, (byte) 0x04, (byte) 0x30,
+            (byte) 0x26, (byte) 0x5A, (byte) 0xE5, (byte) 0xCE, (byte) 0x40, (byte) 0x16,
+            (byte) 0x04, (byte) 0xE5, (byte) 0xA2, (byte) 0x2E, (byte) 0x3F, (byte) 0xE3,
+            (byte) 0x27, (byte) 0xBE, (byte) 0x83, (byte) 0xEE, (byte) 0x5F, (byte) 0x94,
+            (byte) 0x5E, (byte) 0x88, (byte) 0xB3, (byte) 0x3F, (byte) 0x62, (byte) 0x88,
+            (byte) 0xD8, (byte) 0x2E, (byte) 0xC8, (byte) 0xD8, (byte) 0x57, (byte) 0x1C,
+            (byte) 0xA8, (byte) 0xC9, (byte) 0x88, (byte) 0x7C, (byte) 0x59, (byte) 0xA6,
+            (byte) 0x91, (byte) 0x4C, (byte) 0xB7, (byte) 0xDA, (byte) 0x72, (byte) 0x09,
+            (byte) 0xD2, (byte) 0x66, (byte) 0x47, (byte) 0x21, (byte) 0x6A, (byte) 0x09,
+            (byte) 0xA1, (byte) 0x06, (byte) 0x02, (byte) 0x04, (byte) 0x54, (byte) 0x43,
+            (byte) 0x3B, (byte) 0x8E, (byte) 0xA2, (byte) 0x04, (byte) 0x02, (byte) 0x02,
+            (byte) 0x01, (byte) 0x2C, (byte) 0xA3, (byte) 0x82, (byte) 0x04, (byte) 0x7A,
+            (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x76, (byte) 0x30, (byte) 0x82,
+            (byte) 0x03, (byte) 0x5E, (byte) 0xA0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x08, (byte) 0x2B, (byte) 0xD7, (byte) 0x54,
+            (byte) 0xBE, (byte) 0xC3, (byte) 0xD6, (byte) 0x4A, (byte) 0x55, (byte) 0x30,
+            (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48,
+            (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x05,
+            (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x49, (byte) 0x31, (byte) 0x0B,
+            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
+            (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x0A, (byte) 0x13, (byte) 0x0A, (byte) 0x47, (byte) 0x6F,
+            (byte) 0x6F, (byte) 0x67, (byte) 0x6C, (byte) 0x65, (byte) 0x20, (byte) 0x49,
+            (byte) 0x6E, (byte) 0x63, (byte) 0x31, (byte) 0x25, (byte) 0x30, (byte) 0x23,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x13,
+            (byte) 0x1C, (byte) 0x47, (byte) 0x6F, (byte) 0x6F, (byte) 0x67, (byte) 0x6C,
+            (byte) 0x65, (byte) 0x20, (byte) 0x49, (byte) 0x6E, (byte) 0x74, (byte) 0x65,
+            (byte) 0x72, (byte) 0x6E, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x41,
+            (byte) 0x75, (byte) 0x74, (byte) 0x68, (byte) 0x6F, (byte) 0x72, (byte) 0x69,
+            (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x47, (byte) 0x32, (byte) 0x30,
+            (byte) 0x1E, (byte) 0x17, (byte) 0x0D, (byte) 0x31, (byte) 0x34, (byte) 0x31,
+            (byte) 0x30, (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x30,
+            (byte) 0x37, (byte) 0x35, (byte) 0x37, (byte) 0x5A, (byte) 0x17, (byte) 0x0D,
+            (byte) 0x31, (byte) 0x35, (byte) 0x30, (byte) 0x31, (byte) 0x30, (byte) 0x36,
+            (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30,
+            (byte) 0x5A, (byte) 0x30, (byte) 0x68, (byte) 0x31, (byte) 0x0B, (byte) 0x30,
+            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13,
+            (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x08, (byte) 0x0C, (byte) 0x0A, (byte) 0x43, (byte) 0x61, (byte) 0x6C,
+            (byte) 0x69, (byte) 0x66, (byte) 0x6F, (byte) 0x72, (byte) 0x6E, (byte) 0x69,
+            (byte) 0x61, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0C, (byte) 0x0D,
+            (byte) 0x4D, (byte) 0x6F, (byte) 0x75, (byte) 0x6E, (byte) 0x74, (byte) 0x61,
+            (byte) 0x69, (byte) 0x6E, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
+            (byte) 0x77, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0A, (byte) 0x0C, (byte) 0x0A,
+            (byte) 0x47, (byte) 0x6F, (byte) 0x6F, (byte) 0x67, (byte) 0x6C, (byte) 0x65,
+            (byte) 0x20, (byte) 0x49, (byte) 0x6E, (byte) 0x63, (byte) 0x31, (byte) 0x17,
+            (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x03, (byte) 0x0C, (byte) 0x0E, (byte) 0x77, (byte) 0x77, (byte) 0x77,
+            (byte) 0x2E, (byte) 0x67, (byte) 0x6F, (byte) 0x6F, (byte) 0x67, (byte) 0x6C,
+            (byte) 0x65, (byte) 0x2E, (byte) 0x63, (byte) 0x6F, (byte) 0x6D, (byte) 0x30,
+            (byte) 0x82, (byte) 0x01, (byte) 0x22, (byte) 0x30, (byte) 0x0D, (byte) 0x06,
+            (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7,
+            (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
+            (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x0F, (byte) 0x00, (byte) 0x30,
+            (byte) 0x82, (byte) 0x01, (byte) 0x0A, (byte) 0x02, (byte) 0x82, (byte) 0x01,
+            (byte) 0x01, (byte) 0x00, (byte) 0x9C, (byte) 0x29, (byte) 0xE2, (byte) 0xEB,
+            (byte) 0xA6, (byte) 0x50, (byte) 0x02, (byte) 0xF8, (byte) 0xBA, (byte) 0x1F,
+            (byte) 0xCB, (byte) 0xCB, (byte) 0x7F, (byte) 0xC0, (byte) 0x3C, (byte) 0x2D,
+            (byte) 0x07, (byte) 0xA7, (byte) 0xAE, (byte) 0xEF, (byte) 0x60, (byte) 0x95,
+            (byte) 0xA7, (byte) 0x47, (byte) 0x09, (byte) 0xE1, (byte) 0x5D, (byte) 0xE5,
+            (byte) 0x92, (byte) 0x73, (byte) 0x7A, (byte) 0x86, (byte) 0xE1, (byte) 0xFD,
+            (byte) 0x72, (byte) 0xDE, (byte) 0x85, (byte) 0x16, (byte) 0x4E, (byte) 0xF4,
+            (byte) 0xA1, (byte) 0x12, (byte) 0x21, (byte) 0xFD, (byte) 0x50, (byte) 0x4D,
+            (byte) 0x04, (byte) 0x1C, (byte) 0xFD, (byte) 0xD3, (byte) 0x48, (byte) 0xD8,
+            (byte) 0xCB, (byte) 0xEE, (byte) 0xF5, (byte) 0xD7, (byte) 0x52, (byte) 0x66,
+            (byte) 0xD5, (byte) 0xBF, (byte) 0x22, (byte) 0xA8, (byte) 0xE4, (byte) 0xD0,
+            (byte) 0xF5, (byte) 0xA4, (byte) 0xF9, (byte) 0x0B, (byte) 0xB4, (byte) 0x84,
+            (byte) 0x84, (byte) 0xD7, (byte) 0x10, (byte) 0x14, (byte) 0x9B, (byte) 0xEA,
+            (byte) 0xCC, (byte) 0x7D, (byte) 0xDE, (byte) 0x30, (byte) 0xF9, (byte) 0x1B,
+            (byte) 0xE9, (byte) 0x94, (byte) 0x96, (byte) 0x1A, (byte) 0x6D, (byte) 0x72,
+            (byte) 0x18, (byte) 0x5E, (byte) 0xCC, (byte) 0x09, (byte) 0x04, (byte) 0xC6,
+            (byte) 0x41, (byte) 0x71, (byte) 0x76, (byte) 0xD1, (byte) 0x29, (byte) 0x3F,
+            (byte) 0x3B, (byte) 0x5E, (byte) 0x85, (byte) 0x4A, (byte) 0x30, (byte) 0x32,
+            (byte) 0x9D, (byte) 0x4F, (byte) 0xDB, (byte) 0xDE, (byte) 0x82, (byte) 0x66,
+            (byte) 0x39, (byte) 0xCB, (byte) 0x5C, (byte) 0xC9, (byte) 0xC5, (byte) 0x98,
+            (byte) 0x91, (byte) 0x8D, (byte) 0x32, (byte) 0xB5, (byte) 0x2F, (byte) 0xE4,
+            (byte) 0xDC, (byte) 0xB0, (byte) 0x6E, (byte) 0x21, (byte) 0xDE, (byte) 0x39,
+            (byte) 0x3C, (byte) 0x96, (byte) 0xA8, (byte) 0x32, (byte) 0xA8, (byte) 0xC1,
+            (byte) 0xD1, (byte) 0x6C, (byte) 0xA9, (byte) 0xAA, (byte) 0xF3, (byte) 0x5E,
+            (byte) 0x24, (byte) 0x70, (byte) 0xB7, (byte) 0xAB, (byte) 0x92, (byte) 0x63,
+            (byte) 0x08, (byte) 0x1E, (byte) 0x11, (byte) 0x3F, (byte) 0xB3, (byte) 0x5F,
+            (byte) 0xC7, (byte) 0x98, (byte) 0xE3, (byte) 0x1D, (byte) 0x2A, (byte) 0xC2,
+            (byte) 0x32, (byte) 0x1C, (byte) 0x3C, (byte) 0x95, (byte) 0x43, (byte) 0x16,
+            (byte) 0xE0, (byte) 0x46, (byte) 0x83, (byte) 0xC6, (byte) 0x36, (byte) 0x91,
+            (byte) 0xF4, (byte) 0xA0, (byte) 0xE1, (byte) 0x3C, (byte) 0xB8, (byte) 0x23,
+            (byte) 0xB2, (byte) 0x4F, (byte) 0x8B, (byte) 0x0C, (byte) 0x8C, (byte) 0x92,
+            (byte) 0x45, (byte) 0x24, (byte) 0x43, (byte) 0x68, (byte) 0x24, (byte) 0x06,
+            (byte) 0x84, (byte) 0x43, (byte) 0x96, (byte) 0x2C, (byte) 0x96, (byte) 0x55,
+            (byte) 0x2F, (byte) 0x32, (byte) 0xE8, (byte) 0xE0, (byte) 0xDE, (byte) 0xBF,
+            (byte) 0x52, (byte) 0x57, (byte) 0x2D, (byte) 0x08, (byte) 0x71, (byte) 0x25,
+            (byte) 0x96, (byte) 0x90, (byte) 0x54, (byte) 0x4A, (byte) 0xF1, (byte) 0x0E,
+            (byte) 0xC8, (byte) 0x58, (byte) 0x1A, (byte) 0xE7, (byte) 0x6A, (byte) 0xAB,
+            (byte) 0xA0, (byte) 0x68, (byte) 0xE0, (byte) 0xAD, (byte) 0xFD, (byte) 0xD6,
+            (byte) 0x39, (byte) 0x0F, (byte) 0x76, (byte) 0xE4, (byte) 0xC1, (byte) 0x70,
+            (byte) 0xCD, (byte) 0xDE, (byte) 0x80, (byte) 0x2B, (byte) 0xE2, (byte) 0x1C,
+            (byte) 0x87, (byte) 0x48, (byte) 0x03, (byte) 0x46, (byte) 0x0F, (byte) 0x2C,
+            (byte) 0x41, (byte) 0xF7, (byte) 0x4B, (byte) 0x1F, (byte) 0x93, (byte) 0xAE,
+            (byte) 0x3F, (byte) 0x57, (byte) 0x1F, (byte) 0x2D, (byte) 0xF5, (byte) 0x35,
+            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xA3,
+            (byte) 0x82, (byte) 0x01, (byte) 0x41, (byte) 0x30, (byte) 0x82, (byte) 0x01,
+            (byte) 0x3D, (byte) 0x30, (byte) 0x1D, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x1D, (byte) 0x25, (byte) 0x04, (byte) 0x16, (byte) 0x30, (byte) 0x14,
+            (byte) 0x06, (byte) 0x08, (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x05,
+            (byte) 0x05, (byte) 0x07, (byte) 0x03, (byte) 0x01, (byte) 0x06, (byte) 0x08,
+            (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x07,
+            (byte) 0x03, (byte) 0x02, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x1D, (byte) 0x11, (byte) 0x04, (byte) 0x12, (byte) 0x30,
+            (byte) 0x10, (byte) 0x82, (byte) 0x0E, (byte) 0x77, (byte) 0x77, (byte) 0x77,
+            (byte) 0x2E, (byte) 0x67, (byte) 0x6F, (byte) 0x6F, (byte) 0x67, (byte) 0x6C,
+            (byte) 0x65, (byte) 0x2E, (byte) 0x63, (byte) 0x6F, (byte) 0x6D, (byte) 0x30,
+            (byte) 0x68, (byte) 0x06, (byte) 0x08, (byte) 0x2B, (byte) 0x06, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x07, (byte) 0x01, (byte) 0x01, (byte) 0x04,
+            (byte) 0x5C, (byte) 0x30, (byte) 0x5A, (byte) 0x30, (byte) 0x2B, (byte) 0x06,
+            (byte) 0x08, (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x05, (byte) 0x05,
+            (byte) 0x07, (byte) 0x30, (byte) 0x02, (byte) 0x86, (byte) 0x1F, (byte) 0x68,
+            (byte) 0x74, (byte) 0x74, (byte) 0x70, (byte) 0x3A, (byte) 0x2F, (byte) 0x2F,
+            (byte) 0x70, (byte) 0x6B, (byte) 0x69, (byte) 0x2E, (byte) 0x67, (byte) 0x6F,
+            (byte) 0x6F, (byte) 0x67, (byte) 0x6C, (byte) 0x65, (byte) 0x2E, (byte) 0x63,
+            (byte) 0x6F, (byte) 0x6D, (byte) 0x2F, (byte) 0x47, (byte) 0x49, (byte) 0x41,
+            (byte) 0x47, (byte) 0x32, (byte) 0x2E, (byte) 0x63, (byte) 0x72, (byte) 0x74,
+            (byte) 0x30, (byte) 0x2B, (byte) 0x06, (byte) 0x08, (byte) 0x2B, (byte) 0x06,
+            (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x07, (byte) 0x30, (byte) 0x01,
+            (byte) 0x86, (byte) 0x1F, (byte) 0x68, (byte) 0x74, (byte) 0x74, (byte) 0x70,
+            (byte) 0x3A, (byte) 0x2F, (byte) 0x2F, (byte) 0x63, (byte) 0x6C, (byte) 0x69,
+            (byte) 0x65, (byte) 0x6E, (byte) 0x74, (byte) 0x73, (byte) 0x31, (byte) 0x2E,
+            (byte) 0x67, (byte) 0x6F, (byte) 0x6F, (byte) 0x67, (byte) 0x6C, (byte) 0x65,
+            (byte) 0x2E, (byte) 0x63, (byte) 0x6F, (byte) 0x6D, (byte) 0x2F, (byte) 0x6F,
+            (byte) 0x63, (byte) 0x73, (byte) 0x70, (byte) 0x30, (byte) 0x1D, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x1D, (byte) 0x0E, (byte) 0x04, (byte) 0x16,
+            (byte) 0x04, (byte) 0x14, (byte) 0x3B, (byte) 0x6B, (byte) 0xE0, (byte) 0x9C,
+            (byte) 0xC6, (byte) 0xC6, (byte) 0x41, (byte) 0xC8, (byte) 0xEA, (byte) 0x5C,
+            (byte) 0xFB, (byte) 0x1A, (byte) 0x58, (byte) 0x15, (byte) 0xC2, (byte) 0x1B,
+            (byte) 0x9D, (byte) 0x43, (byte) 0x19, (byte) 0x85, (byte) 0x30, (byte) 0x0C,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1D, (byte) 0x13, (byte) 0x01,
+            (byte) 0x01, (byte) 0xFF, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00,
+            (byte) 0x30, (byte) 0x1F, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1D,
+            (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80,
+            (byte) 0x14, (byte) 0x4A, (byte) 0xDD, (byte) 0x06, (byte) 0x16, (byte) 0x1B,
+            (byte) 0xBC, (byte) 0xF6, (byte) 0x68, (byte) 0xB5, (byte) 0x76, (byte) 0xF5,
+            (byte) 0x81, (byte) 0xB6, (byte) 0xBB, (byte) 0x62, (byte) 0x1A, (byte) 0xBA,
+            (byte) 0x5A, (byte) 0x81, (byte) 0x2F, (byte) 0x30, (byte) 0x17, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x1D, (byte) 0x20, (byte) 0x04, (byte) 0x10,
+            (byte) 0x30, (byte) 0x0E, (byte) 0x30, (byte) 0x0C, (byte) 0x06, (byte) 0x0A,
+            (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x01, (byte) 0xD6,
+            (byte) 0x79, (byte) 0x02, (byte) 0x05, (byte) 0x01, (byte) 0x30, (byte) 0x30,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1D, (byte) 0x1F, (byte) 0x04,
+            (byte) 0x29, (byte) 0x30, (byte) 0x27, (byte) 0x30, (byte) 0x25, (byte) 0xA0,
+            (byte) 0x23, (byte) 0xA0, (byte) 0x21, (byte) 0x86, (byte) 0x1F, (byte) 0x68,
+            (byte) 0x74, (byte) 0x74, (byte) 0x70, (byte) 0x3A, (byte) 0x2F, (byte) 0x2F,
+            (byte) 0x70, (byte) 0x6B, (byte) 0x69, (byte) 0x2E, (byte) 0x67, (byte) 0x6F,
+            (byte) 0x6F, (byte) 0x67, (byte) 0x6C, (byte) 0x65, (byte) 0x2E, (byte) 0x63,
+            (byte) 0x6F, (byte) 0x6D, (byte) 0x2F, (byte) 0x47, (byte) 0x49, (byte) 0x41,
+            (byte) 0x47, (byte) 0x32, (byte) 0x2E, (byte) 0x63, (byte) 0x72, (byte) 0x6C,
+            (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, (byte) 0x01,
+            (byte) 0x01, (byte) 0x00, (byte) 0x9A, (byte) 0x39, (byte) 0x70, (byte) 0x81,
+            (byte) 0x76, (byte) 0x8A, (byte) 0x94, (byte) 0xCB, (byte) 0x96, (byte) 0xF1,
+            (byte) 0xCA, (byte) 0xAF, (byte) 0x96, (byte) 0xAE, (byte) 0x1D, (byte) 0x73,
+            (byte) 0xB3, (byte) 0x2C, (byte) 0x82, (byte) 0x16, (byte) 0x29, (byte) 0xB5,
+            (byte) 0x3C, (byte) 0x7E, (byte) 0x55, (byte) 0x53, (byte) 0x6F, (byte) 0xB2,
+            (byte) 0xBC, (byte) 0x34, (byte) 0x96, (byte) 0xAE, (byte) 0x00, (byte) 0xD8,
+            (byte) 0xF2, (byte) 0x26, (byte) 0xD1, (byte) 0x18, (byte) 0x99, (byte) 0x9F,
+            (byte) 0x7D, (byte) 0xFD, (byte) 0xEB, (byte) 0xE0, (byte) 0xBB, (byte) 0x9D,
+            (byte) 0xE6, (byte) 0x46, (byte) 0xA5, (byte) 0x74, (byte) 0xAB, (byte) 0x3D,
+            (byte) 0x93, (byte) 0xC6, (byte) 0x25, (byte) 0x28, (byte) 0x3D, (byte) 0xC8,
+            (byte) 0x4C, (byte) 0x6E, (byte) 0xCF, (byte) 0xD1, (byte) 0x84, (byte) 0xFF,
+            (byte) 0x46, (byte) 0x4F, (byte) 0x21, (byte) 0x2E, (byte) 0x07, (byte) 0xC4,
+            (byte) 0xB8, (byte) 0xB7, (byte) 0x2A, (byte) 0xE5, (byte) 0xC7, (byte) 0x34,
+            (byte) 0xC6, (byte) 0xA9, (byte) 0x84, (byte) 0xE3, (byte) 0x6C, (byte) 0x49,
+            (byte) 0xF8, (byte) 0x4A, (byte) 0x36, (byte) 0xBB, (byte) 0x3A, (byte) 0xBD,
+            (byte) 0xAD, (byte) 0x8A, (byte) 0x2B, (byte) 0x73, (byte) 0x97, (byte) 0xA6,
+            (byte) 0x30, (byte) 0x2C, (byte) 0x5F, (byte) 0xE4, (byte) 0xBD, (byte) 0x13,
+            (byte) 0x24, (byte) 0xE5, (byte) 0xD9, (byte) 0xA8, (byte) 0x74, (byte) 0x29,
+            (byte) 0x38, (byte) 0x47, (byte) 0x2E, (byte) 0xA6, (byte) 0xD6, (byte) 0x50,
+            (byte) 0xE0, (byte) 0xE8, (byte) 0xDD, (byte) 0x60, (byte) 0xC7, (byte) 0xD2,
+            (byte) 0xC6, (byte) 0x4E, (byte) 0x54, (byte) 0xCE, (byte) 0xE7, (byte) 0x94,
+            (byte) 0x84, (byte) 0x0D, (byte) 0xE8, (byte) 0x81, (byte) 0x92, (byte) 0x91,
+            (byte) 0x71, (byte) 0x19, (byte) 0x1D, (byte) 0x07, (byte) 0x75, (byte) 0x9E,
+            (byte) 0x59, (byte) 0x1A, (byte) 0x7E, (byte) 0x9D, (byte) 0x84, (byte) 0x61,
+            (byte) 0xC7, (byte) 0x84, (byte) 0xAD, (byte) 0xA3, (byte) 0x6A, (byte) 0xED,
+            (byte) 0xD8, (byte) 0x0D, (byte) 0x0C, (byte) 0x2A, (byte) 0x66, (byte) 0x3D,
+            (byte) 0xD7, (byte) 0xAE, (byte) 0x46, (byte) 0x1D, (byte) 0x4A, (byte) 0x8C,
+            (byte) 0x2B, (byte) 0xD6, (byte) 0x1A, (byte) 0x69, (byte) 0x71, (byte) 0xC3,
+            (byte) 0x5E, (byte) 0xA0, (byte) 0x6E, (byte) 0xED, (byte) 0x27, (byte) 0x9F,
+            (byte) 0xAF, (byte) 0x5B, (byte) 0x92, (byte) 0xA0, (byte) 0x03, (byte) 0xFD,
+            (byte) 0x83, (byte) 0x22, (byte) 0x09, (byte) 0x29, (byte) 0xE8, (byte) 0xA1,
+            (byte) 0x32, (byte) 0x2B, (byte) 0xEC, (byte) 0x1A, (byte) 0xA2, (byte) 0x75,
+            (byte) 0x4C, (byte) 0x3E, (byte) 0x99, (byte) 0x71, (byte) 0xCE, (byte) 0x8B,
+            (byte) 0x31, (byte) 0xEF, (byte) 0x9D, (byte) 0x37, (byte) 0x63, (byte) 0xFC,
+            (byte) 0x71, (byte) 0x91, (byte) 0x10, (byte) 0x1E, (byte) 0xD0, (byte) 0xF5,
+            (byte) 0xCB, (byte) 0x6F, (byte) 0x7A, (byte) 0xBA, (byte) 0x5E, (byte) 0x0C,
+            (byte) 0x8A, (byte) 0xFA, (byte) 0xA4, (byte) 0xDE, (byte) 0x36, (byte) 0xAD,
+            (byte) 0x51, (byte) 0x52, (byte) 0xFC, (byte) 0xFE, (byte) 0x10, (byte) 0xB0,
+            (byte) 0x81, (byte) 0xC8, (byte) 0x7D, (byte) 0x03, (byte) 0xC3, (byte) 0xB8,
+            (byte) 0x3C, (byte) 0x66, (byte) 0x6A, (byte) 0xF5, (byte) 0x6A, (byte) 0x81,
+            (byte) 0x7C, (byte) 0x45, (byte) 0xA6, (byte) 0x23, (byte) 0x21, (byte) 0xE1,
+            (byte) 0xD5, (byte) 0xD3, (byte) 0xED, (byte) 0x6E, (byte) 0x0D, (byte) 0x65,
+            (byte) 0x39, (byte) 0x77, (byte) 0x58, (byte) 0x09, (byte) 0x6B, (byte) 0x63,
+            (byte) 0xA4, (byte) 0x02, (byte) 0x04, (byte) 0x00, (byte) 0xA5, (byte) 0x03,
+            (byte) 0x02, (byte) 0x01, (byte) 0x14, (byte) 0xA9, (byte) 0x05, (byte) 0x02,
+            (byte) 0x03, (byte) 0x01, (byte) 0x89, (byte) 0xC0, (byte) 0xAA, (byte) 0x81,
+            (byte) 0xA7, (byte) 0x04, (byte) 0x81, (byte) 0xA4, (byte) 0x1C, (byte) 0x14,
+            (byte) 0x42, (byte) 0xFA, (byte) 0x1E, (byte) 0x3A, (byte) 0x4D, (byte) 0x0A,
+            (byte) 0x83, (byte) 0x7E, (byte) 0x92, (byte) 0x61, (byte) 0x37, (byte) 0x0B,
+            (byte) 0x12, (byte) 0x45, (byte) 0xEA, (byte) 0x2B, (byte) 0x03, (byte) 0x81,
+            (byte) 0x7C, (byte) 0x5F, (byte) 0x6F, (byte) 0x13, (byte) 0x82, (byte) 0x97,
+            (byte) 0xD0, (byte) 0xDC, (byte) 0x5E, (byte) 0x2F, (byte) 0x08, (byte) 0xDC,
+            (byte) 0x0D, (byte) 0x3A, (byte) 0x6C, (byte) 0xBA, (byte) 0x1D, (byte) 0xEA,
+            (byte) 0x5C, (byte) 0x46, (byte) 0x99, (byte) 0xF7, (byte) 0xDD, (byte) 0xAB,
+            (byte) 0xD4, (byte) 0xDD, (byte) 0xFC, (byte) 0x54, (byte) 0x37, (byte) 0x32,
+            (byte) 0x4B, (byte) 0xA3, (byte) 0xFB, (byte) 0x23, (byte) 0xA1, (byte) 0xC1,
+            (byte) 0x60, (byte) 0xDF, (byte) 0x41, (byte) 0xB0, (byte) 0xD1, (byte) 0xCC,
+            (byte) 0xDF, (byte) 0xAD, (byte) 0xB3, (byte) 0x66, (byte) 0x76, (byte) 0x36,
+            (byte) 0xEC, (byte) 0x6A, (byte) 0x53, (byte) 0xC3, (byte) 0xE2, (byte) 0xB0,
+            (byte) 0x77, (byte) 0xBE, (byte) 0x75, (byte) 0x08, (byte) 0xBA, (byte) 0x17,
+            (byte) 0x14, (byte) 0xFA, (byte) 0x1A, (byte) 0x30, (byte) 0xE7, (byte) 0xB9,
+            (byte) 0xED, (byte) 0xD6, (byte) 0xC1, (byte) 0xA5, (byte) 0x7A, (byte) 0x2B,
+            (byte) 0xA3, (byte) 0xA3, (byte) 0xDD, (byte) 0xDC, (byte) 0x14, (byte) 0xDB,
+            (byte) 0x7F, (byte) 0xF4, (byte) 0xF3, (byte) 0xAF, (byte) 0xCF, (byte) 0x0A,
+            (byte) 0xD3, (byte) 0xAC, (byte) 0x84, (byte) 0x39, (byte) 0x30, (byte) 0xCA,
+            (byte) 0x3C, (byte) 0xD8, (byte) 0xF7, (byte) 0xFA, (byte) 0x29, (byte) 0xDB,
+            (byte) 0x31, (byte) 0xA5, (byte) 0x62, (byte) 0x82, (byte) 0xD2, (byte) 0xB8,
+            (byte) 0x3C, (byte) 0xBC, (byte) 0x8F, (byte) 0xAB, (byte) 0xE4, (byte) 0xE8,
+            (byte) 0xA7, (byte) 0x2C, (byte) 0xEF, (byte) 0xC7, (byte) 0xD5, (byte) 0x12,
+            (byte) 0x16, (byte) 0x04, (byte) 0x6F, (byte) 0xCA, (byte) 0xEA, (byte) 0x31,
+            (byte) 0x9F, (byte) 0x41, (byte) 0xE0, (byte) 0x6F, (byte) 0xE4, (byte) 0x74,
+            (byte) 0x03, (byte) 0x78, (byte) 0xFA, (byte) 0x48, (byte) 0xB4, (byte) 0x6E,
+            (byte) 0xC8, (byte) 0xE7, (byte) 0x40, (byte) 0x8B, (byte) 0x88, (byte) 0x2F,
+            (byte) 0xED, (byte) 0x8E, (byte) 0x68, (byte) 0x96, (byte) 0x2C, (byte) 0xA7,
+            (byte) 0xB6, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x00};
+
+    private static final byte[] DUMMY_CERT =
+            new byte[] {(byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x58, (byte) 0x30,
+                    (byte) 0x82, (byte) 0x01, (byte) 0xC1, (byte) 0xA0, (byte) 0x03, (byte) 0x02,
+                    (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xFB,
+                    (byte) 0xB0, (byte) 0x4C, (byte) 0x2E, (byte) 0xAB, (byte) 0x10, (byte) 0x9B,
+                    (byte) 0x0C, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A,
+                    (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01,
+                    (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x45,
+                    (byte) 0x31, (byte) 0x0B, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+                    (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
+                    (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+                    (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0C, (byte) 0x0A,
+                    (byte) 0x53, (byte) 0x6F, (byte) 0x6D, (byte) 0x65, (byte) 0x2D, (byte) 0x53,
+                    (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21,
+                    (byte) 0x30, (byte) 0x1F, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+                    (byte) 0x0A, (byte) 0x0C, (byte) 0x18, (byte) 0x49, (byte) 0x6E, (byte) 0x74,
+                    (byte) 0x65, (byte) 0x72, (byte) 0x6E, (byte) 0x65, (byte) 0x74, (byte) 0x20,
+                    (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74,
+                    (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20,
+                    (byte) 0x4C, (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x1E, (byte) 0x17,
+                    (byte) 0x0D, (byte) 0x31, (byte) 0x34, (byte) 0x30, (byte) 0x34, (byte) 0x32,
+                    (byte) 0x33, (byte) 0x32, (byte) 0x30, (byte) 0x35, (byte) 0x30, (byte) 0x34,
+                    (byte) 0x30, (byte) 0x5A, (byte) 0x17, (byte) 0x0D, (byte) 0x31, (byte) 0x37,
+                    (byte) 0x30, (byte) 0x34, (byte) 0x32, (byte) 0x32, (byte) 0x32, (byte) 0x30,
+                    (byte) 0x35, (byte) 0x30, (byte) 0x34, (byte) 0x30, (byte) 0x5A, (byte) 0x30,
+                    (byte) 0x45, (byte) 0x31, (byte) 0x0B, (byte) 0x30, (byte) 0x09, (byte) 0x06,
+                    (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02,
+                    (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11,
+                    (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0C,
+                    (byte) 0x0A, (byte) 0x53, (byte) 0x6F, (byte) 0x6D, (byte) 0x65, (byte) 0x2D,
+                    (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31,
+                    (byte) 0x21, (byte) 0x30, (byte) 0x1F, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+                    (byte) 0x04, (byte) 0x0A, (byte) 0x0C, (byte) 0x18, (byte) 0x49, (byte) 0x6E,
+                    (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6E, (byte) 0x65, (byte) 0x74,
+                    (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69,
+                    (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79,
+                    (byte) 0x20, (byte) 0x4C, (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x81,
+                    (byte) 0x9F, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A,
+                    (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01,
+                    (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81,
+                    (byte) 0x8D, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02,
+                    (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xD8, (byte) 0x2B, (byte) 0xC8,
+                    (byte) 0xA6, (byte) 0x32, (byte) 0xE4, (byte) 0x62, (byte) 0xFF, (byte) 0x4D,
+                    (byte) 0xF3, (byte) 0xD0, (byte) 0xAD, (byte) 0x59, (byte) 0x8B, (byte) 0x45,
+                    (byte) 0xA7, (byte) 0xBD, (byte) 0xF1, (byte) 0x47, (byte) 0xBF, (byte) 0x09,
+                    (byte) 0x58, (byte) 0x7B, (byte) 0x22, (byte) 0xBD, (byte) 0x35, (byte) 0xAE,
+                    (byte) 0x97, (byte) 0x25, (byte) 0x86, (byte) 0x94, (byte) 0xA0, (byte) 0x80,
+                    (byte) 0xC0, (byte) 0xB4, (byte) 0x1F, (byte) 0x76, (byte) 0x91, (byte) 0x67,
+                    (byte) 0x46, (byte) 0x31, (byte) 0xD0, (byte) 0x10, (byte) 0x84, (byte) 0xB7,
+                    (byte) 0x22, (byte) 0x1E, (byte) 0x70, (byte) 0x23, (byte) 0x91, (byte) 0x72,
+                    (byte) 0xC8, (byte) 0xE9, (byte) 0x6D, (byte) 0x79, (byte) 0x3A, (byte) 0x85,
+                    (byte) 0x77, (byte) 0x80, (byte) 0x0F, (byte) 0xC4, (byte) 0x95, (byte) 0x16,
+                    (byte) 0x75, (byte) 0xC5, (byte) 0x4A, (byte) 0x71, (byte) 0x4C, (byte) 0xC8,
+                    (byte) 0x63, (byte) 0x3F, (byte) 0xA3, (byte) 0xF2, (byte) 0x63, (byte) 0x9C,
+                    (byte) 0x2A, (byte) 0x4F, (byte) 0x9A, (byte) 0xFA, (byte) 0xCB, (byte) 0xC1,
+                    (byte) 0x71, (byte) 0x6E, (byte) 0x28, (byte) 0x85, (byte) 0x28, (byte) 0xA0,
+                    (byte) 0x27, (byte) 0x1E, (byte) 0x65, (byte) 0x1C, (byte) 0xAE, (byte) 0x07,
+                    (byte) 0xD5, (byte) 0x5B, (byte) 0x6F, (byte) 0x2D, (byte) 0x43, (byte) 0xED,
+                    (byte) 0x2B, (byte) 0x90, (byte) 0xB1, (byte) 0x8C, (byte) 0xAF, (byte) 0x24,
+                    (byte) 0x6D, (byte) 0xAE, (byte) 0xE9, (byte) 0x17, (byte) 0x3A, (byte) 0x05,
+                    (byte) 0xC1, (byte) 0xBF, (byte) 0xB8, (byte) 0x1C, (byte) 0xAE, (byte) 0x65,
+                    (byte) 0x3B, (byte) 0x1B, (byte) 0x58, (byte) 0xC2, (byte) 0xD9, (byte) 0xAE,
+                    (byte) 0xD6, (byte) 0xAA, (byte) 0x67, (byte) 0x88, (byte) 0xF1, (byte) 0x02,
+                    (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xA3, (byte) 0x50,
+                    (byte) 0x30, (byte) 0x4E, (byte) 0x30, (byte) 0x1D, (byte) 0x06, (byte) 0x03,
+                    (byte) 0x55, (byte) 0x1D, (byte) 0x0E, (byte) 0x04, (byte) 0x16, (byte) 0x04,
+                    (byte) 0x14, (byte) 0x8B, (byte) 0x75, (byte) 0xD5, (byte) 0xAC, (byte) 0xCB,
+                    (byte) 0x08, (byte) 0xBE, (byte) 0x0E, (byte) 0x1F, (byte) 0x65, (byte) 0xB7,
+                    (byte) 0xFA, (byte) 0x56, (byte) 0xBE, (byte) 0x6C, (byte) 0xA7, (byte) 0x75,
+                    (byte) 0xDA, (byte) 0x85, (byte) 0xAF, (byte) 0x30, (byte) 0x1F, (byte) 0x06,
+                    (byte) 0x03, (byte) 0x55, (byte) 0x1D, (byte) 0x23, (byte) 0x04, (byte) 0x18,
+                    (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x8B, (byte) 0x75,
+                    (byte) 0xD5, (byte) 0xAC, (byte) 0xCB, (byte) 0x08, (byte) 0xBE, (byte) 0x0E,
+                    (byte) 0x1F, (byte) 0x65, (byte) 0xB7, (byte) 0xFA, (byte) 0x56, (byte) 0xBE,
+                    (byte) 0x6C, (byte) 0xA7, (byte) 0x75, (byte) 0xDA, (byte) 0x85, (byte) 0xAF,
+                    (byte) 0x30, (byte) 0x0C, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1D,
+                    (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01,
+                    (byte) 0x01, (byte) 0xFF, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09,
+                    (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D,
+                    (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03,
+                    (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x3B, (byte) 0xE8, (byte) 0x78,
+                    (byte) 0x6D, (byte) 0x95, (byte) 0xD6, (byte) 0x3D, (byte) 0x6A, (byte) 0xF7,
+                    (byte) 0x13, (byte) 0x19, (byte) 0x2C, (byte) 0x1B, (byte) 0xC2, (byte) 0x88,
+                    (byte) 0xAE, (byte) 0x22, (byte) 0xAB, (byte) 0xF4, (byte) 0x8D, (byte) 0x32,
+                    (byte) 0xF5, (byte) 0x7C, (byte) 0x71, (byte) 0x67, (byte) 0xCF, (byte) 0x2D,
+                    (byte) 0xD1, (byte) 0x1C, (byte) 0xC2, (byte) 0xC3, (byte) 0x87, (byte) 0xE2,
+                    (byte) 0xE9, (byte) 0xBE, (byte) 0x89, (byte) 0x5C, (byte) 0xE4, (byte) 0x34,
+                    (byte) 0xAB, (byte) 0x48, (byte) 0x91, (byte) 0xC2, (byte) 0x3F, (byte) 0x95,
+                    (byte) 0xAE, (byte) 0x2B, (byte) 0x47, (byte) 0x9E, (byte) 0x25, (byte) 0x78,
+                    (byte) 0x6B, (byte) 0x4F, (byte) 0x9A, (byte) 0x10, (byte) 0xA4, (byte) 0x72,
+                    (byte) 0xFD, (byte) 0xCF, (byte) 0xF7, (byte) 0x02, (byte) 0x0C, (byte) 0xB0,
+                    (byte) 0x0A, (byte) 0x08, (byte) 0xA4, (byte) 0x5A, (byte) 0xE2, (byte) 0xE5,
+                    (byte) 0x74, (byte) 0x7E, (byte) 0x11, (byte) 0x1D, (byte) 0x39, (byte) 0x60,
+                    (byte) 0x6A, (byte) 0xC9, (byte) 0x1F, (byte) 0x69, (byte) 0xF3, (byte) 0x2E,
+                    (byte) 0x63, (byte) 0x26, (byte) 0xDC, (byte) 0x9E, (byte) 0xEF, (byte) 0x6B,
+                    (byte) 0x7A, (byte) 0x0A, (byte) 0xE1, (byte) 0x54, (byte) 0x57, (byte) 0x98,
+                    (byte) 0xAA, (byte) 0x72, (byte) 0x91, (byte) 0x78, (byte) 0x04, (byte) 0x7E,
+                    (byte) 0x1F, (byte) 0x8F, (byte) 0x65, (byte) 0x4D, (byte) 0x1F, (byte) 0x0B,
+                    (byte) 0x12, (byte) 0xAC, (byte) 0x9C, (byte) 0x24, (byte) 0x0F, (byte) 0x84,
+                    (byte) 0x14, (byte) 0x1A, (byte) 0x55, (byte) 0x2D, (byte) 0x1F, (byte) 0xBB,
+                    (byte) 0xF0, (byte) 0x9D, (byte) 0x09, (byte) 0xB2, (byte) 0x08, (byte) 0x5C,
+                    (byte) 0x59, (byte) 0x32, (byte) 0x65, (byte) 0x80, (byte) 0x26};
+
+    private static final byte[] DUMMY_OCSP_DATA = new byte[1];
+
+    private static final byte[] DUMMY_TLS_SCT_DATA = new byte[1];
+
+    private static TestSessionBuilder getType1() {
+        return new TestSessionBuilder()
+                .setType(0x01)
+                .setSessionData(kOpenSSLSession)
+                .addCertificate(DUMMY_CERT);
+    }
+
+    private static TestSessionBuilder getType2() {
+        return new TestSessionBuilder()
+                .setType(0x02)
+                .setSessionData(kOpenSSLSession)
+                .addCertificate(DUMMY_CERT)
+                .addOcspData(DUMMY_OCSP_DATA);
+    }
+
+    private static TestSessionBuilder getType3() {
+        return new TestSessionBuilder()
+                .setType(0x03)
+                .setSessionData(kOpenSSLSession)
+                .addCertificate(DUMMY_CERT)
+                .addOcspData(DUMMY_OCSP_DATA)
+                .setTlsSctData(DUMMY_TLS_SCT_DATA);
+    }
+
+    @Test
+    public void toSession_EmptyArray_Invalid_Failure() throws Exception {
+        assertInvalidSession(new byte[0]);
+    }
+
+    @Test
+    public void toSession_Type1_Valid_Success() throws Exception {
+        assertValidSession(getType1().build());
+    }
+
+    @Test
+    public void toSession_Type2_Valid_Success() throws Exception {
+        assertValidSession(getType2().build());
+    }
+
+    @Test
+    public void toSession_Type3_Valid_Success() throws Exception {
+        assertValidSession(getType3().build());
+    }
+
+    private static void assertValidSession(byte[] data) {
+        assertNotNull(NativeSslSession.newInstance(null, data, "www.google.com", 443));
+    }
+
+    @Test
+    public void toSession_Type3_Truncated_Failure() throws Exception {
+        assertTruncatedSessionFails(getType3().build());
+    }
+
+    private static void assertInvalidSession(byte[] data) {
+        assertNull(NativeSslSession.newInstance(null, data, "www.google.com", 443));
+    }
+
+    private static void check_reserializableFromByteArray_roundTrip(
+            byte[] data, byte[] expectedTrailingBytesAfterReserialization) throws Exception {
+        NativeSslSession session =
+                NativeSslSession.newInstance(null, data, "www.example.com", 12345);
+        byte[] sessionBytes = session.toBytes();
+
+        NativeSslSession session2 =
+                NativeSslSession.newInstance(null, sessionBytes, "www.example.com", 12345);
+        byte[] sessionBytes2 = session2.toBytes();
+
+        assertSSLSessionEquals(session, session2);
+        assertByteArrayEquals(sessionBytes, sessionBytes2);
+
+        assertEquals("www.example.com", session.getPeerHost());
+        assertEquals(12345, session.getPeerPort());
+        assertTrue(sessionBytes.length >= data.length);
+
+        byte[] expectedReserializedData = concat(data, expectedTrailingBytesAfterReserialization);
+        // AbstractSessionContext.toBytes() always writes type 3 == OPEN_SSL_WITH_TLS_SCT
+        expectedReserializedData[3] = 3;
+        assertByteArrayEquals(expectedReserializedData, sessionBytes);
+    }
+
+    @Test
+    public void toSession_UnknownType_Failure() throws Exception {
+        assertInvalidSession(getType3().setType((byte) 0xEE).build());
+    }
+
+    @Test
+    public void toSession_CertificatesCountTooLarge_Failure() throws Exception {
+        assertInvalidSession(getType3().setCertificatesLength(16834).build());
+    }
+
+    @Test
+    public void toSession_CertificatesCountNegative_Failure() throws Exception {
+        assertInvalidSession(getType3().setCertificatesLength(-1).build());
+    }
+
+    @Test
+    public void toSession_CertificateSizeNegative_Failure() throws Exception {
+        assertInvalidSession(getType3().setCertificateLength(0, -1).build());
+    }
+
+    @Test
+    public void toSession_CertificateSizeTooLarge_Failure() throws Exception {
+        assertInvalidSession(getType3().setCertificateLength(0, 16834).build());
+    }
+
+    @Test
+    public void toSession_SessionDataSizeTooLarge_Failure() throws Exception {
+        assertInvalidSession(getType3().setSessionDataLength(16834).build());
+    }
+
+    @Test
+    public void toSession_SessionDataSizeNegative_Failure() throws Exception {
+        assertInvalidSession(getType3().setSessionDataLength(-1).build());
+    }
+
+    @Test
+    public void toSession_OcspDatasNumberTooMany_Failure() throws Exception {
+        assertInvalidSession(getType3().setOcspDatasLength(32791).build());
+    }
+
+    @Test
+    public void toSession_OcspDatasNumberNegative_Failure() throws Exception {
+        assertInvalidSession(getType3().setOcspDatasLength(-1).build());
+    }
+
+    @Test
+    public void toSession_OcspDataSizeNegative_Failure() throws Exception {
+        assertInvalidSession(getType3().setOcspDataLength(0, -1).build());
+    }
+
+    @Test
+    public void toSession_OcspDataSizeTooLarge_Failure() throws Exception {
+        assertInvalidSession(getType3().setOcspDataLength(0, 92948).build());
+    }
+
+    @Test
+    public void toSession_TlsSctDataSizeNegative_Failure() throws Exception {
+        assertInvalidSession(getType3().setTlsSctDataLength(-1).build());
+    }
+
+    @Test
+    public void toSession_TlsSctDataSizeTooLarge_Failure() throws Exception {
+        assertInvalidSession(getType3().setTlsSctDataLength(931148).build());
+    }
+
+    @Test
+    public void toSession_Type2OcspDataEmpty_Success() throws Exception {
+        assertValidSession(getType1().setType(0x02).setOcspDataEmpty().build());
+    }
+
+    @Test
+    public void toSession_Type3TlsSctDataEmpty_Success() throws Exception {
+        assertValidSession(getType2().setType(0x03).setTlsSctDataEmpty().build());
+    }
+
+    @Test
+    public void toSession_Type3OcspAndTlsSctDataEmpty_Success() throws Exception {
+        assertValidSession(
+                getType1().setType(0x03).setOcspDataEmpty().setTlsSctDataEmpty().build());
+    }
+
+    private static void assertTrailingDataFails(byte[] validSession) {
+        byte[] invalidSession = new byte[validSession.length + 1];
+        System.arraycopy(validSession, 0, invalidSession, 0, validSession.length);
+        assertInvalidSession(invalidSession);
+    }
+
+    @Test
+    public void toSession_Type1TrailingData_Failure() throws Exception {
+        assertTrailingDataFails(getType1().build());
+    }
+
+    @Test
+    public void toSession_Type2TrailingData_Failure() throws Exception {
+        assertTrailingDataFails(getType2().build());
+    }
+
+    @Test
+    public void toSession_Type3TrailingData_Failure() throws Exception {
+        assertTrailingDataFails(getType3().build());
+    }
+
+    @Test
+    public void test_reserializableFromByteArray_roundTrip_type1() throws Exception {
+        // Converting OPEN_SSL (type 1) -> OPEN_SSL_WITH_TLS_SCT (type 3) adds
+        // eight zero-bytes:
+        //  1.) 4 bytes for int32 value 0 == countOcspResponses
+        //  2.) 4 bytes for int32 value 0 == tlsSctDataLength
+        // since OPEN_SSL (type 1) cannot contain OSCP or TLS SCT data.
+        check_reserializableFromByteArray_roundTrip(getType1().build(), new byte[8]);
+    }
+
+    @Test
+    public void test_reserializableFromByteArray_roundTrip_type2() throws Exception {
+        // Converting OPEN_SSL_WITH_OCSP (type 2) -> OPEN_SSL_WITH_TLS_SCT (type 3) adds
+        // four zero-bytes for int32 value 0 == tlsSctDataLength
+        // since OPEN_SSL_WITH_OCSP (type 2) cannot contain TLS SCT data.
+        check_reserializableFromByteArray_roundTrip(getType2().build(), new byte[4]);
+    }
+
+    @Test
+    public void test_reserializableFromByteArray_roundTrip_type3() throws Exception {
+        check_reserializableFromByteArray_roundTrip(getType3().build(), new byte[0]);
+    }
+
+    private static void assertSSLSessionEquals(NativeSslSession a, NativeSslSession b)
+            throws Exception {
+        assertEquals(a.getCipherSuite(), b.getCipherSuite());
+        assertByteArrayEquals(a.getId(), b.getId());
+        assertEquals(a.getPeerHost(), b.getPeerHost());
+        assertEquals(a.getPeerPort(), b.getPeerPort());
+        assertEquals(a.getProtocol(), b.getProtocol());
+    }
+
+    private static byte[] concat(byte[] a, byte[] b) {
+        byte[] result = new byte[a.length + b.length];
+        System.arraycopy(a, 0, result, 0, a.length);
+        System.arraycopy(b, 0, result, a.length, b.length);
+        return result;
+    }
+
+    private void assertTruncatedSessionFails(byte[] validSession) {
+        for (int i = 0; i < validSession.length - 1; i++) {
+            byte[] truncatedSession = new byte[i];
+            System.arraycopy(validSession, 0, truncatedSession, 0, i);
+            assertNull("Truncating to " + i + " bytes of " + validSession.length
+                            + " should not succeed",
+                    NativeSslSession.newInstance(null, truncatedSession, "www.google.com", 443));
+        }
+    }
+
+    private static void assertByteArrayEquals(byte[] expected, byte[] actual) {
+        // If running on OpenJDK 8+, could use java.util.Base64 for better failure messages:
+        // assertEquals(Base64.encode(expected), Base64.encode(actual));
+        assertTrue("Expected " + Arrays.toString(expected) + ", got " + Arrays.toString(actual),
+                Arrays.equals(expected, actual));
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLKeyTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLKeyTest.java
new file mode 100644
index 0000000..51e7077
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLKeyTest.java
@@ -0,0 +1,70 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import junit.framework.TestCase;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSLKeyTest extends TestCase {
+    static final String RSA_PUBLIC_KEY =
+        "-----BEGIN PUBLIC KEY-----\n" +
+        "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOHsK2E2FLYfEMWEVH/rJMTqDZLLLysh\n" +
+        "AH5odcfhYdF9xvFFU9rqJT7zXUDH4SjdhZGUUAO5IOC1e8ZIyRsbiY0CAwEAAQ==\n" +
+        "-----END PUBLIC KEY-----";
+
+    static final String RSA_PRIVATE_KEY =
+        "-----BEGIN RSA PRIVATE KEY-----\n" +
+        "MIIBOgIBAAJBAOHsK2E2FLYfEMWEVH/rJMTqDZLLLyshAH5odcfhYdF9xvFFU9rq\n" +
+        "JT7zXUDH4SjdhZGUUAO5IOC1e8ZIyRsbiY0CAwEAAQJBALcu+oGJC0QcbknpIWbT\n" +
+        "L+4mZTkYXLeYu8DDTHT0j47+6eEyYBOoRGcZDdlMWquvFIrV48RSot0GPh1MBE1p\n" +
+        "lKECIQD4krM4UshCwUHH9ZVkoxcPsxzPTTW7ukky4RZVN6mgWQIhAOisOAXVVjon\n" +
+        "fbGNQ6CezH7oOttEeZmiWCu48AVCyixVAiAaDZ41OA//Vywi3i2jV6iyH47Ud347\n" +
+        "R+ImMAtcMTJZOQIgF0+Z1UvIdc8bErzad68xQc22h91WaYQQXWEL+xrz8nkCIDcA\n" +
+        "MpCP/H5qTCj/l5rxQg+/NUGCg2pHHNLL+cy5N5RM\n" +
+        "-----END RSA PRIVATE KEY-----";
+
+    static final BigInteger RSA_MODULUS = new BigInteger(
+        "e1ec2b613614b61f10c584547feb24c4ea0d92cb2f2b21007e6875c7e161d17d" +
+        "c6f14553daea253ef35d40c7e128dd8591945003b920e0b57bc648c91b1b898d", 16);
+
+    static final BigInteger RSA_PUBLIC_EXPONENT = new BigInteger("10001", 16);
+    static final BigInteger RSA_PRIVATE_EXPONENT = new BigInteger(
+        "b72efa81890b441c6e49e92166d32fee266539185cb798bbc0c34c74f48f8efe" +
+        "e9e1326013a84467190dd94c5aabaf148ad5e3c452a2dd063e1d4c044d6994a1", 16);
+
+    public void test_fromPublicKeyPemInputStream() throws Exception {
+        ByteArrayInputStream is = new ByteArrayInputStream(RSA_PUBLIC_KEY.getBytes("UTF-8"));
+        OpenSSLKey key = OpenSSLKey.fromPublicKeyPemInputStream(is);
+        OpenSSLRSAPublicKey publicKey = (OpenSSLRSAPublicKey)key.getPublicKey();
+        assertEquals(RSA_MODULUS, publicKey.getModulus());
+        assertEquals(RSA_PUBLIC_EXPONENT, publicKey.getPublicExponent());
+    }
+
+    public void test_fromPrivateKeyPemInputStream() throws Exception {
+        ByteArrayInputStream is = new ByteArrayInputStream(RSA_PRIVATE_KEY.getBytes("UTF-8"));
+        OpenSSLKey key = OpenSSLKey.fromPrivateKeyPemInputStream(is);
+        OpenSSLRSAPrivateKey privateKey = (OpenSSLRSAPrivateKey)key.getPrivateKey();
+        assertEquals(RSA_MODULUS, privateKey.getModulus());
+        assertEquals(RSA_PRIVATE_EXPONENT, privateKey.getPrivateExponent());
+    }
+}
+
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLServerSocketImplTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLServerSocketImplTest.java
new file mode 100644
index 0000000..7cf7072
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLServerSocketImplTest.java
@@ -0,0 +1,129 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.LOCALHOST;
+import static com.android.org.conscrypt.TestUtils.getConscryptServerSocketFactory;
+import static com.android.org.conscrypt.TestUtils.getJdkSocketFactory;
+import static com.android.org.conscrypt.TestUtils.getProtocols;
+import static com.android.org.conscrypt.TestUtils.newTextMessage;
+import static com.android.org.conscrypt.TestUtils.pickUnusedPort;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class OpenSSLServerSocketImplTest {
+    private static final String CIPHER = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+    private static final int MESSAGE_SIZE = 4096;
+
+    /**
+     * Various factories for SSL server sockets.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum SocketType {
+        DEFAULT(getConscryptServerSocketFactory(false)),
+        ENGINE(getConscryptServerSocketFactory(true));
+
+        @SuppressWarnings("ImmutableEnumChecker")
+        private final SSLServerSocketFactory serverSocketFactory;
+
+        SocketType(SSLServerSocketFactory serverSocketFactory) {
+            this.serverSocketFactory = serverSocketFactory;
+        }
+
+        final SSLServerSocket newServerSocket(String cipher) {
+            try {
+                int port = pickUnusedPort();
+                SSLServerSocket sslSocket =
+                        (SSLServerSocket) serverSocketFactory.createServerSocket(port);
+                sslSocket.setEnabledProtocols(getProtocols());
+                sslSocket.setEnabledCipherSuites(new String[] {cipher});
+                return sslSocket;
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Parameters(name = "{0}")
+    public static Iterable<SocketType> data() {
+        // Android-changed: Temporarily (2017 Q2) disable ENGINE tests. http://b/37271061#comment9
+        // This experimental (unused by default) implementation is unstable and causing test
+        // failures on Android.
+        // return Arrays.asList(SocketType.DEFAULT, SocketType.ENGINE);
+        return Arrays.asList(SocketType.DEFAULT);
+    }
+
+    @Parameter public SocketType socketType;
+
+    private TestClient client;
+    private TestServer server;
+
+    @Before
+    public void setup() throws Exception {
+        // Create and start the server.
+        server = new TestServer(socketType.newServerSocket(CIPHER), MESSAGE_SIZE);
+        Future<?> connectedFuture = server.start();
+
+        // Create and start the client.
+        SSLSocketFactory socketFactory = getJdkSocketFactory();
+        SSLSocket socket = (SSLSocket) socketFactory.createSocket(LOCALHOST, server.port());
+        socket.setEnabledProtocols(getProtocols());
+        socket.setEnabledCipherSuites(new String[] {CIPHER});
+        client = new TestClient(socket);
+        client.start();
+
+        // Wait for the initial connection to complete.
+        connectedFuture.get(5, TimeUnit.SECONDS);
+    }
+
+    @After
+    public void teardown() throws Exception {
+        client.stop();
+        server.stop();
+    }
+
+    @Test
+    public void pingPong() throws IOException {
+        byte[] request = newTextMessage(MESSAGE_SIZE);
+        byte[] responseBuffer = new byte[MESSAGE_SIZE];
+        client.sendMessage(request);
+        client.flush();
+        int numBytes = client.readMessage(responseBuffer);
+        byte[] response = Arrays.copyOfRange(responseBuffer, 0, numBytes);
+        assertArrayEquals(request, response);
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLX509CertificateTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLX509CertificateTest.java
new file mode 100644
index 0000000..07439e0
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/OpenSSLX509CertificateTest.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2015 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.openTestFile;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import junit.framework.TestCase;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OpenSSLX509CertificateTest extends TestCase {
+    public void testSerialization_NoContextDeserialization() throws Exception {
+        // Set correct serialVersionUID
+        {
+            ObjectStreamClass clDesc = ObjectStreamClass.lookup(OpenSSLX509Certificate.class);
+            assertNotNull(clDesc);
+
+            // Set our fake class's serialization UID.
+            Field targetUID = ZpenSSLX509Certificate.class.getDeclaredField("serialVersionUID");
+            targetUID.setAccessible(true);
+
+            // Mark the field as non-final on JVM that need it.
+            try {
+                Field modifiersField = Field.class.getDeclaredField("modifiers");
+                modifiersField.setAccessible(true);
+                modifiersField.setInt(targetUID, targetUID.getModifiers() & ~Modifier.FINAL);
+            } catch (NoSuchFieldException ignored) {
+            }
+
+            targetUID.set(null, clDesc.getSerialVersionUID());
+        }
+
+        final byte[] impostorBytes;
+        // Serialization
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(new ZpenSSLX509Certificate(0xA5A5A5A5A5A5A5A5L));
+            oos.close();
+            impostorBytes = baos.toByteArray();
+        }
+
+        // Fix class name
+        {
+            boolean fixed = false;
+            for (int i = 0; i < impostorBytes.length - 4; i++) {
+                if (impostorBytes[i] == 'Z' && impostorBytes[i + 1] == 'p'
+                        && impostorBytes[i + 2] == 'e' && impostorBytes[i + 3] == 'n') {
+                    impostorBytes[i] = 'O';
+                    fixed = true;
+                    break;
+                }
+            }
+            assertTrue(fixed);
+        }
+
+        // Deserialization
+        {
+            ByteArrayInputStream bais = new ByteArrayInputStream(impostorBytes);
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            OpenSSLX509Certificate cert = (OpenSSLX509Certificate) ois.readObject();
+            ois.close();
+            assertEquals(0L, cert.getContext());
+        }
+    }
+
+    static final String CT_POISON_EXTENSION = "1.3.6.1.4.1.11129.2.4.3";
+
+    private OpenSSLX509Certificate loadTestCertificate(String name)
+            throws FileNotFoundException, ParsingException {
+        return OpenSSLX509Certificate.fromX509PemInputStream(openTestFile(name));
+    }
+
+    public void test_deletingCTPoisonExtension() throws Exception {
+        /* certPoisoned has an extra poison extension.
+         * With the extension, the certificates have different TBS.
+         * Without it, the certificates should have the same TBS.
+         */
+        OpenSSLX509Certificate cert = loadTestCertificate("cert.pem");
+        OpenSSLX509Certificate certPoisoned = loadTestCertificate("cert-ct-poisoned.pem");
+
+        assertFalse(Arrays.equals(
+                certPoisoned.getTBSCertificate(),
+                cert.getTBSCertificate()));
+
+        assertTrue(Arrays.equals(
+                certPoisoned.withDeletedExtension(CT_POISON_EXTENSION).getTBSCertificate(),
+                cert.getTBSCertificate()));
+    }
+
+    public void test_deletingExtensionMakesCopy() throws Exception {
+        /* Calling withDeletedExtension should not modify the original certificate, only make a copy.
+         * Make sure the extension is still present in the original object.
+         */
+        OpenSSLX509Certificate certPoisoned = loadTestCertificate("cert-ct-poisoned.pem");
+        assertTrue(certPoisoned.getCriticalExtensionOIDs().contains(CT_POISON_EXTENSION));
+
+        OpenSSLX509Certificate certWithoutExtension = certPoisoned.withDeletedExtension(CT_POISON_EXTENSION);
+
+        assertTrue(certPoisoned.getCriticalExtensionOIDs().contains(CT_POISON_EXTENSION));
+        assertFalse(certWithoutExtension.getCriticalExtensionOIDs().contains(CT_POISON_EXTENSION));
+    }
+
+    public void test_deletingMissingExtension() throws Exception {
+        /* withDeletedExtension should be safe to call on a certificate without the extension, and
+         * return an identical copy.
+         */
+        OpenSSLX509Certificate cert = loadTestCertificate("cert.pem");
+        assertFalse(cert.getCriticalExtensionOIDs().contains(CT_POISON_EXTENSION));
+
+        OpenSSLX509Certificate cert2 = cert.withDeletedExtension(CT_POISON_EXTENSION);
+        assertEquals(cert, cert2);
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/PlatformTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/PlatformTest.java
new file mode 100644
index 0000000..eddaa18
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/PlatformTest.java
@@ -0,0 +1,179 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.lang.reflect.Method;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLParameters;
+import org.junit.Assume;
+import org.junit.Test;
+
+/**
+ * Test for Platform
+ * @hide This class is not part of the Android public SDK API
+ */
+public class PlatformTest {
+    private static final Method SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD;
+    private static final Method SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD;
+
+    static {
+        Class<?> sslParameters = SSLParameters.class;
+        Method getApplicationProtocolsMethod;
+        Method setApplicationProtocolsMethod;
+        try {
+            getApplicationProtocolsMethod = sslParameters.getMethod("getApplicationProtocols");
+            setApplicationProtocolsMethod =
+                sslParameters.getMethod("setApplicationProtocols", String[].class);
+        } catch (NoSuchMethodException e) {
+            getApplicationProtocolsMethod = null;
+            setApplicationProtocolsMethod = null;
+        }
+
+        SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD = getApplicationProtocolsMethod;
+        SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD = setApplicationProtocolsMethod;
+    }
+
+    private static boolean isJavaVersion(int version) {
+        return Platform.javaVersion() >= version;
+    }
+
+    private static void assumeJava8() {
+        Assume.assumeTrue("Require Java 8: " + Platform.javaVersion(), isJavaVersion(8));
+    }
+
+    @Test
+    public void test_setSSLParameters_Socket() throws Exception {
+        assumeJava8();
+        Socket socket = new OpenSSLSocketFactoryImpl().createSocket();
+        SSLParametersImpl impl = SSLParametersImpl.getDefault();
+        SSLParameters params = new SSLParameters();
+        List<SNIServerName> names = new ArrayList<SNIServerName>();
+        names.add(new SNIHostName("some.host"));
+        params.setServerNames(names);
+        params.setUseCipherSuitesOrder(false);
+        params.setEndpointIdentificationAlgorithm("ABC");
+        String[] applicationProtocols = new String[] {"foo", "bar"};
+        if (isJavaVersion(9)) {
+            setApplicationProtocols(params, applicationProtocols);
+        }
+        Platform.setSSLParameters(params, impl, (AbstractConscryptSocket) socket);
+        assertEquals("some.host", ((AbstractConscryptSocket) socket).getHostname());
+        assertFalse(impl.getUseCipherSuitesOrder());
+        assertEquals("ABC", impl.getEndpointIdentificationAlgorithm());
+        if (isJavaVersion(9)) {
+            assertArrayEquals(applicationProtocols, impl.getApplicationProtocols());
+        }
+    }
+
+    @Test
+    public void test_getSSLParameters_Socket() throws Exception {
+        assumeJava8();
+        Socket socket = new OpenSSLSocketFactoryImpl().createSocket();
+        SSLParametersImpl impl = SSLParametersImpl.getDefault();
+        SSLParameters params = new SSLParameters();
+        impl.setUseCipherSuitesOrder(false);
+        impl.setEndpointIdentificationAlgorithm("ABC");
+        String[] applicationProtocols = new String[] {"foo", "bar"};
+        if (isJavaVersion(9)) {
+            impl.setApplicationProtocols(applicationProtocols);
+        }
+        ((AbstractConscryptSocket) socket).setHostname("some.host");
+        Platform.getSSLParameters(params, impl, (AbstractConscryptSocket) socket);
+        assertEquals("some.host", ((SNIHostName) params.getServerNames().get(0)).getAsciiName());
+        assertFalse(params.getUseCipherSuitesOrder());
+        assertEquals("ABC", params.getEndpointIdentificationAlgorithm());
+        if (isJavaVersion(9)) {
+            assertArrayEquals(applicationProtocols, getApplicationProtocols(params));
+        }
+    }
+
+    @Test
+    public void test_setSSLParameters_Engine() throws Exception {
+        assumeJava8();
+        SSLParametersImpl impl = SSLParametersImpl.getDefault();
+        SSLParameters params = new SSLParameters();
+        ConscryptEngine engine = new ConscryptEngine(impl);
+        List<SNIServerName> names = new ArrayList<SNIServerName>();
+        names.add(new SNIHostName("some.host"));
+        params.setServerNames(names);
+        params.setUseCipherSuitesOrder(false);
+        params.setEndpointIdentificationAlgorithm("ABC");
+        String[] applicationProtocols = new String[] {"foo", "bar"};
+        if (isJavaVersion(9)) {
+            setApplicationProtocols(params, applicationProtocols);
+        }
+        Platform.setSSLParameters(params, impl, engine);
+        assertEquals("some.host", engine.getHostname());
+        assertFalse(impl.getUseCipherSuitesOrder());
+        assertEquals("ABC", impl.getEndpointIdentificationAlgorithm());
+        if (isJavaVersion(9)) {
+            assertArrayEquals(applicationProtocols, impl.getApplicationProtocols());
+        }
+    }
+
+    @Test
+    public void test_getSSLParameters_Engine() throws Exception {
+        assumeJava8();
+        SSLParametersImpl impl = SSLParametersImpl.getDefault();
+        SSLParameters params = new SSLParameters();
+        ConscryptEngine engine = new ConscryptEngine(impl);
+        impl.setUseCipherSuitesOrder(false);
+        impl.setEndpointIdentificationAlgorithm("ABC");
+        engine.setHostname("some.host");
+        String[] applicationProtocols = new String[] {"foo", "bar"};
+        if (isJavaVersion(9)) {
+            impl.setApplicationProtocols(applicationProtocols);
+        }
+        Platform.getSSLParameters(params, impl, engine);
+        assertEquals("some.host", ((SNIHostName) params.getServerNames().get(0)).getAsciiName());
+        assertFalse(params.getUseCipherSuitesOrder());
+        assertEquals("ABC", params.getEndpointIdentificationAlgorithm());
+        if (isJavaVersion(9)) {
+            assertArrayEquals(applicationProtocols, getApplicationProtocols(params));
+        }
+    }
+
+    private static String[] getApplicationProtocols(SSLParameters params) {
+        if (SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD != null) {
+            try {
+                return (String[]) SSL_PARAMETERS_GET_APPLICATION_PROTOCOLS_METHOD.invoke(params);
+            } catch (Exception ignored) {
+                // TODO(nmittler): Should we throw here?
+            }
+        }
+        return EmptyArray.STRING;
+    }
+
+    private static void setApplicationProtocols(SSLParameters params, String[] protocols) {
+        if (SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD != null) {
+            try {
+                SSL_PARAMETERS_SET_APPLICATION_PROTOCOLS_METHOD.invoke(params, (Object) protocols);
+            } catch (Exception ignored) {
+                // TODO(nmittler): Should we throw here?
+            }
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/RenegotiationTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/RenegotiationTest.java
new file mode 100644
index 0000000..a6df39d
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/RenegotiationTest.java
@@ -0,0 +1,447 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.Status;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * This tests that server-initiated cipher renegotiation works properly with a Conscrypt client.
+ * BoringSSL does not support user-initiated renegotiation, so we use the JDK implementation for
+ * the server.
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(Parameterized.class)
+public class RenegotiationTest {
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocateDirect(0);
+    private static final String[] CIPHERS = TestUtils.getCommonCipherSuites();
+    private static final byte[] MESSAGE_BYTES = "Hello".getBytes(TestUtils.UTF_8);
+    private static final ByteBuffer MESSAGE_BUFFER =
+            ByteBuffer.wrap(MESSAGE_BYTES).asReadOnlyBuffer();
+    private static final int MESSAGE_LENGTH = MESSAGE_BYTES.length;
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public enum SocketType {
+        FILE_DESCRIPTOR {
+            @Override
+            Client newClient(int port) {
+                return new Client(false, port);
+            }
+        },
+        ENGINE {
+            @Override
+            Client newClient(int port) {
+                return new Client(true, port);
+            }
+        };
+
+        abstract Client newClient(int port);
+    }
+
+    @Parameters(name = "{0}")
+    public static Object[] data() {
+        return new Object[] {SocketType.FILE_DESCRIPTOR, SocketType.ENGINE};
+    }
+
+    @Parameter
+    public SocketType socketType;
+
+    private Client client;
+    private Server server;
+
+    @Before
+    public void setup() throws Exception {
+        server = new Server();
+        Future<?> connectedFuture = server.start();
+
+        client = socketType.newClient(server.port());
+        client.start();
+
+        // Wait for the initial connection to complete.
+        connectedFuture.get(5, TimeUnit.SECONDS);
+    }
+
+    @After
+    public void teardown() {
+        client.stop();
+        server.stop();
+    }
+
+    @Test
+    public void test() throws Exception {
+        client.socket.startHandshake();
+        String initialCipher = client.socket.getSession().getCipherSuite();
+
+        client.sendMessage();
+
+        Future<?> repliesFuture = client.readReplies();
+        server.await(5, TimeUnit.SECONDS);
+        repliesFuture.get(5, TimeUnit.SECONDS);
+
+        // Verify that the cipher has changed.
+        assertNotEquals(initialCipher, client.socket.getSession().getCipherSuite());
+    }
+
+    private static SSLContext newConscryptClientContext() {
+        SSLContext context = TestUtils.newContext(TestUtils.getConscryptProvider());
+        return TestUtils.initSslContext(context, TestKeyStore.getClient());
+    }
+
+    private static SSLContext newJdkServerContext() {
+        SSLContext context = TestUtils.newContext(TestUtils.getJdkProvider());
+        return TestUtils.initSslContext(context, TestKeyStore.getServer());
+    }
+
+    private static final class Client {
+        private final SSLSocket socket;
+        private ExecutorService executor;
+        private volatile boolean stopping;
+
+        Client(boolean useEngineSocket, int port) {
+            try {
+                SSLSocketFactory socketFactory = newConscryptClientContext().getSocketFactory();
+                Conscrypt.setUseEngineSocket(socketFactory, useEngineSocket);
+                socket = (SSLSocket) socketFactory.createSocket(
+                        TestUtils.getLoopbackAddress(), port);
+                socket.setEnabledCipherSuites(CIPHERS);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        void start() {
+            try {
+                executor = Executors.newSingleThreadExecutor();
+                socket.startHandshake();
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        }
+
+        void stop() {
+            try {
+                stopping = true;
+                socket.close();
+
+                if (executor != null) {
+                    executor.shutdown();
+                    executor.awaitTermination(5, TimeUnit.SECONDS);
+                    executor = null;
+                }
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Future<?> readReplies() {
+            return executor.submit(new Runnable() {
+                @Override
+                public void run() {
+                    readReply();
+                }
+            });
+        }
+
+        private void readReply() {
+            try {
+                byte[] buffer = new byte[MESSAGE_LENGTH];
+                int totalBytesRead = 0;
+                while (totalBytesRead < MESSAGE_LENGTH) {
+                    int remaining = MESSAGE_LENGTH - totalBytesRead;
+                    int bytesRead = socket.getInputStream().read(buffer, totalBytesRead, remaining);
+                    if (bytesRead == -1) {
+                        throw new EOFException();
+                    }
+                    totalBytesRead += bytesRead;
+                }
+
+                // Verify the reply is correct.
+                assertEquals(MESSAGE_LENGTH, totalBytesRead);
+                assertArrayEquals(MESSAGE_BYTES, buffer);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        void sendMessage() throws IOException {
+            try {
+                socket.getOutputStream().write(MESSAGE_BYTES);
+                socket.getOutputStream().flush();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private static final class Server {
+        private final ServerSocketChannel serverChannel;
+        private final SSLEngine engine;
+        private final ByteBuffer inboundPacketBuffer;
+        private final ByteBuffer inboundAppBuffer;
+        private final ByteBuffer outboundPacketBuffer;
+        private final Set<String> ciphers = new LinkedHashSet<String>(Arrays.asList(CIPHERS));
+        private SocketChannel channel;
+        private ExecutorService executor;
+        private volatile boolean stopping;
+        private volatile Future<?> echoFuture;
+
+        Server() throws IOException {
+            serverChannel = ServerSocketChannel.open();
+            serverChannel.socket().bind(new InetSocketAddress(TestUtils.getLoopbackAddress(), 0));
+            engine = newJdkServerContext().createSSLEngine();
+            engine.setEnabledCipherSuites(CIPHERS);
+            engine.setUseClientMode(false);
+
+            inboundPacketBuffer =
+                    ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize());
+            inboundAppBuffer =
+                    ByteBuffer.allocateDirect(engine.getSession().getApplicationBufferSize());
+            outboundPacketBuffer =
+                    ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize());
+        }
+
+        Future<?> start() throws IOException {
+            executor = Executors.newSingleThreadExecutor();
+            return executor.submit(new AcceptTask());
+        }
+
+        void await(long timeout, TimeUnit unit)
+                throws InterruptedException, ExecutionException, TimeoutException {
+            echoFuture.get(timeout, unit);
+        }
+
+        void stop() {
+            try {
+                stopping = true;
+
+                if (channel != null) {
+                    channel.close();
+                    channel = null;
+                }
+
+                serverChannel.close();
+
+                if (executor != null) {
+                    executor.shutdown();
+                    executor.awaitTermination(5, TimeUnit.SECONDS);
+                    executor = null;
+                }
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        int port() {
+            return serverChannel.socket().getLocalPort();
+        }
+
+        private final class AcceptTask implements Runnable {
+            @Override
+            public void run() {
+                try {
+                    if (stopping) {
+                        return;
+                    }
+                    channel = serverChannel.accept();
+                    channel.configureBlocking(false);
+
+                    doHandshake();
+
+                    if (stopping) {
+                        return;
+                    }
+                    echoFuture = executor.submit(new EchoTask());
+                } catch (Throwable e) {
+                    e.printStackTrace();
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        private final class EchoTask implements Runnable {
+            @Override
+            public void run() {
+                try {
+                    readMessage();
+                    renegotiate();
+                    reply();
+                } catch (Throwable e) {
+                    e.printStackTrace();
+                    throw new RuntimeException(e);
+                }
+            }
+
+            private void renegotiate() throws Exception {
+                // Remove the current cipher from the set and renegotiate to force a new
+                // cipher to be selected.
+                String currentCipher = engine.getSession().getCipherSuite();
+                ciphers.remove(currentCipher);
+                engine.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));
+                doHandshake();
+            }
+
+            private void reply() throws IOException {
+                SSLEngineResult result = wrap(newMessage());
+                if (result.getStatus() != Status.OK) {
+                    throw new RuntimeException("Wrap failed. Status: " + result.getStatus());
+                }
+            }
+
+            private ByteBuffer newMessage() {
+                return MESSAGE_BUFFER.duplicate();
+            }
+
+            private void readMessage() throws IOException {
+                int totalProduced = 0;
+                while (!stopping) {
+                    SSLEngineResult result = unwrap();
+                    if (result.getStatus() != Status.OK) {
+                        throw new RuntimeException("Failed reading message: " + result);
+                    }
+                    totalProduced += result.bytesProduced();
+                    if (totalProduced == MESSAGE_LENGTH) {
+                        return;
+                    }
+                }
+            }
+        }
+
+        private SSLEngineResult wrap(ByteBuffer src) throws IOException {
+            outboundPacketBuffer.clear();
+
+            // Check if the engine has bytes to wrap.
+            SSLEngineResult result = engine.wrap(src, outboundPacketBuffer);
+
+            // Write any wrapped bytes to the socket.
+            outboundPacketBuffer.flip();
+
+            do {
+                channel.write(outboundPacketBuffer);
+            } while (outboundPacketBuffer.hasRemaining());
+
+            return result;
+        }
+
+        private SSLEngineResult unwrap() throws IOException {
+            // Unwrap any available bytes from the socket.
+            SSLEngineResult result = null;
+            boolean done = false;
+            while (!done) {
+                if (channel.read(inboundPacketBuffer) == -1) {
+                    throw new EOFException();
+                }
+                // Just clear the app buffer - we don't really use it.
+                inboundAppBuffer.clear();
+                inboundPacketBuffer.flip();
+                result = engine.unwrap(inboundPacketBuffer, inboundAppBuffer);
+                switch (result.getStatus()) {
+                    case BUFFER_UNDERFLOW:
+                        // Continue reading from the socket in a moment.
+                        try {
+                            Thread.sleep(10);
+                        } catch (InterruptedException e) {
+                            throw new RuntimeException(e);
+                        }
+                        break;
+                    case OK:
+                        done = true;
+                        break;
+                    default: { throw new RuntimeException("Unexpected unwrap result: " + result); }
+                }
+
+                // Compact for the next socket read.
+                inboundPacketBuffer.compact();
+            }
+            return result;
+        }
+
+        private void doHandshake() throws IOException {
+            engine.beginHandshake();
+
+            boolean done = false;
+            while (!done) {
+                switch (engine.getHandshakeStatus()) {
+                    case NEED_WRAP: {
+                        wrap(EMPTY_BUFFER);
+                        break;
+                    }
+                    case NEED_UNWRAP: {
+                        unwrap();
+                        break;
+                    }
+                    case NEED_TASK: {
+                        runDelegatedTasks();
+                        break;
+                    }
+                    default: {
+                        done = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        private void runDelegatedTasks() {
+            for (;;) {
+                Runnable task = engine.getDelegatedTask();
+                if (task == null) {
+                    break;
+                }
+                task.run();
+            }
+        }
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/SSLUtilsTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/SSLUtilsTest.java
new file mode 100644
index 0000000..8366738
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/SSLUtilsTest.java
@@ -0,0 +1,226 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import static com.android.org.conscrypt.TestUtils.UTF_8;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class SSLUtilsTest {
+    private static final byte[] VALID_CHARACTERS =
+            "0123456789abcdefghijklmnopqrstuvwxyz".getBytes(UTF_8);
+
+    @Test
+    public void noProtocolsShouldSucceed() {
+        byte[] expected = new byte[0];
+        byte[] actual = SSLUtils.encodeProtocols(EmptyArray.STRING);
+        assertArrayEquals(expected, actual);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void emptyProtocolShouldThrow() {
+        SSLUtils.encodeProtocols(new String[] {""});
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void longProtocolShouldThrow() {
+        SSLUtils.encodeProtocols(new String[] {new String(newValidProtocol(256), UTF_8)});
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void protocolWithInvalidCharacterShouldThrow() {
+        SSLUtils.encodeProtocols(new String[] {"This is a bad character: €"});
+    }
+
+    @Test
+    public void encodeProtocolsShouldSucceed() {
+        byte[][] protocols = new byte[][]{
+                "protocol-1".getBytes(UTF_8),
+                "protocol-2".getBytes(UTF_8),
+                "protocol-3".getBytes(UTF_8),
+        };
+        byte[] expected = getExpectedEncodedBytes(protocols);
+        byte[] actual = SSLUtils.encodeProtocols(toStrings(protocols));
+        assertArrayEquals(expected, actual);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void decodeNullProtocolsShouldThrow() {
+        SSLUtils.decodeProtocols(null);
+    }
+
+    @Test
+    public void decodeEmptyProtocolsShouldSucceed() {
+        assertArrayEquals(EmptyArray.STRING, SSLUtils.decodeProtocols(EmptyArray.BYTE));
+    }
+
+    @Test
+    public void decodeProtocolsShouldSucceed() {
+        byte[][] protocols = new byte[][]{
+            "protocol-1".getBytes(UTF_8),
+            "protocol-2".getBytes(UTF_8),
+            "protocol-3".getBytes(UTF_8),
+        };
+        byte[] encoded = getExpectedEncodedBytes(protocols);
+        String[] strings = SSLUtils.decodeProtocols(encoded);
+        assertArrayEquals(toStrings(protocols), strings);
+    }
+
+    @Test
+    public void testGetClientKeyType() throws Exception {
+        // See http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml
+        byte b = Byte.MIN_VALUE;
+        do {
+            String byteString = Byte.toString(b);
+            String keyType = SSLUtils.getClientKeyType(b);
+            switch (b) {
+                case 1:
+                    assertEquals(byteString, "RSA", keyType);
+                    break;
+                case 64:
+                    assertEquals(byteString, "EC", keyType);
+                    break;
+                default:
+                    assertNull(byteString, keyType);
+            }
+            b++;
+        } while (b != Byte.MIN_VALUE);
+    }
+
+    @Test
+    public void testGetSupportedClientKeyTypes_onlyCertTypes() throws Exception {
+        // Create an array with all possible values. Also, duplicate all values.
+        byte[] allClientCertificateTypes = new byte[512];
+        for (int i = 0; i < allClientCertificateTypes.length; i++) {
+            allClientCertificateTypes[i] = (byte) i;
+        }
+        assertEquals(new HashSet<String>(Arrays.asList("RSA", "EC")),
+                SSLUtils.getSupportedClientKeyTypes(allClientCertificateTypes, new int[0]));
+    }
+
+    @Test
+    public void testGetSupportedClientKeyTypes_onlySignatureAlgs() {
+        // Create an array with lots of values in the supported range
+        int[] allSignatureAlgTypes = new int[7 * 7];
+        int i = 0;
+        for (int upper = 0x02; upper < 0x09; upper++) {
+            for (int lower = 0x01; lower < 0x08; lower++) {
+                allSignatureAlgTypes[i++] = (upper << 8) | lower;
+            }
+        }
+        assertEquals(new HashSet<String>(Arrays.asList("RSA", "EC")),
+                SSLUtils.getSupportedClientKeyTypes(new byte[0], allSignatureAlgTypes));
+    }
+
+    @Test
+    public void testGetSupportedClientKeyTypes_intersection() {
+        assertEquals(new HashSet<String>(Arrays.asList("EC")),
+                SSLUtils.getSupportedClientKeyTypes(
+                        new byte[] { NativeConstants.TLS_CT_RSA_SIGN,
+                                NativeConstants.TLS_CT_ECDSA_SIGN },
+                        new int[] { NativeConstants.SSL_SIGN_ECDSA_SECP256R1_SHA256,
+                                NativeConstants.SSL_SIGN_ECDSA_SECP384R1_SHA384,
+                                NativeConstants.SSL_SIGN_ECDSA_SECP521R1_SHA512 }));
+    }
+
+    @Test
+    public void testGetSupportedClientKeyTypes_intersection_empty() {
+        assertEquals(new HashSet<String>(),
+                SSLUtils.getSupportedClientKeyTypes(
+                        new byte[] { NativeConstants.TLS_CT_RSA_SIGN },
+                        new int[] { NativeConstants.SSL_SIGN_ECDSA_SECP256R1_SHA256,
+                                NativeConstants.SSL_SIGN_ECDSA_SECP384R1_SHA384,
+                                NativeConstants.SSL_SIGN_ECDSA_SECP521R1_SHA512 }));
+    }
+
+    @Test
+    public void testGetSupportedClientKeyTypes_ordered() {
+        List<String> keyTypes = new ArrayList<String>(SSLUtils.getSupportedClientKeyTypes(
+                new byte[0],
+                new int[] { NativeConstants.SSL_SIGN_RSA_PKCS1_SHA1,
+                        NativeConstants.SSL_SIGN_ECDSA_SECP256R1_SHA256 }));
+        assertEquals(Arrays.asList("RSA", "EC"), keyTypes);
+
+        keyTypes = new ArrayList<String>(SSLUtils.getSupportedClientKeyTypes(
+                new byte[0],
+                new int[] { NativeConstants.SSL_SIGN_ECDSA_SECP256R1_SHA256,
+                        NativeConstants.SSL_SIGN_RSA_PKCS1_SHA1 }));
+        assertEquals(Arrays.asList("EC", "RSA"), keyTypes);
+
+        keyTypes = new ArrayList<String>(SSLUtils.getSupportedClientKeyTypes(
+                new byte[0],
+                new int[] { NativeConstants.SSL_SIGN_RSA_PKCS1_SHA512,
+                        NativeConstants.SSL_SIGN_ECDSA_SECP256R1_SHA256,
+                        NativeConstants.SSL_SIGN_RSA_PKCS1_SHA1 }));
+        assertEquals(Arrays.asList("RSA", "EC"), keyTypes);
+
+        keyTypes = new ArrayList<String>(SSLUtils.getSupportedClientKeyTypes(
+                new byte[0],
+                new int[] { NativeConstants.SSL_SIGN_ECDSA_SECP256R1_SHA256,
+                        NativeConstants.SSL_SIGN_RSA_PKCS1_SHA1,
+                        NativeConstants.SSL_SIGN_ECDSA_SECP521R1_SHA512 }));
+        assertEquals(Arrays.asList("EC", "RSA"), keyTypes);
+    }
+
+    private static String[] toStrings(byte[][] protocols) {
+        int numProtocols = protocols.length;
+        String[] out = new String[numProtocols];
+        for(int i = 0; i < numProtocols; ++i) {
+            out[i] = new String(protocols[i], UTF_8);
+        }
+        return out;
+    }
+
+    private static byte[] getExpectedEncodedBytes(byte[][] protocols) {
+        int numProtocols = protocols.length;
+        int encodedLength = numProtocols;
+        for (byte[] protocol : protocols) {
+            encodedLength += protocol.length;
+        }
+        byte[] encoded = new byte[encodedLength];
+        for(int encodedIndex = 0, i = 0; i < numProtocols; ++i) {
+            byte[] protocol = protocols[i];
+            encoded[encodedIndex++] = (byte) protocol.length;
+            System.arraycopy(protocol, 0, encoded, encodedIndex, protocol.length);
+            encodedIndex += protocol.length;
+        }
+        return encoded;
+    }
+
+    private static byte[] newValidProtocol(int length) {
+        byte[] chars = new byte[length];
+        for (int i = 0; i < length; ++i) {
+            int charIndex = i % VALID_CHARACTERS.length;
+            chars[i] = VALID_CHARACTERS[charIndex];
+        }
+        return chars;
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ServerSessionContextTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ServerSessionContextTest.java
new file mode 100644
index 0000000..c5986cc
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ServerSessionContextTest.java
@@ -0,0 +1,50 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.org.conscrypt;
+
+import java.util.Enumeration;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class ServerSessionContextTest extends AbstractSessionContextTest<ServerSessionContext> {
+
+    @Override
+    ServerSessionContext newContext() {
+        return new ServerSessionContext();
+    }
+
+    @Override
+    NativeSslSession getCachedSession(ServerSessionContext context, NativeSslSession s) {
+        return context.getSessionFromCache(s.getId());
+    }
+
+    @Override
+    int size(ServerSessionContext context) {
+        int count = 0;
+        Enumeration<byte[]> ids = context.getIds();
+        while (ids.hasMoreElements()) {
+            ids.nextElement();
+            count++;
+        }
+        return count;
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/TestSessionBuilder.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/TestSessionBuilder.java
new file mode 100644
index 0000000..3962c81
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/TestSessionBuilder.java
@@ -0,0 +1,171 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2016 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TestSessionBuilder {
+    private int type;
+
+    private boolean sessionDataSet;
+    private byte[] sessionData;
+    private int sessionDataLength;
+
+    private boolean certificatesSet;
+    private ArrayList<byte[]> certificates = new ArrayList<byte[]>();
+    private int certificatesLength;
+    private ArrayList<Integer> certificateLengths = new ArrayList<Integer>();
+
+    private boolean ocspDataSet;
+    private ArrayList<byte[]> ocspDatas = new ArrayList<byte[]>();
+    private int ocspDatasLength;
+    private ArrayList<Integer> ocspDataLengths = new ArrayList<Integer>();
+
+    private boolean tlsSctDataSet;
+    private byte[] tlsSctData;
+    private int tlsSctDataLength;
+
+    public TestSessionBuilder setType(int type) {
+        this.type = type;
+        return this;
+    }
+
+    public TestSessionBuilder setSessionData(byte[] sessionData) {
+        sessionDataSet = true;
+        this.sessionData = sessionData;
+        sessionDataLength = sessionData.length;
+        return this;
+    }
+
+    public TestSessionBuilder setSessionDataLength(int sessionDataLength) {
+        assertTrue("call setSessionData first", sessionDataSet);
+        this.sessionDataLength = sessionDataLength;
+        return this;
+    }
+
+    public TestSessionBuilder addCertificate(byte[] certificate) {
+        certificatesSet = true;
+        certificates.add(certificate);
+        certificateLengths.add(certificate.length);
+        certificatesLength = certificates.size();
+        return this;
+    }
+
+    public TestSessionBuilder setCertificatesLength(int certificatesLength) {
+        assertTrue("call addCertificate first", certificatesSet);
+        this.certificatesLength = certificatesLength;
+        return this;
+    }
+
+    public TestSessionBuilder setCertificateLength(int certIndex, int certLength) {
+        assertTrue("call addCertificate first", certificatesSet);
+        certificateLengths.set(certIndex, certLength);
+        return this;
+    }
+
+    public TestSessionBuilder setOcspDataEmpty() {
+        ocspDataSet = true;
+        return this;
+    }
+
+    public TestSessionBuilder addOcspData(byte[] ocspData) {
+        ocspDataSet = true;
+        ocspDatas.add(ocspData);
+        ocspDataLengths.add(ocspData.length);
+        ocspDatasLength = ocspDatas.size();
+        return this;
+    }
+
+    public TestSessionBuilder setOcspDatasLength(int ocspDatasLength) {
+        assertTrue("Call addOcspData before setting length", ocspDataSet);
+        this.ocspDatasLength = ocspDatasLength;
+        return this;
+    }
+
+    public TestSessionBuilder setOcspDataLength(int ocspDataIndex, int ocspDataLength) {
+        assertTrue("Call addOcspData before setting length", ocspDataSet);
+        this.ocspDataLengths.set(ocspDataIndex, ocspDataLength);
+        return this;
+    }
+
+    public TestSessionBuilder setTlsSctData(byte[] tlsSctData) {
+        tlsSctDataSet = true;
+        this.tlsSctData = tlsSctData.clone();
+        tlsSctDataLength = tlsSctData.length;
+        return this;
+    }
+
+    public TestSessionBuilder setTlsSctDataLength(int tlsSctDataLength) {
+        assertTrue("Call setTlsSctData before setting length", tlsSctDataSet);
+        this.tlsSctDataLength = tlsSctDataLength;
+        return this;
+    }
+
+    public TestSessionBuilder setTlsSctDataEmpty() {
+        tlsSctDataSet = true;
+        return this;
+    }
+
+    public byte[] build() {
+        assertTrue("Must set session data", sessionDataSet);
+        assertTrue("Must call addCertificate at least once", certificatesSet);
+
+        ByteBuffer buf = ByteBuffer.allocate(4096);
+        buf.putInt(type);
+
+        buf.putInt(sessionDataLength);
+        buf.put(sessionData);
+
+        buf.putInt(certificatesLength);
+        for (int i = 0; i < certificates.size(); i++) {
+            buf.putInt(certificateLengths.get(i));
+            buf.put(certificates.get(i));
+        }
+
+        if (ocspDataSet) {
+            buf.putInt(ocspDatasLength);
+            for (int i = 0; i < ocspDatas.size(); i++) {
+                buf.putInt(ocspDataLengths.get(i));
+                buf.put(ocspDatas.get(i));
+            }
+
+            if (tlsSctDataSet) {
+                if (tlsSctData == null) {
+                    buf.putInt(0);
+                } else {
+                    buf.putInt(tlsSctDataLength);
+                    buf.put(tlsSctData);
+                }
+            }
+        } else {
+            assertFalse("If ocspData is not set, then tlsSctData must not be set", tlsSctDataSet);
+        }
+
+        buf.flip();
+        byte[] output = new byte[buf.remaining()];
+        buf.get(output);
+        return output;
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/TestSessionBuilderTest.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/TestSessionBuilderTest.java
new file mode 100644
index 0000000..624110f
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/TestSessionBuilderTest.java
@@ -0,0 +1,111 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2016 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TestSessionBuilderTest {
+    @Test
+    public void buildsValidBasicSession() {
+        assertArrayEquals(new byte[] {0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00,
+                                  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33},
+                new TestSessionBuilder()
+                        .setType(0x11)
+                        .setSessionData(new byte[] {0x22})
+                        .addCertificate(new byte[] {0x33})
+                        .build());
+    }
+
+    @Test
+    public void buildsValidOcspSession() {
+        assertArrayEquals(
+                new byte[] {
+                        0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00,
+                        0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                        0x00, 0x01, 0x44,
+                },
+                new TestSessionBuilder()
+                        .setType(0x11)
+                        .setSessionData(new byte[] {0x22})
+                        .addCertificate(new byte[] {0x33})
+                        .addOcspData(new byte[] {0x44})
+                        .build());
+    }
+
+    @Test
+    public void buildsValidOcspAndTlsSctSession() {
+        assertArrayEquals(
+                new byte[] {
+                        0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00,
+                        0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                        0x00, 0x01, 0x44, 0x00, 0x00, 0x00, 0x01, 0x55,
+                },
+                new TestSessionBuilder()
+                        .setType(0x11)
+                        .setSessionData(new byte[] {0x22})
+                        .addCertificate(new byte[] {0x33})
+                        .addOcspData(new byte[] {0x44})
+                        .setTlsSctData(new byte[] {0x55})
+                        .build());
+    }
+
+    @Test
+    public void buildsValidButEmptyOcspAndTlsSctSession() {
+        assertArrayEquals(
+                new byte[] {
+                        0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00,
+                        0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                        0x00, 0x00,
+                },
+                new TestSessionBuilder()
+                        .setType(0x11)
+                        .setSessionData(new byte[] {0x22})
+                        .addCertificate(new byte[] {0x33})
+                        .setOcspDataEmpty()
+                        .setTlsSctDataEmpty()
+                        .build());
+    }
+
+    @Test
+    public void buildsInvalidOcspAndTlsSctSession() {
+        assertArrayEquals(
+                new byte[] {
+                        0x00, 0x00, 0x00, 0x11, 0x00, 0x33, 0x22, 0x11, 0x22, 0x12, 0x11, 0x22,
+                        0x34, 0x10, 0x20, 0x30, 0x40, 0x33, 0x38, 0x48, 0x18, 0x28, 0x13, 0x24,
+                        0x57, 0x68, 0x44, (byte) 0x99, (byte) 0x88, 0x77, 0x66, 0x55,
+                },
+                new TestSessionBuilder()
+                        .setType(0x11)
+                        .setSessionData(new byte[] {0x22})
+                        .setSessionDataLength(0x332211)
+                        .addCertificate(new byte[] {0x33})
+                        .setCertificatesLength(0x12112234)
+                        .setCertificateLength(0, 0x10203040)
+                        .addOcspData(new byte[] {0x44})
+                        .setOcspDatasLength(0x38481828)
+                        .setOcspDataLength(0, 0x13245768)
+                        .setTlsSctData(new byte[] {0x55})
+                        .setTlsSctDataLength(0x99887766)
+                        .build());
+    }
+}
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ZpenSSLX509Certificate.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ZpenSSLX509Certificate.java
new file mode 100644
index 0000000..256f4a4
--- /dev/null
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ZpenSSLX509Certificate.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2015 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 com.android.org.conscrypt;
+
+import java.io.Serializable;
+
+/**
+ * This is a fake class to test de-serialization with malicious payloads.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ZpenSSLX509Certificate implements Serializable {
+    /** This will be set via reflection in the test. */
+    private static final long serialVersionUID = 0L;
+
+    public final long mContext;
+
+    ZpenSSLX509Certificate(long ctx) {
+        mContext = ctx;
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlacklistImpl.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlacklistImpl.java
new file mode 100644
index 0000000..e2c0773
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/CertBlacklistImpl.java
@@ -0,0 +1,266 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.org.conscrypt;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class CertBlacklistImpl implements CertBlacklist {
+    private static final Logger logger = Logger.getLogger(CertBlacklistImpl.class.getName());
+
+    private final Set<BigInteger> serialBlacklist;
+    private final Set<byte[]> pubkeyBlacklist;
+
+    /**
+     * public for testing only.
+     */
+    public CertBlacklistImpl(Set<BigInteger> serialBlacklist, Set<byte[]> pubkeyBlacklist) {
+        this.serialBlacklist = serialBlacklist;
+        this.pubkeyBlacklist = pubkeyBlacklist;
+    }
+
+    public static CertBlacklist getDefault() {
+        String androidData = System.getenv("ANDROID_DATA");
+        String blacklistRoot = androidData + "/misc/keychain/";
+        String defaultPubkeyBlacklistPath = blacklistRoot + "pubkey_blacklist.txt";
+        String defaultSerialBlacklistPath = blacklistRoot + "serial_blacklist.txt";
+
+        Set<byte[]> pubkeyBlacklist = readPublicKeyBlackList(defaultPubkeyBlacklistPath);
+        Set<BigInteger> serialBlacklist = readSerialBlackList(defaultSerialBlacklistPath);
+        return new CertBlacklistImpl(serialBlacklist, pubkeyBlacklist);
+    }
+
+    private static boolean isHex(String value) {
+        try {
+            new BigInteger(value, 16);
+            return true;
+        } catch (NumberFormatException e) {
+            logger.log(Level.WARNING, "Could not parse hex value " + value, e);
+            return false;
+        }
+    }
+
+    private static boolean isPubkeyHash(String value) {
+        if (value.length() != 40) {
+            logger.log(Level.WARNING, "Invalid pubkey hash length: " + value.length());
+            return false;
+        }
+        return isHex(value);
+    }
+
+    private static String readBlacklist(String path) {
+        try {
+            return readFileAsString(path);
+        } catch (FileNotFoundException ignored) {
+        } catch (IOException e) {
+            logger.log(Level.WARNING, "Could not read blacklist", e);
+        }
+        return "";
+    }
+
+    // From IoUtils.readFileAsString
+    private static String readFileAsString(String path) throws IOException {
+        return readFileAsBytes(path).toString("UTF-8");
+    }
+
+    // Based on IoUtils.readFileAsBytes
+    private static ByteArrayOutputStream readFileAsBytes(String path) throws IOException {
+        RandomAccessFile f = null;
+        try {
+            f = new RandomAccessFile(path, "r");
+            ByteArrayOutputStream bytes = new ByteArrayOutputStream((int) f.length());
+            byte[] buffer = new byte[8192];
+            while (true) {
+                int byteCount = f.read(buffer);
+                if (byteCount == -1) {
+                    return bytes;
+                }
+                bytes.write(buffer, 0, byteCount);
+            }
+        } finally {
+            closeQuietly(f);
+        }
+    }
+
+    // Base on IoUtils.closeQuietly
+    private static void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    private static Set<BigInteger> readSerialBlackList(String path) {
+
+        /* Start out with a base set of known bad values.
+         *
+         * WARNING: Do not add short serials to this list!
+         *
+         * Since this currently doesn't compare the serial + issuer, you
+         * should only add serials that have enough entropy here. Short
+         * serials may inadvertently match a certificate that was issued
+         * not in compliance with the Baseline Requirements.
+         */
+        Set<BigInteger> bl = new HashSet<BigInteger>(Arrays.asList(
+            // From http://src.chromium.org/viewvc/chrome/trunk/src/net/base/x509_certificate.cc?revision=78748&view=markup
+            // Not a real certificate. For testing only.
+            new BigInteger("077a59bcd53459601ca6907267a6dd1c", 16),
+            new BigInteger("047ecbe9fca55f7bd09eae36e10cae1e", 16),
+            new BigInteger("d8f35f4eb7872b2dab0692e315382fb0", 16),
+            new BigInteger("b0b7133ed096f9b56fae91c874bd3ac0", 16),
+            new BigInteger("9239d5348f40d1695a745470e1f23f43", 16),
+            new BigInteger("e9028b9578e415dc1a710a2b88154447", 16),
+            new BigInteger("d7558fdaf5f1105bb213282b707729a3", 16),
+            new BigInteger("f5c86af36162f13a64f54f6dc9587c06", 16),
+            new BigInteger("392a434f0e07df1f8aa305de34e0c229", 16),
+            new BigInteger("3e75ced46b693021218830ae86a82a71", 16)
+        ));
+
+        // attempt to augment it with values taken from gservices
+        String serialBlacklist = readBlacklist(path);
+        if (!serialBlacklist.equals("")) {
+            for(String value : serialBlacklist.split(",")) {
+                try {
+                    bl.add(new BigInteger(value, 16));
+                } catch (NumberFormatException e) {
+                    logger.log(Level.WARNING, "Tried to blacklist invalid serial number " + value, e);
+                }
+            }
+        }
+
+        // whether that succeeds or fails, send it on its merry way
+        return Collections.unmodifiableSet(bl);
+    }
+
+    private static Set<byte[]> readPublicKeyBlackList(String path) {
+
+        // start out with a base set of known bad values
+        Set<byte[]> bl = new HashSet<byte[]>(Arrays.asList(
+            // Blacklist test cert for CTS. The cert and key can be found in
+            // src/test/resources/blacklist_test_ca.pem and
+            // src/test/resources/blacklist_test_ca_key.pem.
+            "bae78e6bed65a2bf60ddedde7fd91e825865e93d".getBytes(UTF_8),
+            // From http://src.chromium.org/viewvc/chrome/branches/782/src/net/base/x509_certificate.cc?r1=98750&r2=98749&pathrev=98750
+            // C=NL, O=DigiNotar, CN=DigiNotar Root CA/emailAddress=info@diginotar.nl
+            "410f36363258f30b347d12ce4863e433437806a8".getBytes(UTF_8),
+            // Subject: CN=DigiNotar Cyber CA
+            // Issuer: CN=GTE CyberTrust Global Root
+            "ba3e7bd38cd7e1e6b9cd4c219962e59d7a2f4e37".getBytes(UTF_8),
+            // Subject: CN=DigiNotar Services 1024 CA
+            // Issuer: CN=Entrust.net
+            "e23b8d105f87710a68d9248050ebefc627be4ca6".getBytes(UTF_8),
+            // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2
+            // Issuer: CN=Staat der Nederlanden Organisatie CA - G2
+            "7b2e16bc39bcd72b456e9f055d1de615b74945db".getBytes(UTF_8),
+            // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven
+            // Issuer: CN=Staat der Nederlanden Overheid CA
+            "e8f91200c65cee16e039b9f883841661635f81c5".getBytes(UTF_8),
+            // From http://src.chromium.org/viewvc/chrome?view=rev&revision=108479
+            // Subject: O=Digicert Sdn. Bhd.
+            // Issuer: CN=GTE CyberTrust Global Root
+            "0129bcd5b448ae8d2496d1c3e19723919088e152".getBytes(UTF_8),
+            // Subject: CN=e-islem.kktcmerkezbankasi.org/emailAddress=ileti@kktcmerkezbankasi.org
+            // Issuer: CN=T\xC3\x9CRKTRUST Elektronik Sunucu Sertifikas\xC4\xB1 Hizmetleri
+            "5f3ab33d55007054bc5e3e5553cd8d8465d77c61".getBytes(UTF_8),
+            // Subject: CN=*.EGO.GOV.TR 93
+            // Issuer: CN=T\xC3\x9CRKTRUST Elektronik Sunucu Sertifikas\xC4\xB1 Hizmetleri
+            "783333c9687df63377efceddd82efa9101913e8e".getBytes(UTF_8),
+            // Subject: Subject: C=FR, O=DG Tr\xC3\xA9sor, CN=AC DG Tr\xC3\xA9sor SSL
+            // Issuer: C=FR, O=DGTPE, CN=AC DGTPE Signature Authentification
+            "3ecf4bbbe46096d514bb539bb913d77aa4ef31bf".getBytes(UTF_8)
+        ));
+
+        // attempt to augment it with values taken from gservices
+        String pubkeyBlacklist = readBlacklist(path);
+        if (!pubkeyBlacklist.equals("")) {
+            for (String value : pubkeyBlacklist.split(",")) {
+                value = value.trim();
+                if (isPubkeyHash(value)) {
+                    bl.add(value.getBytes(UTF_8));
+                } else {
+                    logger.log(Level.WARNING, "Tried to blacklist invalid pubkey " + value);
+                }
+            }
+        }
+
+        return bl;
+    }
+
+    @Override
+    public boolean isPublicKeyBlackListed(PublicKey publicKey) {
+        byte[] encoded = publicKey.getEncoded();
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("SHA1");
+        } catch (GeneralSecurityException e) {
+            logger.log(Level.SEVERE, "Unable to get SHA1 MessageDigest", e);
+            return false;
+        }
+        byte[] out = toHex(md.digest(encoded));
+        for (byte[] blacklisted : pubkeyBlacklist) {
+            if (Arrays.equals(blacklisted, out)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static final byte[] HEX_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3',
+        (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a',
+        (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'};
+
+    private static byte[] toHex(byte[] in) {
+        byte[] out = new byte[in.length * 2];
+        int outIndex = 0;
+        for (int i = 0; i < in.length; i++) {
+            int value = in[i] & 0xff;
+            out[outIndex++] = HEX_TABLE[value >> 4];
+            out[outIndex++] = HEX_TABLE[value & 0xf];
+        }
+        return out;
+    }
+
+    @Override
+    public boolean isSerialNumberBlackListed(BigInteger serial) {
+        return serialBlacklist.contains(serial);
+    }
+
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/Hex.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/Hex.java
new file mode 100644
index 0000000..cadbf44
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/Hex.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2013 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 com.android.org.conscrypt;
+
+/**
+ * Helper class for dealing with hexadecimal strings.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+// public for testing by TrustedCertificateStoreTest
+// TODO(nathanmittler): Move to InternalUtil?
+public final class Hex {
+    private Hex() {}
+
+    private final static char[] DIGITS = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+    public static String bytesToHexString(byte[] bytes) {
+        char[] buf = new char[bytes.length * 2];
+        int c = 0;
+        for (byte b : bytes) {
+            buf[c++] = DIGITS[(b >> 4) & 0xf];
+            buf[c++] = DIGITS[b & 0xf];
+        }
+        return new String(buf);
+    }
+
+    public static String intToHexString(int i, int minWidth) {
+        int bufLen = 8;  // Max number of hex digits in an int
+        char[] buf = new char[bufLen];
+        int cursor = bufLen;
+
+        do {
+            buf[--cursor] = DIGITS[i & 0xf];
+        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
+
+        return new String(buf, cursor, bufLen - cursor);
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/InternalUtil.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/InternalUtil.java
new file mode 100644
index 0000000..bf3f043
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/InternalUtil.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+
+/**
+ * Helper to initialize the JNI libraries. This version runs when compiled
+ * as part of the platform.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class InternalUtil {
+    public static PublicKey logKeyToPublicKey(byte[] logKey)
+            throws NoSuchAlgorithmException {
+        try {
+            return new OpenSSLKey(NativeCrypto.EVP_parse_public_key(logKey)).getPublicKey();
+        } catch (ParsingException e) {
+            throw new NoSuchAlgorithmException(e);
+        }
+    }
+
+    public static PublicKey readPublicKeyPem(InputStream pem) throws InvalidKeyException, NoSuchAlgorithmException {
+        return OpenSSLKey.fromPublicKeyPemInputStream(pem).getPublicKey();
+    }
+
+    private InternalUtil() {
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/JSSEProvider.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/JSSEProvider.java
new file mode 100644
index 0000000..d4e2d4a
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/JSSEProvider.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.android.org.conscrypt;
+
+import java.security.Provider;
+
+/**
+ * JSSE Provider implementation.
+ *
+ * The current JSSE provider implementation uses the following
+ * crypto algorithms:
+ *
+ * Algorithms that MUST be provided by crypto provider:
+ *     Mac    HmacMD5
+ *     Mac    HmacSHA1
+ *     MessageDigest    MD5
+ *     MessageDigest    SHA-1
+ *     CertificateFactory    X509
+ *
+ * Trust manager implementation requires:
+ *     CertPathValidator    PKIX
+ *     CertificateFactory    X509
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class JSSEProvider extends Provider {
+
+    private static final long serialVersionUID = 3075686092260669675L;
+
+    public JSSEProvider() {
+        super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
+
+        put("KeyManagerFactory.PKIX", KeyManagerFactoryImpl.class.getName());
+        put("Alg.Alias.KeyManagerFactory.X509", "PKIX");
+
+        put("TrustManagerFactory.PKIX", TrustManagerFactoryImpl.class.getName());
+        put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
+
+        put("KeyStore.AndroidCAStore", TrustedCertificateKeyStoreSpi.class.getName());
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/NativeCryptoJni.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/NativeCryptoJni.java
new file mode 100644
index 0000000..254b45c
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/NativeCryptoJni.java
@@ -0,0 +1,31 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2015 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 com.android.org.conscrypt;
+
+/**
+ * Helper to initialize the JNI libraries. This version runs when compiled
+ * as part of the platform.
+ */
+class NativeCryptoJni {
+    public static void init() {
+        System.loadLibrary("javacrypto");
+    }
+
+    private NativeCryptoJni() {
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java
new file mode 100644
index 0000000..c24a313
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/Platform.java
@@ -0,0 +1,516 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2013 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 com.android.org.conscrypt;
+
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_SNDTIMEO;
+
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructTimeval;
+import dalvik.system.BlockGuard;
+import dalvik.system.CloseGuard;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.security.AlgorithmParameters;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Collections;
+import java.util.List;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.StandardConstants;
+import javax.net.ssl.X509ExtendedTrustManager;
+import javax.net.ssl.X509TrustManager;
+import libcore.net.NetworkSecurityPolicy;
+import com.android.org.conscrypt.ct.CTLogStore;
+import com.android.org.conscrypt.ct.CTLogStoreImpl;
+import com.android.org.conscrypt.ct.CTPolicy;
+import com.android.org.conscrypt.ct.CTPolicyImpl;
+import sun.security.x509.AlgorithmId;
+
+final class Platform {
+    private static class NoPreloadHolder { public static final Platform MAPPER = new Platform(); }
+
+    /**
+     * Runs all the setup for the platform that only needs to run once.
+     */
+    public static void setup() {
+        NoPreloadHolder.MAPPER.ping();
+    }
+
+    /**
+     * Just a placeholder to make sure the class is initialized.
+     */
+    private void ping() {}
+
+    private Platform() {}
+
+    /**
+     * Default name used in the {@link java.security.Security JCE system} by {@code OpenSSLProvider}
+     * if the default constructor is used.
+     */
+    // @VisibleForTesting - used by CTS
+    public static String getDefaultProviderName() {
+        return "AndroidOpenSSL";
+    }
+
+    static boolean provideTrustManagerByDefault() {
+        return false;
+    }
+
+    static FileDescriptor getFileDescriptor(Socket s) {
+        return s.getFileDescriptor$();
+    }
+
+    static FileDescriptor getFileDescriptorFromSSLSocket(AbstractConscryptSocket socket) {
+        try {
+            Field f_impl = Socket.class.getDeclaredField("impl");
+            f_impl.setAccessible(true);
+            Object socketImpl = f_impl.get(socket);
+            Field f_fd = SocketImpl.class.getDeclaredField("fd");
+            f_fd.setAccessible(true);
+            return (FileDescriptor) f_fd.get(socketImpl);
+        } catch (Exception e) {
+            throw new RuntimeException("Can't get FileDescriptor from socket", e);
+        }
+    }
+
+    static String getCurveName(ECParameterSpec spec) {
+        return spec.getCurveName();
+    }
+
+    static void setCurveName(ECParameterSpec spec, String curveName) {
+        spec.setCurveName(curveName);
+    }
+
+    static void setSocketWriteTimeout(Socket s, long timeoutMillis) throws SocketException {
+        StructTimeval tv = StructTimeval.fromMillis(timeoutMillis);
+        try {
+            Os.setsockoptTimeval(s.getFileDescriptor$(), SOL_SOCKET, SO_SNDTIMEO, tv);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsSocketException();
+        }
+    }
+
+    static void setSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
+        impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
+        impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder());
+        List<SNIServerName> serverNames = params.getServerNames();
+        if (serverNames != null) {
+            for (SNIServerName serverName : serverNames) {
+                if (serverName.getType() == StandardConstants.SNI_HOST_NAME) {
+                    socket.setHostname(((SNIHostName) serverName).getAsciiName());
+                    break;
+                }
+            }
+        }
+        impl.setApplicationProtocols(params.getApplicationProtocols());
+    }
+
+    static void getSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) {
+        params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
+        params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder());
+        if (impl.getUseSni() && AddressUtils.isValidSniHostname(socket.getHostname())) {
+            params.setServerNames(Collections.<SNIServerName>singletonList(
+                    new SNIHostName(socket.getHostname())));
+        }
+        params.setApplicationProtocols(impl.getApplicationProtocols());
+    }
+
+    static void setSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) {
+        impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
+        impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder());
+        List<SNIServerName> serverNames = params.getServerNames();
+        if (serverNames != null) {
+            for (SNIServerName serverName : serverNames) {
+                if (serverName.getType() == StandardConstants.SNI_HOST_NAME) {
+                    engine.setHostname(((SNIHostName) serverName).getAsciiName());
+                    break;
+                }
+            }
+        }
+        impl.setApplicationProtocols(params.getApplicationProtocols());
+    }
+
+    static void getSSLParameters(
+            SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) {
+        params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
+        params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder());
+        if (impl.getUseSni() && AddressUtils.isValidSniHostname(engine.getHostname())) {
+            params.setServerNames(Collections.<SNIServerName>singletonList(
+                    new SNIHostName(engine.getHostname())));
+        }
+        params.setApplicationProtocols(impl.getApplicationProtocols());
+    }
+
+    /**
+     * Helper function to unify calls to the different names used for each function taking a
+     * Socket, SSLEngine, or String (legacy Android).
+     */
+    private static boolean checkTrusted(String methodName, X509TrustManager tm,
+            X509Certificate[] chain, String authType, Class<?> argumentClass,
+            Object argumentInstance) throws CertificateException {
+        // Use duck-typing to try and call the hostname-aware method if available.
+        try {
+            Method method = tm.getClass().getMethod(
+                    methodName, X509Certificate[].class, String.class, argumentClass);
+            method.invoke(tm, chain, authType, argumentInstance);
+            return true;
+        } catch (NoSuchMethodException | IllegalAccessException ignored) {
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof CertificateException) {
+                throw(CertificateException) e.getCause();
+            }
+            throw new RuntimeException(e.getCause());
+        }
+        return false;
+    }
+
+    static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            AbstractConscryptSocket socket) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkClientTrusted(chain, authType, socket);
+        } else if (!checkTrusted("checkClientTrusted", tm, chain, authType, Socket.class, socket)
+                && !checkTrusted("checkClientTrusted", tm, chain, authType, String.class,
+                           socket.getHandshakeSession().getPeerHost())) {
+            tm.checkClientTrusted(chain, authType);
+        }
+    }
+
+    static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            AbstractConscryptSocket socket) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkServerTrusted(chain, authType, socket);
+        } else if (!checkTrusted("checkServerTrusted", tm, chain, authType, Socket.class, socket)
+                && !checkTrusted("checkServerTrusted", tm, chain, authType, String.class,
+                           socket.getHandshakeSession().getPeerHost())) {
+            tm.checkServerTrusted(chain, authType);
+        }
+    }
+
+    static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            ConscryptEngine engine) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkClientTrusted(chain, authType, engine);
+        } else if (!checkTrusted("checkClientTrusted", tm, chain, authType, SSLEngine.class, engine)
+                && !checkTrusted("checkClientTrusted", tm, chain, authType, String.class,
+                           engine.getHandshakeSession().getPeerHost())) {
+            tm.checkClientTrusted(chain, authType);
+        }
+    }
+
+    static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType,
+            ConscryptEngine engine) throws CertificateException {
+        if (tm instanceof X509ExtendedTrustManager) {
+            X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
+            x509etm.checkServerTrusted(chain, authType, engine);
+        } else if (!checkTrusted("checkServerTrusted", tm, chain, authType, SSLEngine.class, engine)
+                && !checkTrusted("checkServerTrusted", tm, chain, authType, String.class,
+                           engine.getHandshakeSession().getPeerHost())) {
+            tm.checkServerTrusted(chain, authType);
+        }
+    }
+
+    /**
+     * Wraps an old AndroidOpenSSL key instance. This is not needed on platform
+     * builds since we didn't backport, so return null.
+     */
+    static OpenSSLKey wrapRsaKey(PrivateKey key) {
+        return null;
+    }
+
+    /**
+     * Logs to the system EventLog system.
+     */
+    static void logEvent(String message) {
+        try {
+            Class processClass = Class.forName("android.os.Process");
+            Object processInstance = processClass.newInstance();
+            Method myUidMethod = processClass.getMethod("myUid", (Class[]) null);
+            int uid = (Integer) myUidMethod.invoke(processInstance);
+
+            Class eventLogClass = Class.forName("android.util.EventLog");
+            Object eventLogInstance = eventLogClass.newInstance();
+            Method writeEventMethod = eventLogClass.getMethod(
+                    "writeEvent", new Class[] {Integer.TYPE, Object[].class});
+            writeEventMethod.invoke(eventLogInstance, 0x534e4554 /* SNET */,
+                    new Object[] {"conscrypt", uid, message});
+        } catch (Exception e) {
+            // Do not log and fail silently
+        }
+    }
+
+    static SSLEngine wrapEngine(ConscryptEngine engine) {
+        return new Java8EngineWrapper(engine);
+    }
+
+    static SSLEngine unwrapEngine(SSLEngine engine) {
+        return Java8EngineWrapper.getDelegate(engine);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(SSLParametersImpl sslParameters)
+            throws IOException {
+        return new Java8EngineSocket(sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(String hostname, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        return new Java8EngineSocket(hostname, port, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(InetAddress address, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        return new Java8EngineSocket(address, port, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(String hostname, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        return new Java8EngineSocket(hostname, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(InetAddress address, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        return new Java8EngineSocket(address, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptEngineSocket createEngineSocket(Socket socket, String hostname, int port,
+            boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
+        return new Java8EngineSocket(socket, hostname, port, autoClose, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(SSLParametersImpl sslParameters)
+            throws IOException {
+        return new Java8FileDescriptorSocket(sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(String hostname, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        return new Java8FileDescriptorSocket(hostname, port, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(InetAddress address, int port,
+            SSLParametersImpl sslParameters) throws IOException {
+        return new Java8FileDescriptorSocket(address, port, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(String hostname, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        return new Java8FileDescriptorSocket(
+                hostname, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(InetAddress address, int port,
+            InetAddress clientAddress, int clientPort, SSLParametersImpl sslParameters)
+            throws IOException {
+        return new Java8FileDescriptorSocket(
+                address, port, clientAddress, clientPort, sslParameters);
+    }
+
+    static ConscryptFileDescriptorSocket createFileDescriptorSocket(Socket socket, String hostname,
+            int port, boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
+        return new Java8FileDescriptorSocket(socket, hostname, port, autoClose, sslParameters);
+    }
+
+    /**
+     * Wrap the SocketFactory with the platform wrapper if needed for compatability.
+     * For the platform-bundled library we never need to wrap.
+     */
+    static SSLSocketFactory wrapSocketFactoryIfNeeded(OpenSSLSocketFactoryImpl factory) {
+        return factory;
+    }
+
+    /**
+     * Convert from platform's GCMParameterSpec to our internal version.
+     */
+    static GCMParameters fromGCMParameterSpec(AlgorithmParameterSpec params) {
+        if (params instanceof GCMParameterSpec) {
+            GCMParameterSpec gcmParams = (GCMParameterSpec) params;
+            return new GCMParameters(gcmParams.getTLen(), gcmParams.getIV());
+        }
+        return null;
+    }
+
+    /**
+     * Convert from an opaque AlgorithmParameters to the platform's GCMParameterSpec.
+     */
+    static AlgorithmParameterSpec fromGCMParameters(AlgorithmParameters params) {
+        try {
+            return params.getParameterSpec(GCMParameterSpec.class);
+        } catch (InvalidParameterSpecException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Creates a platform version of {@code GCMParameterSpec}.
+     */
+    static AlgorithmParameterSpec toGCMParameterSpec(int tagLenInBits, byte[] iv) {
+        return new GCMParameterSpec(tagLenInBits, iv);
+    }
+
+    /*
+     * CloseGuard functions.
+     */
+
+    static CloseGuard closeGuardGet() {
+        return CloseGuard.get();
+    }
+
+    static void closeGuardOpen(Object guardObj, String message) {
+        CloseGuard guard = (CloseGuard) guardObj;
+        guard.open(message);
+    }
+
+    static void closeGuardClose(Object guardObj) {
+        CloseGuard guard = (CloseGuard) guardObj;
+        guard.close();
+    }
+
+    static void closeGuardWarnIfOpen(Object guardObj) {
+        CloseGuard guard = (CloseGuard) guardObj;
+        guard.warnIfOpen();
+    }
+
+    /*
+     * BlockGuard functions.
+     */
+
+    static void blockGuardOnNetwork() {
+        BlockGuard.getThreadPolicy().onNetwork();
+    }
+
+    /**
+     * OID to Algorithm Name mapping.
+     */
+    static String oidToAlgorithmName(String oid) {
+        try {
+            return AlgorithmId.get(oid).getName();
+        } catch (NoSuchAlgorithmException e) {
+            return oid;
+        }
+    }
+
+    /**
+     * Provides extended capabilities for the session if supported by the platform.
+     */
+    static SSLSession wrapSSLSession(ExternalSession sslSession) {
+        return new Java8ExtendedSSLSession(sslSession);
+    }
+
+    public static String getOriginalHostNameFromInetAddress(InetAddress addr) {
+        try {
+            Method getHolder = InetAddress.class.getDeclaredMethod("holder");
+            getHolder.setAccessible(true);
+
+            Method getOriginalHostName = Class.forName("java.net.InetAddress$InetAddressHolder")
+                                                 .getDeclaredMethod("getOriginalHostName");
+            getOriginalHostName.setAccessible(true);
+
+            String originalHostName = (String) getOriginalHostName.invoke(getHolder.invoke(addr));
+            if (originalHostName == null) {
+                return addr.getHostAddress();
+            }
+            return originalHostName;
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Failed to get originalHostName", e);
+        } catch (ClassNotFoundException ignore) {
+            // passthrough and return addr.getHostAddress()
+        } catch (IllegalAccessException ignore) {
+        } catch (NoSuchMethodException ignore) {
+        }
+        return addr.getHostAddress();
+    }
+
+    /*
+     * Pre-Java-7 backward compatibility.
+     */
+
+    static String getHostStringFromInetSocketAddress(InetSocketAddress addr) {
+        return addr.getHostString();
+    }
+
+    // The platform always has X509ExtendedTrustManager
+    static boolean supportsX509ExtendedTrustManager() {
+        return true;
+    }
+
+    static boolean isCTVerificationRequired(String hostname) {
+        return NetworkSecurityPolicy.getInstance().isCertificateTransparencyVerificationRequired(
+                hostname);
+    }
+
+    static boolean supportsConscryptCertStore() {
+        return true;
+    }
+
+    static KeyStore getDefaultCertKeyStore() throws KeyStoreException {
+        KeyStore keyStore = KeyStore.getInstance("AndroidCAStore");
+        try {
+            keyStore.load(null, null);
+        } catch (IOException | CertificateException | NoSuchAlgorithmException e) {
+            throw new KeyStoreException(e);
+        }
+        return keyStore;
+    }
+
+    static ConscryptCertStore newDefaultCertStore() {
+        return new TrustedCertificateStore();
+    }
+
+    static CertBlacklist newDefaultBlacklist() {
+        return CertBlacklistImpl.getDefault();
+    }
+
+    static CTLogStore newDefaultLogStore() {
+        return new CTLogStoreImpl();
+    }
+
+    static CTPolicy newDefaultPolicy(CTLogStore logStore) {
+        return new CTPolicyImpl(logStore, 2);
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateKeyStoreSpi.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateKeyStoreSpi.java
new file mode 100644
index 0000000..6bfdbbd
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateKeyStoreSpi.java
@@ -0,0 +1,132 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyStoreSpi;
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+
+/**
+ * A KeyStoreSpi wrapper for the TrustedCertificateStore.
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class TrustedCertificateKeyStoreSpi extends KeyStoreSpi {
+
+    private final TrustedCertificateStore store = new TrustedCertificateStore();
+
+    @Override
+    public Key engineGetKey(String alias, char[] password) {
+        if (alias == null) {
+            throw new NullPointerException("alias == null");
+        }
+        return null;
+    }
+
+    @Override
+    public Certificate[] engineGetCertificateChain(String alias) {
+        if (alias == null) {
+            throw new NullPointerException("alias == null");
+        }
+        return null;
+    }
+
+    @Override
+    public Certificate engineGetCertificate(String alias) {
+        return store.getCertificate(alias);
+    }
+
+    @Override
+    public Date engineGetCreationDate(String alias) {
+        return store.getCreationDate(alias);
+    }
+
+    @Override
+    public void engineSetKeyEntry(
+            String alias, Key key, char[] password, Certificate[] chain) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void engineSetCertificateEntry(String alias, Certificate cert) {
+        if (alias == null) {
+            throw new NullPointerException("alias == null");
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void engineDeleteEntry(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Enumeration<String> engineAliases() {
+        return Collections.enumeration(store.aliases());
+    }
+
+    @Override
+    public boolean engineContainsAlias(String alias) {
+        return store.containsAlias(alias);
+    }
+
+    @Override
+    public int engineSize() {
+        return store.aliases().size();
+    }
+
+    @Override
+    public boolean engineIsKeyEntry(String alias) {
+        if (alias == null) {
+            throw new NullPointerException("alias == null");
+        }
+        return false;
+    }
+
+    @Override
+    public boolean engineIsCertificateEntry(String alias) {
+        return engineContainsAlias(alias);
+    }
+
+    @Override
+    public String engineGetCertificateAlias(Certificate c) {
+        return store.getCertificateAlias(c);
+    }
+
+    @Override
+    public void engineStore(OutputStream stream, char[] password) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void engineLoad(InputStream stream, char[] password) {
+        if (stream != null) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java
new file mode 100644
index 0000000..7296890
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/TrustedCertificateStore.java
@@ -0,0 +1,691 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.security.auth.x500.X500Principal;
+import com.android.org.conscrypt.io.IoUtils;
+
+/**
+ * A source for trusted root certificate authority (CA) certificates
+ * supporting an immutable system CA directory along with mutable
+ * directories allowing the user addition of custom CAs and user
+ * removal of system CAs. This store supports the {@code
+ * TrustedCertificateKeyStoreSpi} wrapper to allow a traditional
+ * KeyStore interface for use with {@link
+ * javax.net.ssl.TrustManagerFactory.init}.
+ *
+ * <p>The CAs are accessed via {@code KeyStore} style aliases. Aliases
+ * are made up of a prefix identifying the source ("system:" vs
+ * "user:") and a suffix based on the OpenSSL X509_NAME_hash_old
+ * function of the CA's subject name. For example, the system CA for
+ * "C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification
+ * Authority" could be represented as "system:7651b327.0". By using
+ * the subject hash, operations such as {@link #getCertificateAlias
+ * getCertificateAlias} can be implemented efficiently without
+ * scanning the entire store.
+ *
+ * <p>In addition to supporting the {@code
+ * TrustedCertificateKeyStoreSpi} implementation, {@code
+ * TrustedCertificateStore} also provides the additional public
+ * methods {@link #isTrustAnchor} and {@link #findIssuer} to allow
+ * efficient lookup operations for CAs again based on the file naming
+ * convention.
+ *
+ * <p>The KeyChainService users the {@link installCertificate} and
+ * {@link #deleteCertificateEntry} to install user CAs as well as
+ * delete those user CAs as well as system CAs. The deletion of system
+ * CAs is performed by placing an exact copy of that CA in the deleted
+ * directory. Such deletions are intended to persist across upgrades
+ * but not intended to mask a CA with a matching name or public key
+ * but is otherwise reissued in a system update. Reinstalling a
+ * deleted system certificate simply removes the copy from the deleted
+ * directory, reenabling the original in the system directory.
+ *
+ * <p>Note that the default mutable directory is created by init via
+ * configuration in the system/core/rootdir/init.rc file. The
+ * directive "mkdir /data/misc/keychain 0775 system system"
+ * ensures that its owner and group are the system uid and system
+ * gid and that it is world readable but only writable by the system
+ * user.
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+@Internal
+public class TrustedCertificateStore implements ConscryptCertStore {
+
+    private static final String PREFIX_SYSTEM = "system:";
+    private static final String PREFIX_USER = "user:";
+
+    public static final boolean isSystem(String alias) {
+        return alias.startsWith(PREFIX_SYSTEM);
+    }
+    @libcore.api.CorePlatformApi
+    public static final boolean isUser(String alias) {
+        return alias.startsWith(PREFIX_USER);
+    }
+
+    private static class PreloadHolder {
+        private static File defaultCaCertsSystemDir;
+        private static File defaultCaCertsAddedDir;
+        private static File defaultCaCertsDeletedDir;
+
+        static {
+            String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
+            String ANDROID_DATA = System.getenv("ANDROID_DATA");
+            defaultCaCertsSystemDir = new File(ANDROID_ROOT + "/etc/security/cacerts");
+            setDefaultUserDirectory(new File(ANDROID_DATA + "/misc/keychain"));
+        }
+    }
+
+    private static final CertificateFactory CERT_FACTORY;
+    static {
+        try {
+            CERT_FACTORY = CertificateFactory.getInstance("X509");
+        } catch (CertificateException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    @libcore.api.CorePlatformApi
+    public static void setDefaultUserDirectory(File root) {
+        PreloadHolder.defaultCaCertsAddedDir = new File(root, "cacerts-added");
+        PreloadHolder.defaultCaCertsDeletedDir = new File(root, "cacerts-removed");
+    }
+
+    private final File systemDir;
+    private final File addedDir;
+    private final File deletedDir;
+
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public TrustedCertificateStore() {
+        this(PreloadHolder.defaultCaCertsSystemDir, PreloadHolder.defaultCaCertsAddedDir,
+                PreloadHolder.defaultCaCertsDeletedDir);
+    }
+
+    public TrustedCertificateStore(File systemDir, File addedDir, File deletedDir) {
+        this.systemDir = systemDir;
+        this.addedDir = addedDir;
+        this.deletedDir = deletedDir;
+    }
+
+    @libcore.api.CorePlatformApi
+    public Certificate getCertificate(String alias) {
+        return getCertificate(alias, false);
+    }
+
+    @libcore.api.CorePlatformApi
+    public Certificate getCertificate(String alias, boolean includeDeletedSystem) {
+
+        File file = fileForAlias(alias);
+        if (file == null || (isUser(alias) && isTombstone(file))) {
+            return null;
+        }
+        X509Certificate cert = readCertificate(file);
+        if (cert == null || (isSystem(alias)
+                             && !includeDeletedSystem
+                             && isDeletedSystemCertificate(cert))) {
+            // skip malformed certs as well as deleted system ones
+            return null;
+        }
+        return cert;
+    }
+
+    private File fileForAlias(String alias) {
+        if (alias == null) {
+            throw new NullPointerException("alias == null");
+        }
+        File file;
+        if (isSystem(alias)) {
+            file = new File(systemDir, alias.substring(PREFIX_SYSTEM.length()));
+        } else if (isUser(alias)) {
+            file = new File(addedDir, alias.substring(PREFIX_USER.length()));
+        } else {
+            return null;
+        }
+        if (!file.exists() || isTombstone(file)) {
+            // silently elide tombstones
+            return null;
+        }
+        return file;
+    }
+
+    private boolean isTombstone(File file) {
+        return file.length() == 0;
+    }
+
+    private X509Certificate readCertificate(File file) {
+        if (!file.isFile()) {
+            return null;
+        }
+        InputStream is = null;
+        try {
+            is = new BufferedInputStream(new FileInputStream(file));
+            return (X509Certificate) CERT_FACTORY.generateCertificate(is);
+        } catch (IOException e) {
+            return null;
+        } catch (CertificateException e) {
+            // reading a cert while its being installed can lead to this.
+            // just pretend like its not available yet.
+            return null;
+        } finally {
+            IoUtils.closeQuietly(is);
+        }
+    }
+
+    private void writeCertificate(File file, X509Certificate cert)
+            throws IOException, CertificateException {
+        File dir = file.getParentFile();
+        dir.mkdirs();
+        dir.setReadable(true, false);
+        dir.setExecutable(true, false);
+        OutputStream os = null;
+        try {
+            os = new FileOutputStream(file);
+            os.write(cert.getEncoded());
+        } finally {
+            IoUtils.closeQuietly(os);
+        }
+        file.setReadable(true, false);
+    }
+
+    private boolean isDeletedSystemCertificate(X509Certificate x) {
+        return getCertificateFile(deletedDir, x).exists();
+    }
+
+    @libcore.api.CorePlatformApi
+    public Date getCreationDate(String alias) {
+        // containsAlias check ensures the later fileForAlias result
+        // was not a deleted system cert.
+        if (!containsAlias(alias)) {
+            return null;
+        }
+        File file = fileForAlias(alias);
+        if (file == null) {
+            return null;
+        }
+        long time = file.lastModified();
+        if (time == 0) {
+            return null;
+        }
+        return new Date(time);
+    }
+
+    @libcore.api.CorePlatformApi
+    public Set<String> aliases() {
+        Set<String> result = new HashSet<String>();
+        addAliases(result, PREFIX_USER, addedDir);
+        addAliases(result, PREFIX_SYSTEM, systemDir);
+        return result;
+    }
+
+    @libcore.api.CorePlatformApi
+    public Set<String> userAliases() {
+        Set<String> result = new HashSet<String>();
+        addAliases(result, PREFIX_USER, addedDir);
+        return result;
+    }
+
+    private void addAliases(Set<String> result, String prefix, File dir) {
+        String[] files = dir.list();
+        if (files == null) {
+            return;
+        }
+        for (String filename : files) {
+            String alias = prefix + filename;
+            if (containsAlias(alias)) {
+                result.add(alias);
+            }
+        }
+    }
+
+    @libcore.api.CorePlatformApi
+    public Set<String> allSystemAliases() {
+        Set<String> result = new HashSet<String>();
+        String[] files = systemDir.list();
+        if (files == null) {
+            return result;
+        }
+        for (String filename : files) {
+            String alias = PREFIX_SYSTEM + filename;
+            if (containsAlias(alias, true)) {
+                result.add(alias);
+            }
+        }
+        return result;
+    }
+
+    @libcore.api.CorePlatformApi
+    public boolean containsAlias(String alias) {
+        return containsAlias(alias, false);
+    }
+
+    private boolean containsAlias(String alias, boolean includeDeletedSystem) {
+        return getCertificate(alias, includeDeletedSystem) != null;
+    }
+
+    @libcore.api.CorePlatformApi
+    public String getCertificateAlias(Certificate c) {
+        return getCertificateAlias(c, false);
+    }
+
+    @libcore.api.CorePlatformApi
+    public String getCertificateAlias(Certificate c, boolean includeDeletedSystem) {
+        if (c == null || !(c instanceof X509Certificate)) {
+            return null;
+        }
+        X509Certificate x = (X509Certificate) c;
+        File user = getCertificateFile(addedDir, x);
+        if (user.exists()) {
+            return PREFIX_USER + user.getName();
+        }
+        if (!includeDeletedSystem && isDeletedSystemCertificate(x)) {
+            return null;
+        }
+        File system = getCertificateFile(systemDir, x);
+        if (system.exists()) {
+            return PREFIX_SYSTEM + system.getName();
+        }
+        return null;
+    }
+
+    /**
+     * Returns true to indicate that the certificate was added by the
+     * user, false otherwise.
+     */
+    @libcore.api.CorePlatformApi
+    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
+     * File.exists()} on the result.
+     *
+     * @VisibleForTesting
+     */
+    @libcore.api.CorePlatformApi
+    public File getCertificateFile(File dir, final X509Certificate x) {
+        // compare X509Certificate.getEncoded values
+        CertSelector selector = new CertSelector() {
+            @Override
+            public boolean match(X509Certificate cert) {
+                return cert.equals(x);
+            }
+        };
+        return findCert(dir, x.getSubjectX500Principal(), selector, File.class);
+    }
+
+    /**
+     * This non-{@code KeyStoreSpi} public interface is used by {@code
+     * TrustManagerImpl} to locate a CA certificate with the same name
+     * and public key as the provided {@code X509Certificate}. We
+     * match on the name and public key and not the entire certificate
+     * since a CA may be reissued with the same name and PublicKey but
+     * with other differences (for example when switching signature
+     * from md2WithRSAEncryption to SHA1withRSA)
+     */
+    @libcore.api.CorePlatformApi
+    @Override
+    public X509Certificate getTrustAnchor(final X509Certificate c) {
+        // compare X509Certificate.getPublicKey values
+        CertSelector selector = new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                return ca.getPublicKey().equals(c.getPublicKey());
+            }
+        };
+        X509Certificate user = findCert(addedDir,
+                                        c.getSubjectX500Principal(),
+                                        selector,
+                                        X509Certificate.class);
+        if (user != null) {
+            return user;
+        }
+        X509Certificate system = findCert(systemDir,
+                                          c.getSubjectX500Principal(),
+                                          selector,
+                                          X509Certificate.class);
+        if (system != null && !isDeletedSystemCertificate(system)) {
+            return system;
+        }
+        return null;
+    }
+
+    /**
+     * This non-{@code KeyStoreSpi} public interface is used by {@code
+     * TrustManagerImpl} to locate the CA certificate that signed the
+     * provided {@code X509Certificate}.
+     */
+    @libcore.api.CorePlatformApi
+    public X509Certificate findIssuer(final X509Certificate c) {
+        // match on verified issuer of Certificate
+        CertSelector selector = new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                try {
+                    c.verify(ca.getPublicKey());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        };
+        X500Principal issuer = c.getIssuerX500Principal();
+        X509Certificate user = findCert(addedDir, issuer, selector, X509Certificate.class);
+        if (user != null) {
+            return user;
+        }
+        X509Certificate system = findCert(systemDir, issuer, selector, X509Certificate.class);
+        if (system != null && !isDeletedSystemCertificate(system)) {
+            return system;
+        }
+        return null;
+    }
+
+    @libcore.api.CorePlatformApi
+    @Override
+    public Set<X509Certificate> findAllIssuers(final X509Certificate c) {
+        Set<X509Certificate> issuers = null;
+        CertSelector selector = new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                try {
+                    c.verify(ca.getPublicKey());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        };
+        X500Principal issuer = c.getIssuerX500Principal();
+        Set<X509Certificate> userAddedCerts = findCert(addedDir, issuer, selector, Set.class);
+        if (userAddedCerts != null) {
+            issuers = userAddedCerts;
+        }
+        selector = new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                try {
+                    if (isDeletedSystemCertificate(ca)) {
+                        return false;
+                    }
+                    c.verify(ca.getPublicKey());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        };
+        Set<X509Certificate> systemCerts = findCert(systemDir, issuer, selector, Set.class);
+        if (systemCerts != null) {
+            if (issuers != null) {
+                issuers.addAll(systemCerts);
+            } else {
+                issuers = systemCerts;
+            }
+        }
+        return (issuers != null) ? issuers : Collections.<X509Certificate>emptySet();
+    }
+
+    private static boolean isSelfIssuedCertificate(OpenSSLX509Certificate cert) {
+        final long ctx = cert.getContext();
+        return NativeCrypto.X509_check_issued(ctx, cert, ctx, cert) == 0;
+    }
+
+    /**
+     * Converts the {@code cert} to the internal OpenSSL X.509 format so we can
+     * run {@link NativeCrypto} methods on it.
+     */
+    private static OpenSSLX509Certificate convertToOpenSSLIfNeeded(X509Certificate cert)
+            throws CertificateException {
+        if (cert == null) {
+            return null;
+        }
+
+        if (cert instanceof OpenSSLX509Certificate) {
+            return (OpenSSLX509Certificate) cert;
+        }
+
+        try {
+            return OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
+        } catch (Exception e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    /**
+     * Attempt to build a certificate chain from the supplied {@code leaf}
+     * argument through the chain of issuers as high up as known. If the chain
+     * can't be completed, the most complete chain available will be returned.
+     * This means that a list with only the {@code leaf} certificate is returned
+     * if no issuer certificates could be found.
+     *
+     * @throws CertificateException if there was a problem parsing the
+     *             certificates
+     */
+    @dalvik.annotation.compat.UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public List<X509Certificate> getCertificateChain(X509Certificate leaf)
+            throws CertificateException {
+        final LinkedHashSet<OpenSSLX509Certificate> chain
+                = new LinkedHashSet<OpenSSLX509Certificate>();
+        OpenSSLX509Certificate cert = convertToOpenSSLIfNeeded(leaf);
+        chain.add(cert);
+
+        while (true) {
+            if (isSelfIssuedCertificate(cert)) {
+                break;
+            }
+            cert = convertToOpenSSLIfNeeded(findIssuer(cert));
+            if (cert == null || chain.contains(cert)) {
+                break;
+            }
+            chain.add(cert);
+        }
+
+        return new ArrayList<X509Certificate>(chain);
+    }
+
+    // like java.security.cert.CertSelector but with X509Certificate and without cloning
+    private static interface CertSelector {
+        public boolean match(X509Certificate cert);
+    }
+
+    private <T> T findCert(
+            File dir, X500Principal subject, CertSelector selector, Class<T> desiredReturnType) {
+
+        Set<X509Certificate> certs = null;
+        String hash = hash(subject);
+        for (int index = 0; true; index++) {
+            File file = file(dir, hash, index);
+            if (!file.isFile()) {
+                // could not find a match, no file exists, bail
+                if (desiredReturnType == Boolean.class) {
+                    return (T) Boolean.FALSE;
+                }
+                if (desiredReturnType == File.class) {
+                    // we return file so that caller that wants to
+                    // write knows what the next available has
+                    // location is
+                    return (T) file;
+                }
+                if (desiredReturnType == Set.class) {
+                    return (T) certs;
+                }
+                return null;
+            }
+            if (isTombstone(file)) {
+                continue;
+            }
+            X509Certificate cert = readCertificate(file);
+            if (cert == null) {
+                // skip problem certificates
+                continue;
+            }
+            if (selector.match(cert)) {
+                if (desiredReturnType == X509Certificate.class) {
+                    return (T) cert;
+                } else if (desiredReturnType == Boolean.class) {
+                    return (T) Boolean.TRUE;
+                } else if (desiredReturnType == File.class) {
+                    return (T) file;
+                } else if (desiredReturnType == Set.class) {
+                    if (certs == null) {
+                        certs = new HashSet<X509Certificate>();
+                    }
+                    certs.add((X509Certificate) cert);
+                } else {
+                    throw new AssertionError();
+                }
+            }
+        }
+    }
+
+    private String hash(X500Principal name) {
+        int hash = NativeCrypto.X509_NAME_hash_old(name);
+        return Hex.intToHexString(hash, 8);
+    }
+
+    private File file(File dir, String hash, int index) {
+        return new File(dir, hash + '.' + index);
+    }
+
+    /**
+     * This non-{@code KeyStoreSpi} public interface is used by the
+     * {@code KeyChainService} to install new CA certificates. It
+     * silently ignores the certificate if it already exists in the
+     * store.
+     */
+    @libcore.api.CorePlatformApi
+    public void installCertificate(X509Certificate cert) throws IOException, CertificateException {
+        if (cert == null) {
+            throw new NullPointerException("cert == null");
+        }
+        File system = getCertificateFile(systemDir, cert);
+        if (system.exists()) {
+            File deleted = getCertificateFile(deletedDir, cert);
+            if (deleted.exists()) {
+                // we have a system cert that was marked deleted.
+                // remove the deleted marker to expose the original
+                if (!deleted.delete()) {
+                    throw new IOException("Could not remove " + deleted);
+                }
+                return;
+            }
+            // otherwise we just have a dup of an existing system cert.
+            // return taking no further action.
+            return;
+        }
+        File user = getCertificateFile(addedDir, cert);
+        if (user.exists()) {
+            // we have an already installed user cert, bail.
+            return;
+        }
+        // install the user cert
+        writeCertificate(user, cert);
+    }
+
+    /**
+     * This could be considered the implementation of {@code
+     * TrustedCertificateKeyStoreSpi.engineDeleteEntry} but we
+     * consider {@code TrustedCertificateKeyStoreSpi} to be read
+     * only. Instead, this is used by the {@code KeyChainService} to
+     * delete CA certificates.
+     */
+    @libcore.api.CorePlatformApi
+    public void deleteCertificateEntry(String alias) throws IOException, CertificateException {
+        if (alias == null) {
+            return;
+        }
+        File file = fileForAlias(alias);
+        if (file == null) {
+            return;
+        }
+        if (isSystem(alias)) {
+            X509Certificate cert = readCertificate(file);
+            if (cert == null) {
+                // skip problem certificates
+                return;
+            }
+            File deleted = getCertificateFile(deletedDir, cert);
+            if (deleted.exists()) {
+                // already deleted system certificate
+                return;
+            }
+            // write copy of system cert to marked as deleted
+            writeCertificate(deleted, cert);
+            return;
+        }
+        if (isUser(alias)) {
+            // truncate the file to make a tombstone by opening and closing.
+            // we need ensure that we don't leave a gap before a valid cert.
+            new FileOutputStream(file).close();
+            removeUnnecessaryTombstones(alias);
+            return;
+        }
+        // non-existant user cert, nothing to delete
+    }
+
+    private void removeUnnecessaryTombstones(String alias) throws IOException {
+        if (!isUser(alias)) {
+            throw new AssertionError(alias);
+        }
+        int dotIndex = alias.lastIndexOf('.');
+        if (dotIndex == -1) {
+            throw new AssertionError(alias);
+        }
+
+        String hash = alias.substring(PREFIX_USER.length(), dotIndex);
+        int lastTombstoneIndex = Integer.parseInt(alias.substring(dotIndex + 1));
+
+        if (file(addedDir, hash, lastTombstoneIndex + 1).exists()) {
+            return;
+        }
+        while (lastTombstoneIndex >= 0) {
+            File file = file(addedDir, hash, lastTombstoneIndex);
+            if (!isTombstone(file)) {
+                break;
+            }
+            if (!file.delete()) {
+                throw new IOException("Could not remove " + file);
+            }
+            lastTombstoneIndex--;
+        }
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java
new file mode 100644
index 0000000..37c84c8
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTLogStoreImpl.java
@@ -0,0 +1,257 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Scanner;
+import java.util.Set;
+import com.android.org.conscrypt.Internal;
+import com.android.org.conscrypt.InternalUtil;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CTLogStoreImpl implements CTLogStore {
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+    /**
+     * Thrown when parsing of a log file fails.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class InvalidLogFileException extends Exception {
+        public InvalidLogFileException() {
+        }
+
+        public InvalidLogFileException(String message) {
+            super(message);
+        }
+
+        public InvalidLogFileException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+        public InvalidLogFileException(Throwable cause) {
+            super(cause);
+        }
+    }
+
+    private static final File defaultUserLogDir;
+    private static final File defaultSystemLogDir;
+    // Lazy loaded by CTLogStoreImpl()
+    private static volatile CTLogInfo[] defaultFallbackLogs = null;
+    static {
+        String ANDROID_DATA = System.getenv("ANDROID_DATA");
+        String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
+        defaultUserLogDir = new File(ANDROID_DATA + "/misc/keychain/trusted_ct_logs/current/");
+        defaultSystemLogDir = new File(ANDROID_ROOT + "/etc/security/ct_known_logs/");
+    }
+
+    private File userLogDir;
+    private File systemLogDir;
+    private CTLogInfo[] fallbackLogs;
+
+    private HashMap<ByteBuffer, CTLogInfo> logCache = new HashMap<>();
+    private Set<ByteBuffer> missingLogCache = Collections.synchronizedSet(new HashSet<ByteBuffer>());
+
+    public CTLogStoreImpl() {
+        this(defaultUserLogDir,
+             defaultSystemLogDir,
+             getDefaultFallbackLogs());
+    }
+
+    public CTLogStoreImpl(File userLogDir, File systemLogDir, CTLogInfo[] fallbackLogs) {
+        this.userLogDir = userLogDir;
+        this.systemLogDir = systemLogDir;
+        this.fallbackLogs = fallbackLogs;
+    }
+
+    @Override
+    public CTLogInfo getKnownLog(byte[] logId) {
+        ByteBuffer buf = ByteBuffer.wrap(logId);
+        CTLogInfo log = logCache.get(buf);
+        if (log != null) {
+            return log;
+        }
+        if (missingLogCache.contains(buf)) {
+            return null;
+        }
+
+        log = findKnownLog(logId);
+        if (log != null) {
+            logCache.put(buf, log);
+        } else {
+            missingLogCache.add(buf);
+        }
+
+        return log;
+    }
+
+    private CTLogInfo findKnownLog(byte[] logId) {
+        String filename = hexEncode(logId);
+        try {
+            return loadLog(new File(userLogDir, filename));
+        } catch (InvalidLogFileException e) {
+            return null;
+        } catch (FileNotFoundException e) {}
+
+        try {
+            return loadLog(new File(systemLogDir, filename));
+        } catch (InvalidLogFileException e) {
+            return null;
+        } catch (FileNotFoundException e) {}
+
+        // If the updateable logs dont exist then use the fallback logs.
+        if (!userLogDir.exists()) {
+            for (CTLogInfo log: fallbackLogs) {
+                if (Arrays.equals(logId, log.getID())) {
+                    return log;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static CTLogInfo[] getDefaultFallbackLogs() {
+        CTLogInfo[] result = defaultFallbackLogs;
+        if (result == null) {
+            // single-check idiom
+            defaultFallbackLogs = result = createDefaultFallbackLogs();
+        }
+        return result;
+    }
+
+    private static CTLogInfo[] createDefaultFallbackLogs() {
+        CTLogInfo[] logs = new CTLogInfo[KnownLogs.LOG_COUNT];
+        for (int i = 0; i < KnownLogs.LOG_COUNT; i++) {
+            try {
+                PublicKey key = InternalUtil.logKeyToPublicKey(KnownLogs.LOG_KEYS[i]);
+
+                logs[i] = new CTLogInfo(key,
+                                        KnownLogs.LOG_DESCRIPTIONS[i],
+                                        KnownLogs.LOG_URLS[i]);
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        defaultFallbackLogs = logs;
+        return logs;
+    }
+
+    /**
+     * Load a CTLogInfo from a file.
+     * @throws FileNotFoundException if the file does not exist
+     * @throws InvalidLogFileException if the file could not be parsed properly
+     * @return a CTLogInfo or null if the file is empty
+     */
+    public static CTLogInfo loadLog(File file) throws FileNotFoundException,
+                                                      InvalidLogFileException {
+        return loadLog(new FileInputStream(file));
+    }
+
+    /**
+     * Load a CTLogInfo from a textual representation. Closes {@code input} upon completion
+     * of loading.
+     *
+     * @throws InvalidLogFileException if the input could not be parsed properly
+     * @return a CTLogInfo or null if the input is empty
+     */
+    public static CTLogInfo loadLog(InputStream input) throws InvalidLogFileException {
+        final Scanner scan = new Scanner(input, "UTF-8");
+        scan.useDelimiter("\n");
+
+        String description = null;
+        String url = null;
+        String key = null;
+        try {
+            // If the scanner can't even read one token then the file must be empty/blank
+            if (!scan.hasNext()) {
+                return null;
+            }
+
+            while (scan.hasNext()) {
+                String[] parts = scan.next().split(":", 2);
+                if (parts.length < 2) {
+                    continue;
+                }
+
+                String name = parts[0];
+                String value = parts[1];
+                switch (name) {
+                    case "description":
+                        description = value;
+                        break;
+                    case "url":
+                        url = value;
+                        break;
+                    case "key":
+                        key = value;
+                        break;
+                }
+            }
+        } finally {
+            scan.close();
+        }
+
+        if (description == null || url == null || key == null) {
+            throw new InvalidLogFileException("Missing one of 'description', 'url' or 'key'");
+        }
+
+        PublicKey pubkey;
+        try {
+            pubkey = InternalUtil.readPublicKeyPem(new ByteArrayInputStream(
+                    ("-----BEGIN PUBLIC KEY-----\n" +
+                        key + "\n" +
+                        "-----END PUBLIC KEY-----").getBytes(US_ASCII)));
+        } catch (InvalidKeyException e) {
+            throw new InvalidLogFileException(e);
+        } catch (NoSuchAlgorithmException e) {
+            throw new InvalidLogFileException(e);
+        }
+
+        return new CTLogInfo(pubkey, description, url);
+    }
+
+    private final static char[] HEX_DIGITS = new char[] {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    private static String hexEncode(byte[] data) {
+        StringBuilder sb = new StringBuilder(data.length * 2);
+        for (byte b: data) {
+            sb.append(HEX_DIGITS[(b >> 4) & 0x0f]);
+            sb.append(HEX_DIGITS[b & 0x0f]);
+        }
+        return sb.toString();
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTPolicyImpl.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTPolicyImpl.java
new file mode 100644
index 0000000..4e19318
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/CTPolicyImpl.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public class CTPolicyImpl implements CTPolicy {
+    private final CTLogStore logStore;
+    private final int minimumLogCount;
+
+    public CTPolicyImpl(CTLogStore logStore, int minimumLogCount) {
+        this.logStore = logStore;
+        this.minimumLogCount = minimumLogCount;
+    }
+
+    @Override
+    public boolean doesResultConformToPolicy(CTVerificationResult result, String hostname,
+                                             X509Certificate[] chain) {
+        Set<CTLogInfo> logSet = new HashSet();
+        for (VerifiedSCT verifiedSCT: result.getValidSCTs()) {
+            CTLogInfo log = logStore.getKnownLog(verifiedSCT.sct.getLogID());
+            if (log != null) {
+                logSet.add(log);
+            }
+        }
+
+        return logSet.size() >= minimumLogCount;
+    }
+}
diff --git a/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/KnownLogs.java b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/KnownLogs.java
new file mode 100644
index 0000000..7d6dca1
--- /dev/null
+++ b/repackaged/platform/src/main/java/com/android/org/conscrypt/ct/KnownLogs.java
@@ -0,0 +1,138 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/* This file is generated by print_log_list.py
+ * https://github.com/google/certificate-transparency/blob/master/python/utilities/log_list/print_log_list.py */
+
+package com.android.org.conscrypt.ct;
+
+import com.android.org.conscrypt.Internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+@Internal
+public final class KnownLogs {
+    public static final int LOG_COUNT = 8;
+    public static final String[] LOG_DESCRIPTIONS = new String[] {
+        "Google 'Pilot' log",
+        "Google 'Aviator' log",
+        "DigiCert Log Server",
+        "Google 'Rocketeer' log",
+        "Certly.IO log",
+        "Izenpe log",
+        "Symantec log",
+        "Venafi log",
+    };
+    public static final String[] LOG_URLS = new String[] {
+        "ct.googleapis.com/pilot",
+        "ct.googleapis.com/aviator",
+        "ct1.digicert-ct.com/log",
+        "ct.googleapis.com/rocketeer",
+        "log.certly.io",
+        "ct.izenpe.com",
+        "ct.ws.symantec.com",
+        "ctlog.api.venafi.com",
+    };
+    public static final byte[][] LOG_KEYS = new byte[][] {
+        // Google 'Pilot' log
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, 125, -88, 75, 18, 41, -128, -93, 61, -83,
+            -45, 90, 119, -72, -52, -30, -120, -77, -91, -3, -15, -45, 12, -51, 24,
+            12, -24, 65, 70, -24, -127, 1, 27, 21, -31, 75, -15, 27, 98, -35, 54, 10,
+            8, 24, -70, -19, 11, 53, -124, -48, -98, 64, 60, 45, -98, -101, -126,
+            101, -67, 31, 4, 16, 65, 76, -96
+        },
+        // Google 'Aviator' log
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, -41, -12, -52, 105, -78, -28, 14, -112,
+            -93, -118, -22, 90, 112, 9, 79, -17, 19, 98, -48, -115, 73, 96, -1, 27,
+            64, 80, 7, 12, 109, 113, -122, -38, 37, 73, -115, 101, -31, 8, 13, 71,
+            52, 107, -67, 39, -68, -106, 33, 62, 52, -11, -121, 118, 49, -79, 127,
+            29, -55, -123, 59, 13, -9, 31, 63, -23
+        },
+        // DigiCert Log Server
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, 2, 70, -59, -66, 27, -69, -126, 64, 22,
+            -24, -63, -46, -84, 25, 105, 19, 89, -8, -8, 112, -123, 70, 64, -71, 56,
+            -80, 35, -126, -88, 100, 76, 127, -65, -69, 52, -97, 74, 95, 40, -118,
+            -49, 25, -60, 0, -10, 54, 6, -109, 101, -19, 76, -11, -87, 33, 98, 90,
+            -40, -111, -21, 56, 36, 64, -84, -24
+        },
+        // Google 'Rocketeer' log
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, 32, 91, 24, -56, 60, -63, -117, -77, 49,
+            8, 0, -65, -96, -112, 87, 43, -73, 71, -116, 111, -75, 104, -80, -114,
+            -112, 120, -23, -96, 115, -22, 79, 40, 33, 46, -100, -64, -12, 22, 27,
+            -86, -7, -43, -41, -87, -128, -61, 78, 47, 82, 60, -104, 1, 37, 70, 36,
+            37, 40, 35, 119, 45, 5, -62, 64, 122
+        },
+        // Certly.IO log
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, 11, 35, -53, -123, 98, -104, 97, 72, 4,
+            115, -21, 84, 93, -13, -48, 7, -116, 45, 25, 45, -116, 54, -11, -21,
+            -113, 1, 66, 10, 124, -104, 38, 39, -63, -75, -35, -110, -109, -80, -82,
+            -8, -101, 61, 12, -40, 76, 78, 29, -7, 21, -5, 71, 104, 123, -70, 102,
+            -73, 37, -100, -48, 74, -62, 102, -37, 72
+        },
+        // Izenpe log
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, 39, 100, 57, 12, 45, -36, 80, 24, -8, 33,
+            0, -94, 14, -19, 44, -22, 62, 117, -70, -97, -109, 100, 9, 0, 17, -60,
+            17, 23, -85, 92, -49, 15, 116, -84, -75, -105, -112, -109, 0, 91, -72,
+            -21, -9, 39, 61, -39, -78, 10, -127, 95, 47, 13, 117, 56, -108, 55, -103,
+            30, -10, 7, 118, -32, -18, -66
+        },
+        // Symantec log
+        new byte[] {
+            48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72,
+            -50, 61, 3, 1, 7, 3, 66, 0, 4, -106, -22, -84, 28, 70, 12, 27, 85, -36,
+            13, -4, -75, -108, 39, 70, 87, 66, 112, 58, 105, 24, -30, -65, 59, -60,
+            -37, -85, -96, -12, -74, 108, -64, 83, 63, 77, 66, 16, 51, -16, 88, -105,
+            -113, 107, -66, 114, -12, 42, -20, 28, 66, -86, 3, 47, 26, 126, 40, 53,
+            118, -103, 8, 61, 33, 20, -122
+        },
+        // Venafi log
+        new byte[] {
+            48, -126, 1, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0,
+            3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -94, 90, 72, 31,
+            23, 82, -107, 53, -53, -93, 91, 58, 31, 83, -126, 118, -108, -93, -1,
+            -128, -14, 28, 55, 60, -64, -79, -67, -63, 89, -117, -85, 45, 101, -109,
+            -41, -13, -32, 4, -43, -102, 111, -65, -42, 35, 118, 54, 79, 35, -103,
+            -53, 84, 40, -83, -116, 21, 75, 101, 89, 118, 65, 74, -100, -90, -9, -77,
+            59, 126, -79, -91, 73, -92, 23, 81, 108, -128, -36, 42, -112, 80, 75,
+            -120, 36, -23, -91, 18, 50, -109, 4, 72, -112, 2, -6, 95, 14, 48, -121,
+            -114, 85, 118, 5, -18, 42, 76, -50, -93, 106, 105, 9, 110, 37, -83, -126,
+            118, 15, -124, -110, -6, 56, -42, -122, 78, 36, -113, -101, -80, 114,
+            -53, -98, -30, 107, 63, -31, 109, -55, 37, 117, 35, -120, -95, 24, 88, 6,
+            35, 51, 120, -38, 0, -48, 56, -111, 103, -46, -90, 125, 39, -105, 103,
+            90, -63, -13, 47, 23, -26, -22, -46, 91, -24, -127, -51, -3, -110, 104,
+            -25, -13, 6, -16, -23, 114, -124, -18, 1, -91, -79, -40, 51, -38, -50,
+            -125, -91, -37, -57, -49, -42, 22, 126, -112, 117, 24, -65, 22, -36, 50,
+            59, 109, -115, -85, -126, 23, 31, -119, 32, -115, 29, -102, -26, 77, 35,
+            8, -33, 120, 111, -58, 5, -65, 95, -82, -108, -105, -37, 95, 100, -44,
+            -18, 22, -117, -93, -124, 108, 113, 43, -15, -85, 127, 93, 13, 50, -18,
+            4, -30, -112, -20, 65, -97, -5, 57, -63, 2, 3, 1, 0, 1
+        },
+    };
+}
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlacklistTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlacklistTest.java
new file mode 100644
index 0000000..454ac30
--- /dev/null
+++ b/repackaged/platform/src/test/java/com/android/org/conscrypt/CertBlacklistTest.java
@@ -0,0 +1,127 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.org.conscrypt;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import javax.net.ssl.X509TrustManager;
+import junit.framework.TestCase;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CertBlacklistTest extends TestCase {
+
+    private static final String BLACKLIST_CA = "test_blacklist_ca.pem";
+    private static final String BLACKLISTED_CHAIN = "blacklist_test_chain.pem";
+    private static final String BLACKLIST_FALLBACK_VALID_CA = "blacklist_test_valid_ca.pem";
+    private static final String BLACKLISTED_VALID_CHAIN = "blacklist_test_valid_chain.pem";
+
+    /**
+     * Ensure that the test blacklisted CA is actually blacklisted by default.
+     */
+    public void testBlacklistedPublicKey() throws Exception {
+        X509Certificate blacklistedCa = loadCertificate(BLACKLIST_CA);
+        CertBlacklist blacklist = CertBlacklistImpl.getDefault();
+        assertTrue(blacklist.isPublicKeyBlackListed(blacklistedCa.getPublicKey()));
+    }
+
+    /**
+     * Check that the blacklisted CA is rejected even if it used as a root of trust
+     */
+    public void testBlacklistedCaUntrusted() throws Exception {
+        X509Certificate blacklistedCa = loadCertificate(BLACKLIST_CA);
+        assertUntrusted(new X509Certificate[] {blacklistedCa}, getTrustManager(blacklistedCa));
+    }
+
+    /**
+     * Check that a chain that is rooted in a blacklisted trusted CA is rejected.
+     */
+    public void testBlacklistedRootOfTrust() throws Exception {
+        // Chain is leaf -> blacklisted
+        X509Certificate[] chain = loadCertificates(BLACKLISTED_CHAIN);
+        X509Certificate blacklistedCa = loadCertificate(BLACKLIST_CA);
+        assertUntrusted(chain, getTrustManager(blacklistedCa));
+    }
+
+    /** Test that the path building correctly routes around a blacklisted cert where there are
+     * other valid paths available. This prevents breakage where a cert was cross signed by a
+     * blacklisted CA but is still valid due to also being cross signed by CAs that remain trusted.
+     * Path:
+     *
+     * leaf -> intermediate -> blacklisted_ca
+     *               \
+     *                -------> trusted_ca
+     */
+    public void testBlacklistedIntermediateFallback() throws Exception {
+        X509Certificate[] chain = loadCertificates(BLACKLISTED_VALID_CHAIN);
+        X509Certificate blacklistedCa = loadCertificate(BLACKLIST_CA);
+        X509Certificate validCa = loadCertificate(BLACKLIST_FALLBACK_VALID_CA);
+        assertTrusted(chain, getTrustManager(blacklistedCa, validCa));
+        // Check that without the trusted_ca the chain is invalid (since it only chains to a
+        // blacklisted ca)
+        assertUntrusted(chain, getTrustManager(blacklistedCa));
+    }
+
+    private static X509Certificate loadCertificate(String file) throws Exception {
+        return loadCertificates(file)[0];
+    }
+
+    private static X509Certificate[] loadCertificates(String file) throws Exception {
+        CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        try (InputStream is = TestUtils.openTestFile(file)) {
+            Collection<? extends Certificate> collection = factory.generateCertificates(is);
+            is.close();
+            X509Certificate[] certs = new X509Certificate[collection.size()];
+            int i = 0;
+            for (Certificate cert : collection) {
+                certs[i++] = (X509Certificate) cert;
+            }
+            return certs;
+        }
+    }
+
+    private static TrustManagerImpl getTrustManager(X509Certificate... trustedCas)
+            throws Exception {
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        ks.load(null);
+        int i = 0;
+        for (X509Certificate ca : trustedCas) {
+            ks.setCertificateEntry(String.valueOf(i++), ca);
+        }
+        return new TrustManagerImpl(ks);
+    }
+
+    private static void assertTrusted(X509Certificate[] certs, X509TrustManager tm)
+            throws Exception {
+        tm.checkServerTrusted(certs, "RSA");
+    }
+
+    private static void assertUntrusted(X509Certificate[] certs, X509TrustManager tm) {
+        try {
+            tm.checkServerTrusted(certs, "RSA");
+            fail();
+        } catch (CertificateException expected) {
+        }
+    }
+}
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java
new file mode 100644
index 0000000..6ca624f
--- /dev/null
+++ b/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java
@@ -0,0 +1,987 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2011 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 com.android.org.conscrypt;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStore.TrustedCertificateEntry;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.security.auth.x500.X500Principal;
+import junit.framework.TestCase;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TrustedCertificateStoreTest extends TestCase {
+    private static final Random tempFileRandom = new Random();
+
+    private final File dirTest = new File(System.getProperty("java.io.tmpdir", "."),
+            "cert-store-test" + tempFileRandom.nextInt());
+    private final File dirSystem = new File(dirTest, "system");
+    private final File dirAdded = new File(dirTest, "added");
+    private final File dirDeleted = new File(dirTest, "removed");
+
+    private static X509Certificate CA1;
+    private static X509Certificate CA2;
+
+    private static KeyStore.PrivateKeyEntry PRIVATE;
+    private static X509Certificate[] CHAIN;
+
+    private static X509Certificate CA3_WITH_CA1_SUBJECT;
+    private static String ALIAS_SYSTEM_CA1;
+    private static String ALIAS_SYSTEM_CA2;
+    private static String ALIAS_USER_CA1;
+    private static String ALIAS_USER_CA2;
+
+    private static String ALIAS_SYSTEM_CHAIN0;
+    private static String ALIAS_SYSTEM_CHAIN1;
+    private static String ALIAS_SYSTEM_CHAIN2;
+    private static String ALIAS_USER_CHAIN0;
+    private static String ALIAS_USER_CHAIN1;
+    private static String ALIAS_USER_CHAIN2;
+
+    private static String ALIAS_SYSTEM_CA3;
+    private static String ALIAS_SYSTEM_CA3_COLLISION;
+    private static String ALIAS_USER_CA3;
+    private static String ALIAS_USER_CA3_COLLISION;
+
+    private static X509Certificate CERTLOOP_EE;
+    private static X509Certificate CERTLOOP_CA1;
+    private static X509Certificate CERTLOOP_CA2;
+    private static String ALIAS_USER_CERTLOOP_EE;
+    private static String ALIAS_USER_CERTLOOP_CA1;
+    private static String ALIAS_USER_CERTLOOP_CA2;
+
+    private static X509Certificate MULTIPLE_ISSUERS_CA1;
+    private static X509Certificate MULTIPLE_ISSUERS_CA1_CROSS;
+    private static X509Certificate MULTIPLE_ISSUERS_CA2;
+    private static X509Certificate MULTIPLE_ISSUERS_EE;
+    private static String ALIAS_MULTIPLE_ISSUERS_CA1;
+    private static String ALIAS_MULTIPLE_ISSUERS_CA1_CROSS;
+    private static String ALIAS_MULTIPLE_ISSUERS_CA2;
+    private static String ALIAS_MULTIPLE_ISSUERS_EE;
+
+    private static X509Certificate getCa1() {
+        initCerts();
+        return CA1;
+    }
+    private static X509Certificate getCa2() {
+        initCerts();
+        return CA2;
+    }
+
+    private static KeyStore.PrivateKeyEntry getPrivate() {
+        initCerts();
+        return PRIVATE;
+    }
+    private static X509Certificate[] getChain() {
+        initCerts();
+        return CHAIN;
+    }
+
+    private static X509Certificate getCa3WithCa1Subject() {
+        initCerts();
+        return CA3_WITH_CA1_SUBJECT;
+    }
+
+    private static String getAliasSystemCa1() {
+        initCerts();
+        return ALIAS_SYSTEM_CA1;
+    }
+    private static String getAliasSystemCa2() {
+        initCerts();
+        return ALIAS_SYSTEM_CA2;
+    }
+    private static String getAliasUserCa1() {
+        initCerts();
+        return ALIAS_USER_CA1;
+    }
+    private static String getAliasUserCa2() {
+        initCerts();
+        return ALIAS_USER_CA2;
+    }
+
+    private static String getAliasSystemChain0() {
+        initCerts();
+        return ALIAS_SYSTEM_CHAIN0;
+    }
+    private static String getAliasSystemChain1() {
+        initCerts();
+        return ALIAS_SYSTEM_CHAIN1;
+    }
+    private static String getAliasSystemChain2() {
+        initCerts();
+        return ALIAS_SYSTEM_CHAIN2;
+    }
+    private static String getAliasUserChain0() {
+        initCerts();
+        return ALIAS_USER_CHAIN0;
+    }
+    private static String getAliasUserChain1() {
+        initCerts();
+        return ALIAS_USER_CHAIN1;
+    }
+    private static String getAliasUserChain2() {
+        initCerts();
+        return ALIAS_USER_CHAIN2;
+    }
+
+    private static String getAliasSystemCa3() {
+        initCerts();
+        return ALIAS_SYSTEM_CA3;
+    }
+    private static String getAliasSystemCa3Collision() {
+        initCerts();
+        return ALIAS_SYSTEM_CA3_COLLISION;
+    }
+    private static String getAliasUserCa3() {
+        initCerts();
+        return ALIAS_USER_CA3;
+    }
+    private static String getAliasUserCa3Collision() {
+        initCerts();
+        return ALIAS_USER_CA3_COLLISION;
+    }
+    private static X509Certificate getCertLoopEe() {
+        initCerts();
+        return CERTLOOP_EE;
+    }
+    private static X509Certificate getCertLoopCa1() {
+        initCerts();
+        return CERTLOOP_CA1;
+    }
+    private static X509Certificate getCertLoopCa2() {
+        initCerts();
+        return CERTLOOP_CA2;
+    }
+    private static String getAliasCertLoopEe() {
+        initCerts();
+        return ALIAS_USER_CERTLOOP_EE;
+    }
+    private static String getAliasCertLoopCa1() {
+        initCerts();
+        return ALIAS_USER_CERTLOOP_CA1;
+    }
+    private static String getAliasCertLoopCa2() {
+        initCerts();
+        return ALIAS_USER_CERTLOOP_CA2;
+    }
+    private static String getAliasMultipleIssuersCa1() {
+        initCerts();
+        return ALIAS_MULTIPLE_ISSUERS_CA1;
+    }
+    private static String getAliasMultipleIssuersCa2() {
+        initCerts();
+        return ALIAS_MULTIPLE_ISSUERS_CA2;
+    }
+    private static String getAliasMultipleIssuersCa1Cross() {
+        initCerts();
+        return ALIAS_MULTIPLE_ISSUERS_CA1_CROSS;
+    }
+    private static String getAliasMultipleIssuersEe() {
+        initCerts();
+        return ALIAS_MULTIPLE_ISSUERS_EE;
+    }
+    private static X509Certificate getMultipleIssuersCa1() {
+        initCerts();
+        return MULTIPLE_ISSUERS_CA1;
+    }
+    private static X509Certificate getMultipleIssuersCa2() {
+        initCerts();
+        return MULTIPLE_ISSUERS_CA2;
+    }
+    private static X509Certificate getMultipleIssuersCa1Cross() {
+        initCerts();
+        return MULTIPLE_ISSUERS_CA1_CROSS;
+    }
+    private static X509Certificate getMultipleIssuersEe() {
+        initCerts();
+        return MULTIPLE_ISSUERS_EE;
+    }
+
+    /**
+     * Lazily create shared test certificates.
+     */
+    private static synchronized void initCerts() {
+        if (CA1 != null) {
+            return;
+        }
+        try {
+            CA1 = TestKeyStore.getClient().getRootCertificate("RSA");
+            CA2 = TestKeyStore.getClientCA2().getRootCertificate("RSA");
+            PRIVATE = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+            CHAIN = (X509Certificate[]) PRIVATE.getCertificateChain();
+            CA3_WITH_CA1_SUBJECT = new TestKeyStore.Builder()
+                    .aliasPrefix("unused")
+                    .subject(CA1.getSubjectX500Principal())
+                    .ca(true)
+                    .build().getRootCertificate("RSA");
+
+
+            ALIAS_SYSTEM_CA1 = alias(false, CA1, 0);
+            ALIAS_SYSTEM_CA2 = alias(false, CA2, 0);
+            ALIAS_USER_CA1 = alias(true, CA1, 0);
+            ALIAS_USER_CA2 = alias(true, CA2, 0);
+
+            ALIAS_SYSTEM_CHAIN0 = alias(false, getChain()[0], 0);
+            ALIAS_SYSTEM_CHAIN1 = alias(false, getChain()[1], 0);
+            ALIAS_SYSTEM_CHAIN2 = alias(false, getChain()[2], 0);
+            ALIAS_USER_CHAIN0 = alias(true, getChain()[0], 0);
+            ALIAS_USER_CHAIN1 = alias(true, getChain()[1], 0);
+            ALIAS_USER_CHAIN2 = alias(true, getChain()[2], 0);
+
+            ALIAS_SYSTEM_CA3 = alias(false, CA3_WITH_CA1_SUBJECT, 0);
+            ALIAS_SYSTEM_CA3_COLLISION = alias(false, CA3_WITH_CA1_SUBJECT, 1);
+            ALIAS_USER_CA3 = alias(true, CA3_WITH_CA1_SUBJECT, 0);
+            ALIAS_USER_CA3_COLLISION = alias(true, CA3_WITH_CA1_SUBJECT, 1);
+
+            /*
+             * The construction below is to build a certificate chain that has a loop
+             * in it:
+             *
+             *   EE ---> CA1 ---> CA2 ---+
+             *            ^              |
+             *            |              |
+             *            +--------------+
+             */
+            TestKeyStore certLoopTempCa1 = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("certloop-ca1")
+                    .subject("CN=certloop-ca1")
+                    .ca(true)
+                    .build();
+            Certificate certLoopTempCaCert1 = ((TrustedCertificateEntry) certLoopTempCa1
+                    .getEntryByAlias("certloop-ca1-public-RSA")).getTrustedCertificate();
+            PrivateKeyEntry certLoopCaKey1 = (PrivateKeyEntry) certLoopTempCa1
+                    .getEntryByAlias("certloop-ca1-private-RSA");
+
+            TestKeyStore certLoopCa2 = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("certloop-ca2")
+                    .subject("CN=certloop-ca2")
+                    .rootCa(certLoopTempCaCert1)
+                    .signer(certLoopCaKey1)
+                    .ca(true)
+                    .build();
+            CERTLOOP_CA2 = (X509Certificate) ((TrustedCertificateEntry) certLoopCa2
+                    .getEntryByAlias("certloop-ca2-public-RSA")).getTrustedCertificate();
+            ALIAS_USER_CERTLOOP_CA2 = alias(true, CERTLOOP_CA2, 0);
+            PrivateKeyEntry certLoopCaKey2 = (PrivateKeyEntry) certLoopCa2
+                    .getEntryByAlias("certloop-ca2-private-RSA");
+
+            TestKeyStore certLoopCa1 = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("certloop-ca1")
+                    .subject("CN=certloop-ca1")
+                    .privateEntry(certLoopCaKey1)
+                    .rootCa(CERTLOOP_CA2)
+                    .signer(certLoopCaKey2)
+                    .ca(true)
+                    .build();
+            CERTLOOP_CA1 = (X509Certificate) ((TrustedCertificateEntry) certLoopCa1
+                    .getEntryByAlias("certloop-ca1-public-RSA")).getTrustedCertificate();
+            ALIAS_USER_CERTLOOP_CA1 = alias(true, CERTLOOP_CA1, 0);
+
+            TestKeyStore certLoopEe = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("certloop-ee")
+                    .subject("CN=certloop-ee")
+                    .rootCa(CERTLOOP_CA1)
+                    .signer(certLoopCaKey1)
+                    .build();
+            CERTLOOP_EE = (X509Certificate) ((TrustedCertificateEntry) certLoopEe
+                    .getEntryByAlias("certloop-ee-public-RSA")).getTrustedCertificate();
+            ALIAS_USER_CERTLOOP_EE = alias(true, CERTLOOP_EE, 0);
+
+            /*
+             * The construction below creates a certificate with multiple possible issuer certs.
+             *
+             *    EE ----> CA1 ---> CA2
+             *
+             *    Where CA1 also exists in a self-issued form.
+             */
+            TestKeyStore multipleIssuersCa1 = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("multiple-issuers-ca1")
+                    .subject("CN=multiple-issuers-ca1")
+                    .ca(true)
+                    .build();
+            MULTIPLE_ISSUERS_CA1 = (X509Certificate) ((TrustedCertificateEntry) multipleIssuersCa1
+                    .getEntryByAlias("multiple-issuers-ca1-public-RSA")).getTrustedCertificate();
+            ALIAS_MULTIPLE_ISSUERS_CA1 = alias(false, MULTIPLE_ISSUERS_CA1, 0);
+            PrivateKeyEntry multipleIssuersCa1Key = (PrivateKeyEntry) multipleIssuersCa1
+                    .getEntryByAlias("multiple-issuers-ca1-private-RSA");
+
+            TestKeyStore multipleIssuersCa2 = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("multiple-issuers-ca2")
+                    .subject("CN=multiple-issuers-ca2")
+                    .ca(true)
+                    .build();
+            MULTIPLE_ISSUERS_CA2 = (X509Certificate) ((TrustedCertificateEntry) multipleIssuersCa2
+                    .getEntryByAlias("multiple-issuers-ca2-public-RSA")).getTrustedCertificate();
+            ALIAS_MULTIPLE_ISSUERS_CA2 = alias(false, MULTIPLE_ISSUERS_CA2, 0);
+            PrivateKeyEntry multipleIssuersCa2Key = (PrivateKeyEntry) multipleIssuersCa2
+                    .getEntryByAlias("multiple-issuers-ca2-private-RSA");
+
+            TestKeyStore multipleIssuersCa1SignedByCa2 = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("multiple-issuers-ca1")
+                    .subject("CN=multiple-issuers-ca1")
+                    .privateEntry(multipleIssuersCa1Key)
+                    .rootCa(MULTIPLE_ISSUERS_CA2)
+                    .signer(multipleIssuersCa2Key)
+                    .ca(true)
+                    .build();
+            MULTIPLE_ISSUERS_CA1_CROSS =
+                    (X509Certificate) ((TrustedCertificateEntry) multipleIssuersCa1SignedByCa2
+                            .getEntryByAlias("multiple-issuers-ca1-public-RSA"))
+                    .getTrustedCertificate();
+            ALIAS_MULTIPLE_ISSUERS_CA1_CROSS = alias(false, MULTIPLE_ISSUERS_CA1_CROSS, 1);
+
+            TestKeyStore multipleIssuersEe = new TestKeyStore.Builder()
+                    .keyAlgorithms("RSA")
+                    .aliasPrefix("multiple-issuers-ee")
+                    .subject("CN=multiple-issuers-ee")
+                    .rootCa(MULTIPLE_ISSUERS_CA1)
+                    .signer(multipleIssuersCa1Key)
+                    .build();
+            MULTIPLE_ISSUERS_EE = (X509Certificate) ((TrustedCertificateEntry) multipleIssuersEe
+                    .getEntryByAlias("multiple-issuers-ee-public-RSA")).getTrustedCertificate();
+            ALIAS_MULTIPLE_ISSUERS_EE = alias(false, MULTIPLE_ISSUERS_EE, 0);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private TrustedCertificateStore store;
+
+    @Override protected void setUp() {
+        setupStore();
+    }
+
+    private void setupStore() {
+        dirSystem.mkdirs();
+        cleanStore();
+        createStore();
+    }
+
+    private void createStore() {
+        store = new TrustedCertificateStore(dirSystem, dirAdded, dirDeleted);
+    }
+
+    @Override protected void tearDown() {
+        cleanStore();
+    }
+
+    private void cleanStore() {
+        for (File dir : new File[] { dirSystem, dirAdded, dirDeleted, dirTest }) {
+            File[] files = dir.listFiles();
+            if (files == null) {
+                continue;
+            }
+            for (File file : files) {
+                assertTrue("Should delete " + file.getPath(), file.delete());
+            }
+        }
+        store = null;
+    }
+
+    private void resetStore() {
+        cleanStore();
+        setupStore();
+    }
+
+    public void testEmptyDirectories() throws Exception {
+        assertEmpty();
+    }
+
+    public void testOneSystemOneDeleted() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasSystemCa1());
+    }
+
+    public void testTwoSystemTwoDeleted() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        install(getCa2(), getAliasSystemCa2());
+        store.deleteCertificateEntry(getAliasSystemCa2());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasSystemCa1());
+        assertDeleted(getCa2(), getAliasSystemCa2());
+    }
+
+    public void testPartialFileIsIgnored() throws Exception {
+        File file = file(getAliasSystemCa1());
+        file.getParentFile().mkdirs();
+        OutputStream os = new FileOutputStream(file);
+        os.write(0);
+        os.close();
+        assertTrue(file.exists());
+        assertEmpty();
+        assertTrue(file.exists());
+    }
+
+    private void assertEmpty() throws Exception {
+        try {
+            store.getCertificate(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        assertNull(store.getCertificate(""));
+
+        try {
+            store.getCreationDate(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        assertNull(store.getCreationDate(""));
+
+        Set<String> s = store.aliases();
+        assertNotNull(s);
+        assertTrue(s.isEmpty());
+        assertAliases();
+
+        Set<String> u = store.userAliases();
+        assertNotNull(u);
+        assertTrue(u.isEmpty());
+
+        try {
+            store.containsAlias(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        assertFalse(store.containsAlias(""));
+
+        assertNull(store.getCertificateAlias(null));
+        assertNull(store.getCertificateAlias(getCa1()));
+
+        try {
+            store.getTrustAnchor(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        assertNull(store.getTrustAnchor(getCa1()));
+
+        try {
+            store.findIssuer(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        assertNull(store.findIssuer(getCa1()));
+
+        try {
+            store.installCertificate(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        store.deleteCertificateEntry(null);
+        store.deleteCertificateEntry("");
+
+        String[] userFiles = dirAdded.list();
+        assertTrue(userFiles == null || userFiles.length == 0);
+    }
+
+    public void testTwoSystem() throws Exception {
+        testTwo(getCa1(), getAliasSystemCa1(),
+                getCa2(), getAliasSystemCa2());
+    }
+
+    public void testTwoUser() throws Exception {
+        testTwo(getCa1(), getAliasUserCa1(),
+                getCa2(), getAliasUserCa2());
+    }
+
+    public void testOneSystemOneUser() throws Exception {
+        testTwo(getCa1(), getAliasSystemCa1(),
+                getCa2(), getAliasUserCa2());
+    }
+
+    public void testTwoSystemSameSubject() throws Exception {
+        testTwo(getCa1(), getAliasSystemCa1(),
+                getCa3WithCa1Subject(), getAliasSystemCa3Collision());
+    }
+
+    public void testTwoUserSameSubject() throws Exception {
+        testTwo(getCa1(), getAliasUserCa1(),
+                getCa3WithCa1Subject(), getAliasUserCa3Collision());
+
+        store.deleteCertificateEntry(getAliasUserCa1());
+        assertDeleted(getCa1(), getAliasUserCa1());
+        assertTombstone(getAliasUserCa1());
+        assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3Collision());
+        assertAliases(getAliasUserCa3Collision());
+
+        store.deleteCertificateEntry(getAliasUserCa3Collision());
+        assertDeleted(getCa3WithCa1Subject(), getAliasUserCa3Collision());
+        assertNoTombstone(getAliasUserCa3Collision());
+        assertNoTombstone(getAliasUserCa1());
+        assertEmpty();
+    }
+
+    public void testOneSystemOneUserSameSubject() throws Exception {
+        testTwo(getCa1(), getAliasSystemCa1(),
+                getCa3WithCa1Subject(), getAliasUserCa3());
+        testTwo(getCa1(), getAliasUserCa1(),
+                getCa3WithCa1Subject(), getAliasSystemCa3());
+    }
+
+    private void testTwo(X509Certificate x1, String alias1,
+                         X509Certificate x2, String alias2) {
+        install(x1, alias1);
+        install(x2, alias2);
+        assertRootCa(x1, alias1);
+        assertRootCa(x2, alias2);
+        assertAliases(alias1, alias2);
+    }
+
+
+    public void testOneSystemOneUserOneDeleted() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        store.installCertificate(getCa2());
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertDeleted(getCa1(), getAliasSystemCa1());
+        assertRootCa(getCa2(), getAliasUserCa2());
+        assertAliases(getAliasUserCa2());
+    }
+
+    public void testOneSystemOneUserOneDeletedSameSubject() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        store.installCertificate(getCa3WithCa1Subject());
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertDeleted(getCa1(), getAliasSystemCa1());
+        assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3());
+        assertAliases(getAliasUserCa3());
+    }
+
+    public void testUserMaskingSystem() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        install(getCa1(), getAliasUserCa1());
+        assertMasked(getCa1(), getAliasSystemCa1());
+        assertRootCa(getCa1(), getAliasUserCa1());
+        assertAliases(getAliasSystemCa1(), getAliasUserCa1());
+    }
+
+    public void testChain() throws Exception {
+        testChain(getAliasSystemChain1(), getAliasSystemChain2());
+        testChain(getAliasSystemChain1(), getAliasUserChain2());
+        testChain(getAliasUserChain1(), getAliasSystemCa1());
+        testChain(getAliasUserChain1(), getAliasUserChain2());
+    }
+
+    private void testChain(String alias1, String alias2) throws Exception {
+        install(getChain()[1], alias1);
+        install(getChain()[2], alias2);
+        assertIntermediateCa(getChain()[1], alias1);
+        assertRootCa(getChain()[2], alias2);
+        assertAliases(alias1, alias2);
+        assertEquals(getChain()[2], store.findIssuer(getChain()[1]));
+        assertEquals(getChain()[1], store.findIssuer(getChain()[0]));
+
+        X509Certificate[] expected = getChain();
+        List<X509Certificate> actualList = store.getCertificateChain(expected[0]);
+
+        assertEquals("Generated CA list should be same length", expected.length, actualList.size());
+        for (int i = 0; i < expected.length; i++) {
+            assertEquals("Chain value should be the same for position " + i, expected[i],
+                    actualList.get(i));
+        }
+        resetStore();
+    }
+
+    public void testMissingSystemDirectory() throws Exception {
+        cleanStore();
+        createStore();
+        assertEmpty();
+    }
+
+    public void testWithExistingUserDirectories() throws Exception {
+        dirAdded.mkdirs();
+        dirDeleted.mkdirs();
+        install(getCa1(), getAliasSystemCa1());
+        assertRootCa(getCa1(), getAliasSystemCa1());
+        assertAliases(getAliasSystemCa1());
+    }
+
+    public void testIsTrustAnchorWithReissuedgetCa() throws Exception {
+        PublicKey publicKey = getPrivate().getCertificate().getPublicKey();
+        PrivateKey privateKey = getPrivate().getPrivateKey();
+        String name = "CN=CA4";
+        X509Certificate ca1 = TestKeyStore.createCa(publicKey, privateKey, name);
+        Thread.sleep(1 * 1000); // wait to ensure CAs vary by expiration
+        X509Certificate ca2 = TestKeyStore.createCa(publicKey, privateKey, name);
+        assertFalse(ca1.equals(ca2));
+
+        String systemAlias = alias(false, ca1, 0);
+        install(ca1, systemAlias);
+        assertRootCa(ca1, systemAlias);
+        assertEquals(ca1, store.getTrustAnchor(ca2));
+        assertEquals(ca1, store.findIssuer(ca2));
+        resetStore();
+
+        String userAlias = alias(true, ca1, 0);
+        store.installCertificate(ca1);
+        assertRootCa(ca1, userAlias);
+        assertNotNull(store.getTrustAnchor(ca2));
+        assertEquals(ca1, store.findIssuer(ca2));
+        resetStore();
+    }
+
+    public void testInstallEmpty() throws Exception {
+        store.installCertificate(getCa1());
+        assertRootCa(getCa1(), getAliasUserCa1());
+        assertAliases(getAliasUserCa1());
+
+        // reinstalling should not change anything
+        store.installCertificate(getCa1());
+        assertRootCa(getCa1(), getAliasUserCa1());
+        assertAliases(getAliasUserCa1());
+    }
+
+    public void testInstallEmptySystemExists() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        assertRootCa(getCa1(), getAliasSystemCa1());
+        assertAliases(getAliasSystemCa1());
+
+        // reinstalling should not affect system CA
+        store.installCertificate(getCa1());
+        assertRootCa(getCa1(), getAliasSystemCa1());
+        assertAliases(getAliasSystemCa1());
+
+    }
+
+    public void testInstallEmptyDeletedSystemExists() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasSystemCa1());
+
+        // installing should restore deleted system CA
+        store.installCertificate(getCa1());
+        assertRootCa(getCa1(), getAliasSystemCa1());
+        assertAliases(getAliasSystemCa1());
+    }
+
+    public void testDeleteEmpty() throws Exception {
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasSystemCa1());
+    }
+
+    public void testDeleteUser() throws Exception {
+        store.installCertificate(getCa1());
+        assertRootCa(getCa1(), getAliasUserCa1());
+        assertAliases(getAliasUserCa1());
+
+        store.deleteCertificateEntry(getAliasUserCa1());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasUserCa1());
+        assertNoTombstone(getAliasUserCa1());
+    }
+
+    public void testDeleteSystem() throws Exception {
+        install(getCa1(), getAliasSystemCa1());
+        assertRootCa(getCa1(), getAliasSystemCa1());
+        assertAliases(getAliasSystemCa1());
+
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasSystemCa1());
+
+        // deleting again should not change anything
+        store.deleteCertificateEntry(getAliasSystemCa1());
+        assertEmpty();
+        assertDeleted(getCa1(), getAliasSystemCa1());
+    }
+
+    public void testGetLoopedCert() throws Exception {
+        install(getCertLoopEe(), getAliasCertLoopEe());
+        install(getCertLoopCa1(), getAliasCertLoopCa1());
+        install(getCertLoopCa2(), getAliasCertLoopCa2());
+
+        ExecutorService executor = Executors.newSingleThreadExecutor();
+        Future<List<X509Certificate>> future = executor
+                .submit(new Callable<List<X509Certificate>>() {
+                    @Override
+                    public List<X509Certificate> call() throws Exception {
+                        return store.getCertificateChain(getCertLoopEe());
+                    }
+                });
+        executor.shutdown();
+        final List<X509Certificate> certs;
+        try {
+            certs = future.get(10, TimeUnit.SECONDS);
+        } catch (TimeoutException e) {
+            fail("Could not finish building chain; possibly confused by loops");
+            return; // Not actually reached.
+        }
+        assertEquals(3, certs.size());
+        assertEquals(getCertLoopEe(), certs.get(0));
+        assertEquals(getCertLoopCa1(), certs.get(1));
+        assertEquals(getCertLoopCa2(), certs.get(2));
+    }
+
+    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()));
+    }
+
+    public void testSystemCaCertsUseCorrectFileNames() throws Exception {
+        TrustedCertificateStore store = new TrustedCertificateStore();
+
+        // Assert that all the certificates in the system cacerts directory are stored in files with
+        // expected names.
+        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+        File dir = new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
+        int systemCertFileCount = 0;
+        for (File actualFile : listFilesNoNull(dir)) {
+            if (!actualFile.isFile()) {
+                continue;
+            }
+            systemCertFileCount++;
+            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(
+                    new ByteArrayInputStream(readFully(actualFile)));
+
+            File expectedFile = store.getCertificateFile(dir, cert);
+            assertEquals("System certificate stored in the wrong file",
+                    expectedFile.getAbsolutePath(), actualFile.getAbsolutePath());
+
+            // The two statements below indirectly assert that the certificate can be looked up
+            // from a file (hopefully the same one as the expectedFile above). As opposed to
+            // getCertifiacteFile above, these are the actual methods used when verifying chain of
+            // trust. Thus, we assert that they work as expected for all system certificates.
+            assertNotNull("Issuer certificate not found for system certificate " + actualFile,
+                    store.findIssuer(cert));
+            assertNotNull("Trust anchor not found for system certificate " + actualFile,
+                    store.getTrustAnchor(cert));
+        }
+
+        // Assert that all files corresponding to all system certs/aliases known to the store are
+        // present.
+        int systemCertAliasCount = 0;
+        for (String alias : store.aliases()) {
+            if (!TrustedCertificateStore.isSystem(alias)) {
+                continue;
+            }
+            systemCertAliasCount++;
+            // Checking that the certificate is stored in a file is extraneous given the current
+            // implementation of the class under test. We do it just in case the implementation
+            // changes.
+            X509Certificate cert = (X509Certificate) store.getCertificate(alias);
+            File expectedFile = store.getCertificateFile(dir, cert);
+            if (!expectedFile.isFile()) {
+                fail("Missing certificate file for alias " + alias
+                        + ": " + expectedFile.getAbsolutePath());
+            }
+        }
+
+        assertEquals("Number of system cert files and aliases doesn't match",
+                systemCertFileCount, systemCertAliasCount);
+    }
+
+    public void testMultipleIssuers() throws Exception {
+        Set<X509Certificate> result;
+        install(getMultipleIssuersCa1(), getAliasMultipleIssuersCa1());
+        result = store.findAllIssuers(getMultipleIssuersEe());
+        assertEquals("Unexpected number of issuers found", 1, result.size());
+        assertTrue("findAllIssuers does not contain expected issuer",
+                result.contains(getMultipleIssuersCa1()));
+        install(getMultipleIssuersCa1Cross(), getAliasMultipleIssuersCa1Cross());
+        result = store.findAllIssuers(getMultipleIssuersEe());
+        assertEquals("findAllIssuers did not return all issuers", 2, result.size());
+        assertTrue("findAllIssuers does not contain CA1",
+                result.contains(getMultipleIssuersCa1()));
+        assertTrue("findAllIssuers does not contain CA1 signed by CA2",
+                result.contains(getMultipleIssuersCa1Cross()));
+    }
+
+    private static File[] listFilesNoNull(File dir) {
+        File[] files = dir.listFiles();
+        return (files != null) ? files : new File[0];
+    }
+
+    private static byte[] readFully(File file) throws IOException {
+        InputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            byte[] buf = new byte[16384];
+            int chunkSize;
+            while ((chunkSize = in.read(buf)) != -1) {
+                out.write(buf, 0, chunkSize);
+            }
+            return out.toByteArray();
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+        }
+    }
+
+    private void assertRootCa(X509Certificate x, String alias) {
+        assertIntermediateCa(x, alias);
+        assertEquals(x, store.findIssuer(x));
+    }
+
+    private void assertTrusted(X509Certificate x, String alias) {
+        assertEquals(x, store.getCertificate(alias));
+        assertEquals(file(alias).lastModified(), store.getCreationDate(alias).getTime());
+        assertTrue(store.containsAlias(alias));
+        assertEquals(x, store.getTrustAnchor(x));
+    }
+
+    private void assertIntermediateCa(X509Certificate x, String alias) {
+        assertTrusted(x, alias);
+        assertEquals(alias, store.getCertificateAlias(x));
+    }
+
+    private void assertMasked(X509Certificate x, String alias) {
+        assertTrusted(x, alias);
+        assertFalse(alias.equals(store.getCertificateAlias(x)));
+    }
+
+    private void assertDeleted(X509Certificate x, String alias) {
+        assertNull(store.getCertificate(alias));
+        assertFalse(store.containsAlias(alias));
+        assertNull(store.getCertificateAlias(x));
+        assertNull(store.getTrustAnchor(x));
+        assertEquals(store.allSystemAliases().contains(alias),
+                     store.getCertificate(alias, true) != null);
+    }
+
+    private void assertTombstone(String alias) {
+        assertTrue(TrustedCertificateStore.isUser(alias));
+        File file = file(alias);
+        assertTrue(file.exists());
+        assertEquals(0, file.length());
+    }
+
+    private void assertNoTombstone(String alias) {
+        assertTrue(TrustedCertificateStore.isUser(alias));
+        assertFalse(file(alias).exists());
+    }
+
+    private void assertAliases(String... aliases) {
+        Set<String> expected = new HashSet<String>(Arrays.asList(aliases));
+        Set<String> actual = new HashSet<String>();
+        for (String alias : store.aliases()) {
+            boolean system = TrustedCertificateStore.isSystem(alias);
+            boolean user = TrustedCertificateStore.isUser(alias);
+            if (system || user) {
+                assertEquals(system, store.allSystemAliases().contains(alias));
+                assertEquals(user, store.userAliases().contains(alias));
+                actual.add(alias);
+            } else {
+                throw new AssertionError(alias);
+            }
+        }
+        assertEquals(expected, actual);
+    }
+
+    /**
+     * format a certificate alias
+     */
+    private static String alias(boolean user, X509Certificate x, int index) {
+        String prefix = user ? "user:" : "system:";
+
+        X500Principal subject = x.getSubjectX500Principal();
+        int intHash = NativeCrypto.X509_NAME_hash_old(subject);
+        String strHash = Hex.intToHexString(intHash, 8);
+
+        return prefix + strHash + '.' + index;
+    }
+
+    /**
+     * Install certificate under specified alias
+     */
+    private void install(X509Certificate x, String alias) {
+        try {
+            File file = file(alias);
+            file.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(file);
+            out.write(x.getEncoded());
+            out.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Compute file for an alias
+     */
+    private File file(String alias) {
+        File dir;
+        if (TrustedCertificateStore.isSystem(alias)) {
+            dir = dirSystem;
+        } else if (TrustedCertificateStore.isUser(alias)) {
+            dir = dirAdded;
+        } else {
+            throw new IllegalArgumentException(alias);
+        }
+
+        int index = alias.lastIndexOf(":");
+        if (index == -1) {
+            throw new IllegalArgumentException(alias);
+        }
+        String filename = alias.substring(index+1);
+
+        return new File(dir, filename);
+    }
+}
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
new file mode 100644
index 0000000..606c099
--- /dev/null
+++ b/repackaged/platform/src/test/java/com/android/org/conscrypt/ct/CTLogStoreImplTest.java
@@ -0,0 +1,205 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt.ct;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringBufferInputStream;
+import java.security.PublicKey;
+import junit.framework.TestCase;
+import com.android.org.conscrypt.InternalUtil;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CTLogStoreImplTest extends TestCase {
+    private static final String[] LOG_KEYS = new String[] {
+        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3U" +
+        "yEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w==",
+
+        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErEULmlBnX9L/+AK20hLYzPMFozYx" +
+        "pP0Wm1ylqGkPEwuDKn9DSpNSOym49SN77BLGuAXu9twOW/qT+ddIYVBEIw==",
+
+        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEP6PGcXmjlyCBz2ZFUuUjrgbZLaEF" +
+        "gfLUkt2cEqlSbb4vTuB6WWmgC9h0L6PN6JF0CPcajpBKGlTI15242a8d4g==",
+
+        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER3qB0NADsP1szXxe4EagrD/ryPVh" +
+        "Y/azWbKyXcK12zhXnO8WH2U4QROVUMctFXLflIzw0EivdRN9t7UH1Od30w==",
+
+        "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY0ww9JqeJvzVtKNTPVb3JZa7s0ZV" +
+        "duH3PpshpMS5XVoPRSjSQCph6f3HjUcM3c4N2hpa8OFbrFFy37ttUrgD+A=="
+    };
+    private static final String[] LOG_FILENAMES = new String[] {
+        "df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d764",
+        "84f8ae3f613b13407a75fa2893b93ab03b18d86c455fe7c241ae020033216446",
+        "89baa01a445100009d8f9a238947115b30702275aafee675a7d94b6b09287619",
+        "57456bffe268e49a190dce4318456034c2b4958f3c0201bed5a366737d1e74ca",
+        "896c898ced4b8e6547fa351266caae4ca304f1c1ec2b623c2ee259c5452147b0"
+    };
+
+    private static final CTLogInfo[] LOGS;
+    private static final String[] LOGS_SERIALIZED;
+
+    static {
+        try {
+            int logCount = LOG_KEYS.length;
+            LOGS = new CTLogInfo[logCount];
+            LOGS_SERIALIZED = new String[logCount];
+            for (int i = 0; i < logCount; i++) {
+                PublicKey key = InternalUtil.readPublicKeyPem(new StringBufferInputStream(
+                    "-----BEGIN PUBLIC KEY-----\n" +
+                    LOG_KEYS[i] + "\n" +
+                    "-----END PUBLIC KEY-----\n"));
+                String description = String.format("Test Log %d", i);
+                String url = String.format("log%d.example.com", i);
+                LOGS[i] = new CTLogInfo(key, description, url);
+                LOGS_SERIALIZED[i] = String.format("description:%s\nurl:%s\nkey:%s",
+                    description, url, LOG_KEYS[i]);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* CTLogStoreImpl loads the list of logs lazily when they are first needed
+     * to avoid any overhead when CT is disabled.
+     * This test simply forces the logs to be loaded to make sure it doesn't
+     * fail, as all of the other tests use a different log store.
+     */
+    public void test_getDefaultFallbackLogs() {
+        CTLogInfo[] knownLogs = CTLogStoreImpl.getDefaultFallbackLogs();
+        assertEquals(KnownLogs.LOG_COUNT, knownLogs.length);
+    }
+
+    public void test_loadLog() throws Exception {
+        CTLogInfo log = CTLogStoreImpl.loadLog(new StringBufferInputStream(LOGS_SERIALIZED[0]));
+        assertEquals(LOGS[0], log);
+
+        File testFile = writeFile(LOGS_SERIALIZED[0]);
+        log = CTLogStoreImpl.loadLog(testFile);
+        assertEquals(LOGS[0], log);
+
+        // Empty log file, used to mask fallback logs
+        assertEquals(null, CTLogStoreImpl.loadLog(new StringBufferInputStream("")));
+        try {
+            CTLogStoreImpl.loadLog(new StringBufferInputStream("randomgarbage"));
+            fail("InvalidLogFileException not thrown");
+        } catch (CTLogStoreImpl.InvalidLogFileException e) {}
+
+        try {
+            CTLogStoreImpl.loadLog(new File("/nonexistent"));
+            fail("FileNotFoundException not thrown");
+        } catch (FileNotFoundException e) {}
+    }
+
+    public void test_getKnownLog() throws Exception {
+        File userDir = createTempDirectory();
+        userDir.deleteOnExit();
+
+        File systemDir = createTempDirectory();
+        systemDir.deleteOnExit();
+
+        CTLogInfo[] fallback = new CTLogInfo[] { LOGS[2], LOGS[3] };
+
+        CTLogStore store = new CTLogStoreImpl(userDir, systemDir, fallback);
+
+        /* Add logs 0 and 1 to the user and system directories respectively
+         * Log 2 & 3 are part of the fallbacks
+         * But mask log 3 with an empty file in the user directory.
+         * Log 4 is not in the store
+         */
+        File log0File = new File(userDir, LOG_FILENAMES[0]);
+        File log1File = new File(systemDir, LOG_FILENAMES[1]);
+        File log3File = new File(userDir, LOG_FILENAMES[3]);
+        File log4File = new File(userDir, LOG_FILENAMES[4]);
+
+        writeFile(log0File, LOGS_SERIALIZED[0]);
+        writeFile(log1File, LOGS_SERIALIZED[1]);
+        writeFile(log3File, "");
+
+        // Logs 01 are present, log 2 is in the fallback and unused, log 3 is present but masked,
+        // log 4 is missing
+        assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
+        assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
+        // Fallback logs are not used if the userDir is present.
+        assertEquals(null, store.getKnownLog(LOGS[2].getID()));
+        assertEquals(null, store.getKnownLog(LOGS[3].getID()));
+        assertEquals(null, store.getKnownLog(LOGS[4].getID()));
+
+        /* Test whether CTLogStoreImpl caches properly
+         * Modify the files on the disk, the result of the store should not change
+         * Delete log 0, mask log 1, add log 4
+         */
+        log0File.delete();
+        writeFile(log1File, "");
+        writeFile(log4File, LOGS_SERIALIZED[4]);
+
+        assertEquals(LOGS[0], store.getKnownLog(LOGS[0].getID()));
+        assertEquals(LOGS[1], store.getKnownLog(LOGS[1].getID()));
+        assertEquals(null, store.getKnownLog(LOGS[4].getID()));
+
+        // Test that fallback logs are used when the userDir doesn't exist.
+        File doesntExist = new File("/doesnt/exist/");
+        store = new CTLogStoreImpl(doesntExist, doesntExist, fallback);
+        assertEquals(LOGS[2], store.getKnownLog(LOGS[2].getID()));
+        assertEquals(LOGS[3], store.getKnownLog(LOGS[3].getID()));
+    }
+
+    /**
+     * Create a temporary file and write to it.
+     * The file will be deleted on exit.
+     * @param contents The data to be written to the file
+     * @return A reference to the temporary file
+     */
+    private File writeFile(String contents) throws IOException {
+        File file = File.createTempFile("test", null);
+        file.deleteOnExit();
+        writeFile(file, contents);
+        return file;
+    }
+
+    private static void writeFile(File file, String contents) throws FileNotFoundException {
+        PrintWriter writer = new PrintWriter(
+                new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF_8)),
+                false);
+        try {
+            writer.write(contents);
+        } finally {
+            writer.close();
+        }
+    }
+
+    /*
+     * This is NOT safe, as another process could create a file between delete() and mkdir()
+     * It should be fine for tests though
+     */
+    private static File createTempDirectory() throws IOException {
+        File folder = File.createTempFile("test", "");
+        folder.delete();
+        folder.mkdir();
+        return folder;
+    }
+}
+
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java
new file mode 100644
index 0000000..a1a77c1
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/ChannelType.java
@@ -0,0 +1,132 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2017 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * The type of socket to be wrapped by the Conscrypt socket.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("unused")
+public enum ChannelType {
+    NONE {
+        @Override
+        SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+                throws IOException {
+            return clientMode(factory.createSocket(address, port));
+        }
+
+        @Override
+        ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException {
+            return factory.createServerSocket(0, 50, InetAddress.getLoopbackAddress());
+        }
+
+        @Override
+        SSLSocket accept(ServerSocket socket, SSLSocketFactory unused) throws IOException {
+            return serverMode(socket.accept());
+        }
+    },
+    NO_CHANNEL {
+        @Override
+        SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+                throws IOException {
+            Socket wrapped = new Socket(address, port);
+            assertNull(wrapped.getChannel());
+
+            return clientMode(factory.createSocket(wrapped, address.getHostName(), port, true));
+        }
+
+        @Override
+        ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
+            return ServerSocketFactory.getDefault().createServerSocket(
+                    0, 50, InetAddress.getLoopbackAddress());
+        }
+
+        @Override
+        SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
+            assertFalse(serverSocket instanceof SSLServerSocket);
+            Socket wrapped = serverSocket.accept();
+            assertNull(wrapped.getChannel());
+
+            return serverMode(factory.createSocket(
+                    wrapped, wrapped.getInetAddress().getHostAddress(), wrapped.getPort(), true));
+        }
+    },
+    CHANNEL {
+        @Override
+        SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+                throws IOException {
+            Socket wrapped = SocketChannel.open(new InetSocketAddress(address, port)).socket();
+            return clientMode(factory.createSocket(wrapped, address.getHostName(), port, true));
+        }
+
+        @Override
+        ServerSocket newServerSocket(SSLServerSocketFactory unused) throws IOException {
+            return ServerSocketChannel.open()
+                    .bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0))
+                    .socket();
+        }
+
+        @Override
+        SSLSocket accept(ServerSocket serverSocket, SSLSocketFactory factory) throws IOException {
+            assertFalse(serverSocket instanceof SSLServerSocket);
+            ServerSocketChannel serverChannel = serverSocket.getChannel();
+
+            // Just loop until the accept completes.
+            SocketChannel channel;
+            do {
+                channel = serverChannel.accept();
+            } while (channel == null);
+
+            Socket wrapped = channel.socket();
+            return serverMode(factory.createSocket(
+                    wrapped, wrapped.getInetAddress().getHostAddress(), wrapped.getPort(), true));
+        }
+    };
+
+    abstract SSLSocket newClientSocket(SSLSocketFactory factory, InetAddress address, int port)
+            throws IOException;
+    abstract ServerSocket newServerSocket(SSLServerSocketFactory factory) throws IOException;
+    abstract SSLSocket accept(ServerSocket socket, SSLSocketFactory factory) throws IOException;
+
+    private static SSLSocket clientMode(Socket socket) {
+        SSLSocket sslSocket = (SSLSocket) socket;
+        sslSocket.setUseClientMode(true);
+        return sslSocket;
+    }
+
+    private static SSLSocket serverMode(Socket socket) {
+        SSLSocket sslSocket = (SSLSocket) socket;
+        sslSocket.setUseClientMode(false);
+        return sslSocket;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java
new file mode 100644
index 0000000..0545d77
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java
@@ -0,0 +1,704 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.org.conscrypt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+import com.android.org.conscrypt.testing.Streams;
+import org.junit.Assume;
+
+/**
+ * Utility methods to support testing.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestUtils {
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+    private static final String PROTOCOL_TLS_V1_2 = "TLSv1.2";
+    private static final String PROTOCOL_TLS_V1_1 = "TLSv1.1";
+    private static final String PROTOCOL_TLS_V1 = "TLSv1";
+    private static final String[] DESIRED_PROTOCOLS =
+        new String[] {PROTOCOL_TLS_V1_2, PROTOCOL_TLS_V1_1, /* For Java 6 */ PROTOCOL_TLS_V1};
+    private static final Provider JDK_PROVIDER = getDefaultTlsProvider();
+    private static final byte[] CHARS =
+            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".getBytes(UTF_8);
+    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocateDirect(0);
+    private static final String[] PROTOCOLS = getProtocolsInternal();
+
+    static final String TEST_CIPHER = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+
+    private TestUtils() {}
+
+    private static Provider getDefaultTlsProvider() {
+        for (String protocol : DESIRED_PROTOCOLS) {
+            for (Provider p : Security.getProviders()) {
+                if (hasProtocol(p, protocol)) {
+                    return p;
+                }
+            }
+        }
+        // For Java 1.6 testing
+        return new BouncyCastleProvider();
+    }
+
+    private static boolean hasProtocol(Provider p, String protocol) {
+        return p.get("SSLContext." + protocol) != null;
+    }
+
+    static Provider getJdkProvider() {
+        return JDK_PROVIDER;
+    }
+
+    public static boolean isClassAvailable(String classname) {
+        try {
+            Class.forName(classname);
+            return true;
+        } catch (ClassNotFoundException ignore) {
+            // Ignored
+        }
+        return false;
+    }
+
+    private static void assumeClassAvailable(String classname) {
+        Assume.assumeTrue("Skipping test: " + classname + " unavailable",
+                isClassAvailable(classname));
+    }
+
+    public static void assumeSNIHostnameAvailable() {
+        assumeClassAvailable("javax.net.ssl.SNIHostName");
+    }
+
+    public static void assumeExtendedTrustManagerAvailable() {
+        assumeClassAvailable("javax.net.ssl.X509ExtendedTrustManager");
+    }
+
+    public static void assumeSetEndpointIdentificationAlgorithmAvailable() {
+        boolean supported = false;
+        try {
+            SSLParameters.class.getMethod("setEndpointIdentificationAlgorithm", String.class);
+            supported = true;
+        } catch (NoSuchMethodException ignore) {
+            // Ignored
+        }
+        Assume.assumeTrue("Skipping test: "
+                + "SSLParameters.setEndpointIdentificationAlgorithm unavailable", supported);
+    }
+
+    public static void assumeAEADAvailable() {
+        assumeClassAvailable("javax.crypto.AEADBadTagException");
+    }
+
+    private static boolean isAndroid() {
+        try {
+            Class.forName("android.app.Application", false, ClassLoader.getSystemClassLoader());
+            return true;
+        } catch (Throwable ignored) {
+            // Failed to load the class uniquely available in Android.
+            return false;
+        }
+    }
+
+    public static void assumeAndroid() {
+        Assume.assumeTrue(isAndroid());
+    }
+
+    public static void assumeAllowsUnsignedCrypto() {
+        // The Oracle JRE disallows loading crypto providers from unsigned jars
+        Assume.assumeTrue(isAndroid()
+                || !System.getProperty("java.vm.name").contains("HotSpot"));
+    }
+
+    public static void assumeSHA2WithDSAAvailable() {
+        boolean available;
+        try {
+            Signature.getInstance("SHA256withDSA");
+            available = true;
+        } catch (NoSuchAlgorithmException e) {
+            available = false;
+        }
+        Assume.assumeTrue("SHA2 with DSA signatures not available", available);
+    }
+
+    public static InetAddress getLoopbackAddress() {
+        try {
+            Method method = InetAddress.class.getMethod("getLoopbackAddress");
+            return (InetAddress) method.invoke(null);
+        } catch (Exception ignore) {
+            // Ignored.
+        }
+        try {
+            return InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static Provider getConscryptProvider() {
+        try {
+            String defaultName = (String) conscryptClass("Platform")
+                .getDeclaredMethod("getDefaultProviderName")
+                .invoke(null);
+            Constructor<?> c = conscryptClass("OpenSSLProvider")
+                .getDeclaredConstructor(String.class, Boolean.TYPE);
+
+            if (!isClassAvailable("javax.net.ssl.X509ExtendedTrustManager")) {
+                return (Provider) c.newInstance(defaultName, false);
+            } else {
+                return (Provider) c.newInstance(defaultName, true);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static synchronized boolean installConscryptIfNotPresent() {
+        Provider conscryptProvider = getConscryptProvider();
+        if (Security.getProvider(conscryptProvider.getName()) == null) {
+            Security.insertProviderAt(conscryptProvider, 1);
+            return true;
+        }
+        return false;
+    }
+
+    public static synchronized void installConscryptAsDefaultProvider() {
+        final Provider conscryptProvider = getConscryptProvider();
+        Provider[] providers = Security.getProviders();
+        if (providers.length == 0 || !providers[0].equals(conscryptProvider)) {
+            Security.insertProviderAt(conscryptProvider, 1);
+        }
+    }
+
+    public static InputStream openTestFile(String name) throws FileNotFoundException {
+        InputStream is = TestUtils.class.getResourceAsStream("/" + name);
+        if (is == null) {
+            throw new FileNotFoundException(name);
+        }
+        return is;
+    }
+
+    public static byte[] readTestFile(String name) throws IOException {
+        return Streams.readFully(openTestFile(name));
+    }
+
+    public static PublicKey readPublicKeyPemFile(String name)
+            throws InvalidKeySpecException, NoSuchAlgorithmException, IOException {
+        String keyData = new String(readTestFile(name), "US-ASCII");
+        keyData = keyData.replace("-----BEGIN PUBLIC KEY-----", "");
+        keyData = keyData.replace("-----END PUBLIC KEY-----", "");
+        keyData = keyData.replace("\r", "");
+        keyData = keyData.replace("\n", "");
+        return KeyFactory.getInstance("EC").generatePublic(
+                new X509EncodedKeySpec(decodeBase64(keyData)));
+    }
+
+    /**
+     * Looks up the conscrypt class for the given simple name (i.e. no package prefix).
+     */
+    public static Class<?> conscryptClass(String simpleName) throws ClassNotFoundException {
+        ClassNotFoundException ex = null;
+        for (String packageName : new String[] {"com.android.org.conscrypt", "com.android.com.android.org.conscrypt"}) {
+            String name = packageName + "." + simpleName;
+            try {
+                return Class.forName(name);
+            } catch (ClassNotFoundException e) {
+                ex = e;
+            }
+        }
+        throw ex;
+    }
+
+    /**
+     * Returns an array containing only {@link #PROTOCOL_TLS_V1_2}.
+     */
+    public static String[] getProtocols() {
+        return PROTOCOLS;
+    }
+
+    private static String[] getProtocolsInternal() {
+        List<String> protocols = new ArrayList<String>();
+        for (String protocol : DESIRED_PROTOCOLS) {
+            if (hasProtocol(getJdkProvider(), protocol)) {
+                protocols.add(protocol);
+            }
+        }
+        return protocols.toArray(new String[protocols.size()]);
+    }
+
+    public static SSLSocketFactory getJdkSocketFactory() {
+        return getSocketFactory(JDK_PROVIDER);
+    }
+
+    public static SSLServerSocketFactory getJdkServerSocketFactory() {
+        return getServerSocketFactory(JDK_PROVIDER);
+    }
+
+    static SSLSocketFactory setUseEngineSocket(
+            SSLSocketFactory conscryptFactory, boolean useEngineSocket) {
+        try {
+            Class<?> clazz = conscryptClass("Conscrypt");
+            Method method =
+                    clazz.getMethod("setUseEngineSocket", SSLSocketFactory.class, boolean.class);
+            method.invoke(null, conscryptFactory, useEngineSocket);
+            return conscryptFactory;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static SSLServerSocketFactory setUseEngineSocket(
+            SSLServerSocketFactory conscryptFactory, boolean useEngineSocket) {
+        try {
+            Class<?> clazz = conscryptClass("Conscrypt");
+            Method method = clazz.getMethod(
+                    "setUseEngineSocket", SSLServerSocketFactory.class, boolean.class);
+            method.invoke(null, conscryptFactory, useEngineSocket);
+            return conscryptFactory;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void setUseSessionTickets(SSLSocket socket, boolean useTickets) {
+        try {
+            Class<?> clazz = conscryptClass("Conscrypt");
+            Method method = clazz.getMethod("setUseSessionTickets", SSLSocket.class, boolean.class);
+            method.invoke(null, socket, useTickets);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static SSLSocketFactory getConscryptSocketFactory(boolean useEngineSocket) {
+        return setUseEngineSocket(getSocketFactory(getConscryptProvider()), useEngineSocket);
+    }
+
+    public static SSLServerSocketFactory getConscryptServerSocketFactory(boolean useEngineSocket) {
+        return setUseEngineSocket(getServerSocketFactory(getConscryptProvider()), useEngineSocket);
+    }
+
+    private static SSLSocketFactory getSocketFactory(Provider provider) {
+        SSLContext clientContext = initClientSslContext(newContext(provider));
+        return clientContext.getSocketFactory();
+    }
+
+    private static SSLServerSocketFactory getServerSocketFactory(Provider provider) {
+        SSLContext serverContext = initServerSslContext(newContext(provider));
+        return serverContext.getServerSocketFactory();
+    }
+
+    static SSLContext newContext(Provider provider) {
+        try {
+            return SSLContext.getInstance("TLS", provider);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static String[] getCommonCipherSuites() {
+        SSLContext jdkContext =
+                TestUtils.initSslContext(newContext(getJdkProvider()), TestKeyStore.getClient());
+        SSLContext conscryptContext = TestUtils.initSslContext(
+                newContext(getConscryptProvider()), TestKeyStore.getClient());
+        Set<String> supported = new LinkedHashSet<String>();
+        supported.addAll(supportedCiphers(jdkContext));
+        supported.retainAll(supportedCiphers(conscryptContext));
+        filterCiphers(supported);
+
+        return supported.toArray(new String[supported.size()]);
+    }
+
+    private static List<String> supportedCiphers(SSLContext ctx) {
+        return Arrays.asList(ctx.getDefaultSSLParameters().getCipherSuites());
+    }
+
+    private static void filterCiphers(Iterable<String> ciphers) {
+        // Filter all non-TLS ciphers.
+        Iterator<String> iter = ciphers.iterator();
+        while (iter.hasNext()) {
+            String cipher = iter.next();
+            if (cipher.startsWith("SSL_") || cipher.startsWith("TLS_EMPTY")
+                    || cipher.contains("_RC4_")) {
+                iter.remove();
+            }
+        }
+    }
+
+    /**
+     * Picks a port that is not used right at this moment.
+     * Warning: Not thread safe. May see "BindException: Address already in use: bind" if using the
+     * returned port to create a new server socket when other threads/processes are concurrently
+     * creating new sockets without a specific port.
+     */
+    public static int pickUnusedPort() {
+        try {
+            ServerSocket serverSocket = new ServerSocket(0);
+            int port = serverSocket.getLocalPort();
+            serverSocket.close();
+            return port;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Creates a text message of the given length.
+     */
+    public static byte[] newTextMessage(int length) {
+        byte[] msg = new byte[length];
+        for (int msgIndex = 0; msgIndex < length;) {
+            int remaining = length - msgIndex;
+            int numChars = Math.min(remaining, CHARS.length);
+            System.arraycopy(CHARS, 0, msg, msgIndex, numChars);
+            msgIndex += numChars;
+        }
+        return msg;
+    }
+
+    static SSLContext newClientSslContext(Provider provider) {
+        SSLContext context = newContext(provider);
+        return initClientSslContext(context);
+    }
+
+    static SSLContext newServerSslContext(Provider provider) {
+        SSLContext context = newContext(provider);
+        return initServerSslContext(context);
+    }
+
+    /**
+     * Initializes the given client-side {@code context} with a default cert.
+     */
+    public static SSLContext initClientSslContext(SSLContext context) {
+        return initSslContext(context, TestKeyStore.getClient());
+    }
+
+    /**
+     * Initializes the given server-side {@code context} with the given cert chain and private key.
+     */
+    public static SSLContext initServerSslContext(SSLContext context) {
+        return initSslContext(context, TestKeyStore.getServer());
+    }
+
+    /**
+     * Initializes the given {@code context} from the {@code keyStore}.
+     */
+    static SSLContext initSslContext(SSLContext context, TestKeyStore keyStore) {
+        try {
+            context.init(keyStore.keyManagers, keyStore.trustManagers, null);
+            return context;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Performs the intial TLS handshake between the two {@link SSLEngine} instances.
+     */
+    public static void doEngineHandshake(SSLEngine clientEngine, SSLEngine serverEngine,
+        ByteBuffer clientAppBuffer, ByteBuffer clientPacketBuffer, ByteBuffer serverAppBuffer,
+        ByteBuffer serverPacketBuffer, boolean beginHandshake) throws SSLException {
+        if (beginHandshake) {
+            clientEngine.beginHandshake();
+            serverEngine.beginHandshake();
+        }
+
+        SSLEngineResult clientResult;
+        SSLEngineResult serverResult;
+
+        boolean clientHandshakeFinished = false;
+        boolean serverHandshakeFinished = false;
+
+        do {
+            int cTOsPos = clientPacketBuffer.position();
+            int sTOcPos = serverPacketBuffer.position();
+
+            clientResult = clientEngine.wrap(EMPTY_BUFFER, clientPacketBuffer);
+            runDelegatedTasks(clientResult, clientEngine);
+            serverResult = serverEngine.wrap(EMPTY_BUFFER, serverPacketBuffer);
+            runDelegatedTasks(serverResult, serverEngine);
+
+            // Verify that the consumed and produced number match what is in the buffers now.
+            assertEquals(0, clientResult.bytesConsumed());
+            assertEquals(0, serverResult.bytesConsumed());
+            assertEquals(clientPacketBuffer.position() - cTOsPos, clientResult.bytesProduced());
+            assertEquals(serverPacketBuffer.position() - sTOcPos, serverResult.bytesProduced());
+
+            clientPacketBuffer.flip();
+            serverPacketBuffer.flip();
+
+            // Verify that we only had one SSLEngineResult.HandshakeStatus.FINISHED
+            if (isHandshakeFinished(clientResult)) {
+                assertFalse(clientHandshakeFinished);
+                clientHandshakeFinished = true;
+            }
+            if (isHandshakeFinished(serverResult)) {
+                assertFalse(serverHandshakeFinished);
+                serverHandshakeFinished = true;
+            }
+
+            cTOsPos = clientPacketBuffer.position();
+            sTOcPos = serverPacketBuffer.position();
+
+            int clientAppReadBufferPos = clientAppBuffer.position();
+            int serverAppReadBufferPos = serverAppBuffer.position();
+
+            clientResult = clientEngine.unwrap(serverPacketBuffer, clientAppBuffer);
+            runDelegatedTasks(clientResult, clientEngine);
+            serverResult = serverEngine.unwrap(clientPacketBuffer, serverAppBuffer);
+            runDelegatedTasks(serverResult, serverEngine);
+
+            // Verify that the consumed and produced number match what is in the buffers now.
+            assertEquals(serverPacketBuffer.position() - sTOcPos, clientResult.bytesConsumed());
+            assertEquals(clientPacketBuffer.position() - cTOsPos, serverResult.bytesConsumed());
+            assertEquals(clientAppBuffer.position() - clientAppReadBufferPos,
+                clientResult.bytesProduced());
+            assertEquals(serverAppBuffer.position() - serverAppReadBufferPos,
+                serverResult.bytesProduced());
+
+            clientPacketBuffer.compact();
+            serverPacketBuffer.compact();
+
+            // Verify that we only had one SSLEngineResult.HandshakeStatus.FINISHED
+            if (isHandshakeFinished(clientResult)) {
+                assertFalse(clientHandshakeFinished);
+                clientHandshakeFinished = true;
+            }
+            if (isHandshakeFinished(serverResult)) {
+                assertFalse(serverHandshakeFinished);
+                serverHandshakeFinished = true;
+            }
+        } while (!clientHandshakeFinished || !serverHandshakeFinished);
+    }
+
+    private static boolean isHandshakeFinished(SSLEngineResult result) {
+        return result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED;
+    }
+
+    private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) {
+        if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
+            for (;;) {
+                Runnable task = engine.getDelegatedTask();
+                if (task == null) {
+                    break;
+                }
+                task.run();
+            }
+        }
+    }
+
+    public static String pickArbitraryNonTls13Suite(String[] cipherSuites) {
+        return pickArbitraryNonTls13Suite(Arrays.asList(cipherSuites));
+    }
+
+    public static String pickArbitraryNonTls13Suite(Iterable<String> cipherSuites) {
+        for (String cipherSuite : cipherSuites) {
+            if (!StandardNames.CIPHER_SUITES_TLS13.contains(cipherSuite)) {
+                return cipherSuite;
+            }
+        }
+        fail("No non-TLSv1.3 cipher suite available.");
+        return null;
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
+     * are not allowed.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decodeHex(String encoded) throws IllegalArgumentException {
+        return decodeHex(encoded.toCharArray());
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
+     * is {@code true} odd-length inputs are allowed and the first character is interpreted
+     * as the lower bits of the first result byte.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decodeHex(String encoded, boolean allowSingleChar) throws IllegalArgumentException {
+        return decodeHex(encoded.toCharArray(), allowSingleChar);
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
+     * are not allowed.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decodeHex(char[] encoded) throws IllegalArgumentException {
+        return decodeHex(encoded, false);
+    }
+
+    /**
+     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
+     * is {@code true} odd-length inputs are allowed and the first character is interpreted
+     * as the lower bits of the first result byte.
+     *
+     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     */
+    public static byte[] decodeHex(char[] encoded, boolean allowSingleChar) throws IllegalArgumentException {
+        int resultLengthBytes = (encoded.length + 1) / 2;
+        byte[] result = new byte[resultLengthBytes];
+
+        int resultOffset = 0;
+        int i = 0;
+        if (allowSingleChar) {
+            if ((encoded.length % 2) != 0) {
+                // Odd number of digits -- the first digit is the lower 4 bits of the first result byte.
+                result[resultOffset++] = (byte) toDigit(encoded, i);
+                i++;
+            }
+        } else {
+            if ((encoded.length % 2) != 0) {
+                throw new IllegalArgumentException("Invalid input length: " + encoded.length);
+            }
+        }
+
+        for (int len = encoded.length; i < len; i += 2) {
+            result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1));
+        }
+
+        return result;
+    }
+
+
+    private static int toDigit(char[] str, int offset) throws IllegalArgumentException {
+        // NOTE: that this isn't really a code point in the traditional sense, since we're
+        // just rejecting surrogate pairs outright.
+        int pseudoCodePoint = str[offset];
+
+        if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') {
+            return pseudoCodePoint - '0';
+        } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') {
+            return 10 + (pseudoCodePoint - 'a');
+        } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') {
+            return 10 + (pseudoCodePoint - 'A');
+        }
+
+        throw new IllegalArgumentException("Illegal char: " + str[offset] +
+                " at offset " + offset);
+    }
+
+    private static final String BASE64_ALPHABET =
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+    public static String encodeBase64(byte[] data) {
+        // Base64 was introduced in Java 8, so if it's not available we can use a hacky
+        // solution that works in previous versions
+        if (isClassAvailable("java.util.Base64")) {
+            return Base64.getEncoder().encodeToString(data);
+        } else {
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < data.length; i += 3) {
+                int padding = (i + 2 < data.length) ? 0 : (i + 3 - data.length);
+                byte b1 = data[i];
+                byte b2 = padding >= 2 ? 0 : data[i+1];
+                byte b3 = padding >= 1 ? 0 : data[i+2];
+
+                char c1 = BASE64_ALPHABET.charAt((b1 & 0xFF) >>> 2);
+                char c2 = BASE64_ALPHABET.charAt(((b1 & 0x03) << 4) | ((b2 & 0xFF) >>> 4));
+                char c3 = BASE64_ALPHABET.charAt(((b2 & 0x0F) << 2) | ((b3 & 0xFF) >>> 6));
+                char c4 = BASE64_ALPHABET.charAt(b3 & 0x3F);
+
+                if (padding >= 1) {
+                    c4 = '=';
+                }
+                if (padding >= 2) {
+                    c3 = '=';
+                }
+                builder.append(c1).append(c2).append(c3).append(c4);
+            }
+            return builder.toString();
+        }
+    }
+
+    public static byte[] decodeBase64(String data) {
+        // Base64 was introduced in Java 8, so if it's not available we can use a hacky
+        // solution that works in previous versions
+        if (isClassAvailable("java.util.Base64")) {
+            return Base64.getDecoder().decode(data);
+        } else {
+            while (data.endsWith("=")) {
+                data = data.substring(0, data.length() - 1);
+            }
+            int padding = (data.length() % 4 == 0) ? 0 : 4 - (data.length() % 4);
+            byte[] output = new byte[((data.length() - 1) / 4) * 3 + 3 - padding];
+            int outputindex = 0;
+            for (int i = 0; i < data.length(); i += 4) {
+                char c1 = data.charAt(i);
+                char c2 = data.charAt(i+1);
+                char c3 = (i+2 < data.length()) ? data.charAt(i+2) : 'A';
+                char c4 = (i+3 < data.length()) ? data.charAt(i+3) : 'A';
+
+                byte b1 = (byte)
+                        (BASE64_ALPHABET.indexOf(c1) << 2 | BASE64_ALPHABET.indexOf(c2) >>> 4);
+                byte b2 = (byte)
+                        ((BASE64_ALPHABET.indexOf(c2) & 0x0F) << 4 | BASE64_ALPHABET.indexOf(c3) >>> 2);
+                byte b3 = (byte)
+                        ((BASE64_ALPHABET.indexOf(c3) & 0x03) << 6 | BASE64_ALPHABET.indexOf(c4));
+
+                output[outputindex++] = b1;
+                if (outputindex < output.length) {
+                    output[outputindex++] = b2;
+                }
+                if (outputindex < output.length) {
+                    output[outputindex++] = b3;
+                }
+            }
+            return output;
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractAlgorithmParameterGeneratorTest.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractAlgorithmParameterGeneratorTest.java
new file mode 100644
index 0000000..cdbd7e8
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractAlgorithmParameterGeneratorTest.java
@@ -0,0 +1,47 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import org.junit.Test;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractAlgorithmParameterGeneratorTest {
+
+    private final String algorithmName;
+    private final TestHelper<AlgorithmParameters> helper;
+
+    protected AbstractAlgorithmParameterGeneratorTest(String algorithmName, TestHelper<AlgorithmParameters> helper) {
+        this.algorithmName = algorithmName;
+        this.helper = helper;
+    }
+
+    @Test
+    public void testAlgorithmParameterGenerator() throws Exception {
+        AlgorithmParameterGenerator generator = AlgorithmParameterGenerator.getInstance(algorithmName);
+        generator.init(1024);
+
+        AlgorithmParameters parameters = generator.generateParameters();
+        assertNotNull("generated parameters are null", parameters);
+        helper.test(parameters);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractAlgorithmParametersTest.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractAlgorithmParametersTest.java
new file mode 100644
index 0000000..9f2ea86
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractAlgorithmParametersTest.java
@@ -0,0 +1,45 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+import org.junit.Test;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractAlgorithmParametersTest {
+
+    private final String algorithmName;
+    private final TestHelper<AlgorithmParameters> helper;
+    private final AlgorithmParameterSpec parameterData;
+
+    public AbstractAlgorithmParametersTest(String algorithmName,
+            TestHelper<AlgorithmParameters> helper, AlgorithmParameterSpec parameterData) {
+        this.algorithmName = algorithmName;
+        this.helper = helper;
+        this.parameterData = parameterData;
+    }
+
+    @Test
+    public void testAlgorithmParameters() throws Exception {
+        AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance(algorithmName);
+        algorithmParameters.init(parameterData);
+        helper.test(algorithmParameters);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java
new file mode 100644
index 0000000..2f851c8
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.KeySpec;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractKeyFactoryTest<PublicKeySpec extends KeySpec, PrivateKeySpec extends KeySpec> {
+
+    private final String algorithmName;
+    private final Class<PublicKeySpec> publicKeySpecClass;
+    private final Class<PrivateKeySpec> privateKeySpecClass;
+    private KeyFactory factory;
+
+    public AbstractKeyFactoryTest(String algorithmName,
+            Class<PublicKeySpec> publicKeySpecClass,
+            Class<PrivateKeySpec> privateKeySpecClass) {
+        this.algorithmName = algorithmName;
+        this.publicKeySpecClass = publicKeySpecClass;
+        this.privateKeySpecClass = privateKeySpecClass;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        factory = getFactory();
+    }
+
+    private KeyFactory getFactory() throws Exception {
+        return KeyFactory.getInstance(algorithmName);
+    }
+
+    @Test
+    public void testKeyFactory() throws Exception {
+        PrivateKeySpec privateKeySpec = factory.getKeySpec(DefaultKeys.getPrivateKey(algorithmName),
+                                                           privateKeySpecClass);
+        PrivateKey privateKey =  factory.generatePrivate(privateKeySpec);
+        PublicKeySpec publicKeySpec = factory.getKeySpec(DefaultKeys.getPublicKey(algorithmName),
+                                                         publicKeySpecClass);
+        PublicKey publicKey = factory.generatePublic(publicKeySpec);
+        check(new KeyPair(publicKey, privateKey));
+    }
+
+    protected void check(KeyPair keyPair) throws Exception {}
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyPairGeneratorTest.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyPairGeneratorTest.java
new file mode 100644
index 0000000..f9ea7cf
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyPairGeneratorTest.java
@@ -0,0 +1,59 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2008 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class AbstractKeyPairGeneratorTest {
+
+    private final String algorithmName;
+    private final TestHelper<KeyPair> helper;
+
+    private KeyPairGenerator generator;
+
+    protected AbstractKeyPairGeneratorTest(String algorithmName, TestHelper<KeyPair> helper) {
+        this.algorithmName = algorithmName;
+        this.helper = helper;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        generator = KeyPairGenerator.getInstance(algorithmName);
+    }
+
+    @Test
+    public void testKeyPairGenerator() throws Exception {
+        generator.initialize(1024);
+
+        KeyPair keyPair = generator.generateKeyPair();
+
+        assertNotNull("no keypair generated", keyPair);
+        assertNotNull("no public key generated", keyPair.getPublic());
+        assertNotNull("no private key generated", keyPair.getPrivate());
+
+        helper.test(keyPair);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterAsymmetricHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterAsymmetricHelper.java
new file mode 100644
index 0000000..bbc6bd4
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterAsymmetricHelper.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.AlgorithmParameters;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.util.Arrays;
+import javax.crypto.Cipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParameterAsymmetricHelper extends TestHelper<AlgorithmParameters> {
+
+    private static final String plainData = "some data to encrypt and decrypt";
+    private final String algorithmName;
+
+    public AlgorithmParameterAsymmetricHelper(String algorithmName) {
+        this.algorithmName = algorithmName;
+    }
+
+    private String baseName() {
+        return algorithmName.contains("/")
+                ? algorithmName.substring(0, algorithmName.indexOf('/'))
+                : algorithmName;
+    }
+
+    @Override
+    public void test(AlgorithmParameters parameters) throws Exception {
+        KeyPairGenerator generator = KeyPairGenerator.getInstance(baseName());
+        generator.initialize(1024);
+        KeyPair keyPair = generator.generateKeyPair();
+
+        Cipher cipher = Cipher.getInstance(algorithmName);
+        cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), parameters);
+        byte[] bs = cipher.doFinal(plainData.getBytes("UTF-8"));
+
+        cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate(), parameters);
+        byte[] decrypted = cipher.doFinal(bs);
+        assertTrue(Arrays.equals(plainData.getBytes("UTF-8"), decrypted));
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterKeyAgreementHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterKeyAgreementHelper.java
new file mode 100644
index 0000000..5eba48e
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterKeyAgreementHelper.java
@@ -0,0 +1,49 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.security.AlgorithmParameters;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import javax.crypto.KeyAgreement;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParameterKeyAgreementHelper extends TestHelper<AlgorithmParameters> {
+
+    private final String algorithmName;
+
+    public AlgorithmParameterKeyAgreementHelper(String algorithmName) {
+        this.algorithmName = algorithmName;
+    }
+
+    @Override
+    public void test(AlgorithmParameters parameters) throws Exception {
+        KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithmName);
+        generator.initialize(1024);
+
+        KeyPair keyPair = generator.generateKeyPair();
+        KeyAgreement keyAgreement = KeyAgreement.getInstance(algorithmName);
+        keyAgreement.init(keyPair.getPrivate());
+        keyAgreement.doPhase(keyPair.getPublic(), true);
+        assertNotNull("generated secret is null", keyAgreement.generateSecret());
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterSignatureHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterSignatureHelper.java
new file mode 100644
index 0000000..f9d0898
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterSignatureHelper.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.AlgorithmParameters;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Signature;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParameterSignatureHelper<T extends AlgorithmParameterSpec>
+        extends TestHelper<AlgorithmParameters> {
+
+    private final String algorithmName;
+    private final String plainData = "some data do sign and verify";
+    private final Class<T> parameterSpecClass;
+
+    public AlgorithmParameterSignatureHelper(String algorithmName, Class<T> parameterSpecCla1ss) {
+        this.algorithmName = algorithmName;
+        this.parameterSpecClass = parameterSpecCla1ss;
+    }
+
+    @Override
+    public void test(AlgorithmParameters parameters) throws Exception {
+        Signature signature = Signature.getInstance(algorithmName);
+        T parameterSpec = parameters.getParameterSpec(parameterSpecClass);
+        KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithmName);
+
+        generator.initialize(parameterSpec);
+        KeyPair keyPair = generator.genKeyPair();
+
+        signature.initSign(keyPair.getPrivate());
+        signature.update(plainData.getBytes("UTF-8"));
+        byte[] signed = signature.sign();
+
+        signature.initVerify(keyPair.getPublic());
+        signature.update(plainData.getBytes("UTF-8"));
+        assertTrue("signature should verify", signature.verify(signed));
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterSymmetricHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterSymmetricHelper.java
new file mode 100644
index 0000000..8791ecb
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AlgorithmParameterSymmetricHelper.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.util.Arrays;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlgorithmParameterSymmetricHelper extends TestHelper<AlgorithmParameters> {
+
+    private static final String plainData = "some data to encrypt and decrypt";
+    private final String algorithmName;
+    private final int keySize;
+    private String blockmode;
+
+    public AlgorithmParameterSymmetricHelper(String algorithmName, int keySize) {
+        this.algorithmName = algorithmName;
+        this.keySize = keySize;
+    }
+
+    public AlgorithmParameterSymmetricHelper(String algorithmName, String blockmode, int keySize) {
+        this(algorithmName, keySize);
+        this.blockmode = blockmode;
+    }
+
+    @Override
+    public void test(AlgorithmParameters parameters) throws Exception {
+        KeyGenerator generator = KeyGenerator.getInstance(algorithmName);
+        generator.init(keySize);
+
+        Key key = generator.generateKey();
+        String transformation = algorithmName;
+        if (blockmode != null)
+        {
+            transformation += "/" + blockmode;
+        }
+
+        Cipher cipher = Cipher.getInstance(transformation);
+        cipher.init(Cipher.ENCRYPT_MODE, key, parameters);
+        byte[] bs = cipher.doFinal(plainData.getBytes("UTF-8"));
+
+        cipher.init(Cipher.DECRYPT_MODE, key, parameters);
+        byte[] decrypted = cipher.doFinal(bs);
+
+        assertTrue(Arrays.equals(plainData.getBytes("UTF-8"), decrypted));
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CipherAsymmetricCryptHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CipherAsymmetricCryptHelper.java
new file mode 100644
index 0000000..049f609
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CipherAsymmetricCryptHelper.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.KeyPair;
+import javax.crypto.Cipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CipherAsymmetricCryptHelper extends CipherHelper<KeyPair> {
+
+    private static final String plainData = "some data to encrypt and decrypt test";
+
+    public CipherAsymmetricCryptHelper(String algorithmName) {
+        super(algorithmName, plainData, Cipher.ENCRYPT_MODE,
+                Cipher.DECRYPT_MODE);
+    }
+
+    @Override
+    public void test(KeyPair keyPair) throws Exception {
+        test(keyPair.getPrivate(), keyPair.getPublic());
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CipherHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CipherHelper.java
new file mode 100644
index 0000000..73f59f7
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CipherHelper.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+
+import java.security.Key;
+import javax.crypto.Cipher;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class CipherHelper<T> extends TestHelper<T> {
+
+    private final String algorithmName;
+    private final String plainData;
+    private final int mode1;
+    private final int mode2;
+
+    public CipherHelper(String algorithmName, String plainData, int mode1, int mode2) {
+        this.algorithmName = algorithmName;
+        this.plainData = plainData;
+        this.mode1 = mode1;
+        this.mode2 = mode2;
+    }
+
+    public void test(Key encryptKey, Key decryptKey) throws Exception {
+        Cipher cipher = Cipher.getInstance(algorithmName);
+        cipher.init(mode1, encryptKey);
+        byte[] encrypted = cipher.doFinal(plainData.getBytes("UTF-8"));
+
+        cipher.init(mode2, decryptKey);
+        byte[] decrypted = cipher.doFinal(encrypted);
+        String decryptedString = new String(decrypted, "UTF-8");
+
+        assertEquals("transformed data does not match", plainData, decryptedString);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CpuFeatures.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CpuFeatures.java
new file mode 100644
index 0000000..f75fb94
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/CpuFeatures.java
@@ -0,0 +1,151 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2016 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 com.android.org.conscrypt.java.security;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CpuFeatures {
+    private CpuFeatures() {}
+
+    public static boolean isAESHardwareAccelerated() {
+        List<String> features = getListFromCpuinfo("Features");
+        if (features != null && features.contains("aes")) {
+            return true;
+        }
+
+        List<String> flags = getListFromCpuinfo("flags");
+        if (flags != null && flags.contains("aes")) {
+            return true;
+        }
+
+        features = getCpuFeaturesMac();
+        if (features != null && features.contains("aes")) {
+            return true;
+        }
+
+        // If we're in an emulated ABI, Conscrypt's NativeCrypto might bridge to
+        // a library that has accelerated AES instructions. See if Conscrypt
+        // detects that condition.
+        Class<?> nativeCrypto = findNativeCrypto();
+        if (nativeCrypto != null) {
+            try {
+                Method EVP_has_aes_hardware =
+                        nativeCrypto.getDeclaredMethod("EVP_has_aes_hardware");
+                EVP_has_aes_hardware.setAccessible(true);
+                return ((Integer) EVP_has_aes_hardware.invoke(null)) == 1;
+            } catch (NoSuchMethodException ignored) {
+            } catch (SecurityException ignored) {
+            } catch (IllegalAccessException ignored) {
+            } catch (IllegalArgumentException ignored) {
+            } catch (InvocationTargetException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        return false;
+    }
+
+    private static Class<?> findNativeCrypto() {
+        for (String packageName : new String[]{"com.android.com.android.org.conscrypt", "com.android.org.conscrypt"}) {
+            String name = packageName + ".NativeCrypto";
+            try {
+                return Class.forName(name);
+            } catch (ClassNotFoundException e) {
+                // Try the next one.
+            }
+        }
+        return null;
+    }
+
+    private static String getFieldFromCpuinfo(String field) {
+        try {
+            @SuppressWarnings("DefaultCharset")
+            BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"));
+            Pattern p = Pattern.compile(field + "\\s*:\\s*(.*)");
+
+            try {
+                String line;
+                while ((line = br.readLine()) != null) {
+                    Matcher m = p.matcher(line);
+                    if (m.matches()) {
+                        return m.group(1);
+                    }
+                }
+            } finally {
+                br.close();
+            }
+        } catch (IOException ignored) {
+            // Ignored.
+        }
+
+        return null;
+    }
+
+    private static List<String> getListFromCpuinfo(String fieldName) {
+        String features = getFieldFromCpuinfo(fieldName);
+        if (features == null)
+            return null;
+
+        return Arrays.asList(features.split("\\s"));
+    }
+
+    private static List<String> getCpuFeaturesMac() {
+        try {
+            StringBuilder output = new StringBuilder();
+            Process proc = Runtime.getRuntime().exec("sysctl -a");
+            if (proc.waitFor() == 0) {
+                BufferedReader reader =
+                        new BufferedReader(new InputStreamReader(proc.getInputStream(), UTF_8));
+
+                final String linePrefix = "machdep.cpu.features:";
+
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    line = line.toLowerCase();
+                    if (line.startsWith(linePrefix)) {
+                        // Strip the line prefix from the results.
+                        output.append(line.substring(linePrefix.length())).append(' ');
+                    }
+                }
+                if (output.length() > 0) {
+                    String outputString = output.toString();
+                    String[] parts = outputString.split("\\s+");
+                    return Arrays.asList(parts);
+                }
+            }
+        } catch (Exception ignored) {
+            // Ignored.
+        }
+
+        return null;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/DefaultKeys.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/DefaultKeys.java
new file mode 100644
index 0000000..5a89f3d
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/DefaultKeys.java
@@ -0,0 +1,210 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DefaultKeys {
+    private static final byte[] RSA_private = new byte[] {
+        (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x75, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D,
+        (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, (byte) 0x02, (byte) 0x5F, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5B, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02,
+        (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x99, (byte) 0xA5, (byte) 0x96, (byte) 0x72, (byte) 0xAE, (byte) 0xBB, (byte) 0x59, (byte) 0x36, (byte) 0xA8, (byte) 0x12, (byte) 0x17, (byte) 0x05, (byte) 0x4C, (byte) 0x63,
+        (byte) 0x9E, (byte) 0xB8, (byte) 0x85, (byte) 0xD4, (byte) 0x2D, (byte) 0x71, (byte) 0xD7, (byte) 0x29, (byte) 0xB9, (byte) 0x05, (byte) 0x0F, (byte) 0xB4, (byte) 0x57, (byte) 0xFB, (byte) 0xD3, (byte) 0x95, (byte) 0x5C,
+        (byte) 0x21, (byte) 0xEC, (byte) 0xB5, (byte) 0xEB, (byte) 0x67, (byte) 0xA2, (byte) 0x4F, (byte) 0xC1, (byte) 0x93, (byte) 0xEF, (byte) 0x96, (byte) 0x41, (byte) 0x05, (byte) 0x3D, (byte) 0xC5, (byte) 0x3E, (byte) 0x04,
+        (byte) 0x4D, (byte) 0xC6, (byte) 0xCF, (byte) 0x32, (byte) 0x7C, (byte) 0x1F, (byte) 0x66, (byte) 0xA3, (byte) 0xC5, (byte) 0x27, (byte) 0x79, (byte) 0xEC, (byte) 0x2E, (byte) 0x67, (byte) 0xFA, (byte) 0x19, (byte) 0x5B,
+        (byte) 0xE3, (byte) 0xB1, (byte) 0x69, (byte) 0xDA, (byte) 0x63, (byte) 0xBC, (byte) 0xDA, (byte) 0xD3, (byte) 0xBB, (byte) 0xAD, (byte) 0x8C, (byte) 0x38, (byte) 0x7B, (byte) 0x4A, (byte) 0x9C, (byte) 0xD4, (byte) 0x4D,
+        (byte) 0xD2, (byte) 0x33, (byte) 0xB7, (byte) 0x4E, (byte) 0x04, (byte) 0xB6, (byte) 0xDF, (byte) 0x62, (byte) 0x55, (byte) 0x48, (byte) 0x5C, (byte) 0x94, (byte) 0x02, (byte) 0xF7, (byte) 0x84, (byte) 0xE6, (byte) 0x9B,
+        (byte) 0x57, (byte) 0xFF, (byte) 0x17, (byte) 0x2A, (byte) 0xA1, (byte) 0x74, (byte) 0x8D, (byte) 0x07, (byte) 0xD8, (byte) 0xCE, (byte) 0xF7, (byte) 0x0B, (byte) 0x59, (byte) 0xFB, (byte) 0x13, (byte) 0x6E, (byte) 0xF1,
+        (byte) 0xC3, (byte) 0xAB, (byte) 0x3E, (byte) 0x72, (byte) 0x1B, (byte) 0x62, (byte) 0x09, (byte) 0xE8, (byte) 0xD8, (byte) 0x41, (byte) 0x69, (byte) 0xE1, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01,
+        (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x57, (byte) 0xD6, (byte) 0x1C, (byte) 0x2E, (byte) 0x2F, (byte) 0xCA, (byte) 0x16, (byte) 0xF4, (byte) 0x72, (byte) 0x1C, (byte) 0xF5, (byte) 0x60, (byte) 0x28, (byte) 0x0D,
+        (byte) 0x83, (byte) 0x7D, (byte) 0x85, (byte) 0xB4, (byte) 0x88, (byte) 0xCE, (byte) 0x5D, (byte) 0xED, (byte) 0x12, (byte) 0x42, (byte) 0xDC, (byte) 0x79, (byte) 0x83, (byte) 0x1B, (byte) 0x0A, (byte) 0x18, (byte) 0x86,
+        (byte) 0xF5, (byte) 0x35, (byte) 0xF7, (byte) 0xC2, (byte) 0x3E, (byte) 0x1A, (byte) 0xC2, (byte) 0x71, (byte) 0xAD, (byte) 0xFA, (byte) 0xF7, (byte) 0xF0, (byte) 0xEF, (byte) 0xE8, (byte) 0x22, (byte) 0x4C, (byte) 0x93,
+        (byte) 0xF5, (byte) 0x4A, (byte) 0xC4, (byte) 0xC4, (byte) 0xDD, (byte) 0xC4, (byte) 0xAD, (byte) 0xCE, (byte) 0xCE, (byte) 0x35, (byte) 0x05, (byte) 0x34, (byte) 0x8A, (byte) 0x4B, (byte) 0x12, (byte) 0xE4, (byte) 0x69,
+        (byte) 0xE6, (byte) 0xDA, (byte) 0x07, (byte) 0x1A, (byte) 0x77, (byte) 0x5C, (byte) 0xA7, (byte) 0x21, (byte) 0x41, (byte) 0x89, (byte) 0x8C, (byte) 0x95, (byte) 0x6A, (byte) 0x5D, (byte) 0x9C, (byte) 0x3C, (byte) 0xAE,
+        (byte) 0xC3, (byte) 0xE4, (byte) 0x64, (byte) 0x54, (byte) 0xDA, (byte) 0xFB, (byte) 0xBA, (byte) 0xA6, (byte) 0xE5, (byte) 0x8A, (byte) 0x7F, (byte) 0xFA, (byte) 0x1A, (byte) 0x3F, (byte) 0x9B, (byte) 0xAB, (byte) 0xDA,
+        (byte) 0x3D, (byte) 0x3B, (byte) 0x43, (byte) 0xF0, (byte) 0x0C, (byte) 0x06, (byte) 0x57, (byte) 0x43, (byte) 0x45, (byte) 0xEE, (byte) 0x8C, (byte) 0x27, (byte) 0x05, (byte) 0xAF, (byte) 0xCD, (byte) 0x5A, (byte) 0x47,
+        (byte) 0xB9, (byte) 0xEA, (byte) 0xD9, (byte) 0xAA, (byte) 0x66, (byte) 0xDB, (byte) 0xE3, (byte) 0xDC, (byte) 0x54, (byte) 0x47, (byte) 0x60, (byte) 0x01, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xED, (byte) 0xE9,
+        (byte) 0xBD, (byte) 0xD5, (byte) 0x02, (byte) 0x6D, (byte) 0x44, (byte) 0x0E, (byte) 0x3F, (byte) 0x74, (byte) 0x0C, (byte) 0x45, (byte) 0x54, (byte) 0x88, (byte) 0xFE, (byte) 0x5C, (byte) 0xFC, (byte) 0xF2, (byte) 0x31,
+        (byte) 0x7B, (byte) 0xAF, (byte) 0x15, (byte) 0x77, (byte) 0x7A, (byte) 0xDC, (byte) 0xC6, (byte) 0x9E, (byte) 0x7E, (byte) 0xC1, (byte) 0xCA, (byte) 0x84, (byte) 0xC7, (byte) 0x4B, (byte) 0xC4, (byte) 0x41, (byte) 0xE1,
+        (byte) 0x85, (byte) 0xE4, (byte) 0x5A, (byte) 0xA7, (byte) 0x3D, (byte) 0x54, (byte) 0x87, (byte) 0x0D, (byte) 0x7A, (byte) 0xC5, (byte) 0x47, (byte) 0x5C, (byte) 0xF2, (byte) 0xAD, (byte) 0x14, (byte) 0x4D, (byte) 0x63,
+        (byte) 0xB0, (byte) 0xDC, (byte) 0x34, (byte) 0xB5, (byte) 0xDA, (byte) 0x17, (byte) 0x0D, (byte) 0x4E, (byte) 0x2B, (byte) 0x9E, (byte) 0x81, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xA5, (byte) 0x53, (byte) 0xDB,
+        (byte) 0xD8, (byte) 0x28, (byte) 0x57, (byte) 0x65, (byte) 0x2B, (byte) 0xFA, (byte) 0xF2, (byte) 0x21, (byte) 0xB8, (byte) 0x60, (byte) 0xAE, (byte) 0x43, (byte) 0x4B, (byte) 0x51, (byte) 0x85, (byte) 0xCB, (byte) 0xDA,
+        (byte) 0x89, (byte) 0x5A, (byte) 0x7D, (byte) 0x05, (byte) 0xDA, (byte) 0xFC, (byte) 0xAF, (byte) 0x46, (byte) 0x86, (byte) 0xBC, (byte) 0x3F, (byte) 0xD1, (byte) 0xEA, (byte) 0xA4, (byte) 0x56, (byte) 0xA3, (byte) 0xE6,
+        (byte) 0xD4, (byte) 0xA2, (byte) 0x08, (byte) 0x93, (byte) 0x63, (byte) 0x21, (byte) 0x0E, (byte) 0xC5, (byte) 0x3C, (byte) 0x97, (byte) 0x7E, (byte) 0x71, (byte) 0x0B, (byte) 0x79, (byte) 0xF8, (byte) 0x60, (byte) 0x73,
+        (byte) 0xD1, (byte) 0xF9, (byte) 0xD4, (byte) 0x66, (byte) 0x29, (byte) 0x7D, (byte) 0xDC, (byte) 0x22, (byte) 0xDB, (byte) 0x61, (byte) 0x02, (byte) 0x40, (byte) 0x5D, (byte) 0x3D, (byte) 0xEF, (byte) 0x85, (byte) 0x4D,
+        (byte) 0x27, (byte) 0x2F, (byte) 0xB5, (byte) 0xF9, (byte) 0xCE, (byte) 0x6C, (byte) 0x84, (byte) 0xBB, (byte) 0x85, (byte) 0xD9, (byte) 0x52, (byte) 0xEE, (byte) 0x5B, (byte) 0xA9, (byte) 0x63, (byte) 0x15, (byte) 0x12,
+        (byte) 0x6F, (byte) 0xBA, (byte) 0x3A, (byte) 0x4E, (byte) 0xA9, (byte) 0x8D, (byte) 0x7A, (byte) 0x3B, (byte) 0xF9, (byte) 0xDF, (byte) 0xF5, (byte) 0xE4, (byte) 0xDC, (byte) 0x01, (byte) 0x1C, (byte) 0x2D, (byte) 0x8C,
+        (byte) 0x0D, (byte) 0xE1, (byte) 0x6E, (byte) 0x80, (byte) 0x63, (byte) 0x9B, (byte) 0x0B, (byte) 0x38, (byte) 0x55, (byte) 0xC8, (byte) 0x52, (byte) 0x67, (byte) 0x13, (byte) 0x91, (byte) 0x8F, (byte) 0x9E, (byte) 0x2E,
+        (byte) 0x16, (byte) 0x5B, (byte) 0x7C, (byte) 0x0F, (byte) 0x5D, (byte) 0xE4, (byte) 0xA0, (byte) 0x81, (byte) 0x02, (byte) 0x40, (byte) 0x20, (byte) 0x12, (byte) 0x11, (byte) 0x5E, (byte) 0x70, (byte) 0x0C, (byte) 0xEC,
+        (byte) 0x02, (byte) 0x49, (byte) 0x0E, (byte) 0xB9, (byte) 0x3D, (byte) 0xD3, (byte) 0xFB, (byte) 0x59, (byte) 0xF0, (byte) 0x7D, (byte) 0x62, (byte) 0xEF, (byte) 0xF5, (byte) 0x77, (byte) 0x99, (byte) 0x87, (byte) 0x11,
+        (byte) 0x20, (byte) 0xB6, (byte) 0xCD, (byte) 0xA5, (byte) 0x67, (byte) 0xB3, (byte) 0x92, (byte) 0xC9, (byte) 0xBC, (byte) 0xB3, (byte) 0x9E, (byte) 0x5E, (byte) 0xF3, (byte) 0x03, (byte) 0x22, (byte) 0x5F, (byte) 0x79,
+        (byte) 0x7F, (byte) 0xCC, (byte) 0x44, (byte) 0xDA, (byte) 0x3B, (byte) 0xF3, (byte) 0xC3, (byte) 0x42, (byte) 0x58, (byte) 0x90, (byte) 0x93, (byte) 0x7E, (byte) 0xDA, (byte) 0x58, (byte) 0xCC, (byte) 0x16, (byte) 0xC8,
+        (byte) 0xAE, (byte) 0x99, (byte) 0xCC, (byte) 0x9F, (byte) 0x32, (byte) 0x61, (byte) 0x02, (byte) 0x40, (byte) 0x02, (byte) 0x29, (byte) 0xDB, (byte) 0x00, (byte) 0x0F, (byte) 0x0A, (byte) 0x17, (byte) 0x33, (byte) 0x7E,
+        (byte) 0xC5, (byte) 0xEC, (byte) 0x21, (byte) 0x47, (byte) 0x65, (byte) 0xDC, (byte) 0xE5, (byte) 0xC2, (byte) 0x0D, (byte) 0x42, (byte) 0x28, (byte) 0xE1, (byte) 0x17, (byte) 0x1A, (byte) 0x00, (byte) 0xBD, (byte) 0xBE,
+        (byte) 0x1C, (byte) 0x7D, (byte) 0xCA, (byte) 0x93, (byte) 0x67, (byte) 0x8F, (byte) 0x28, (byte) 0xB7, (byte) 0x60, (byte) 0x8E, (byte) 0xF0, (byte) 0x5D, (byte) 0xCD, (byte) 0xFA, (byte) 0xDD, (byte) 0x6B, (byte) 0x72,
+        (byte) 0xF7, (byte) 0x48, (byte) 0xD9, (byte) 0x3C, (byte) 0x40, (byte) 0x7C, (byte) 0xB0, (byte) 0xD7, (byte) 0x58, (byte) 0xC2, (byte) 0x53, (byte) 0xAD, (byte) 0x04, (byte) 0xF6, (byte) 0x0B, (byte) 0x35, (byte) 0x51,
+        (byte) 0x45, (byte) 0xB9, (byte) 0x4F, (byte) 0x49  };
+        private static final byte[] RSA_public = new byte[] {
+        (byte) 0x30, (byte) 0x81, (byte) 0x9F, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05,
+        (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8D, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x99, (byte) 0xA5, (byte) 0x96, (byte) 0x72, (byte) 0xAE,
+        (byte) 0xBB, (byte) 0x59, (byte) 0x36, (byte) 0xA8, (byte) 0x12, (byte) 0x17, (byte) 0x05, (byte) 0x4C, (byte) 0x63, (byte) 0x9E, (byte) 0xB8, (byte) 0x85, (byte) 0xD4, (byte) 0x2D, (byte) 0x71, (byte) 0xD7, (byte) 0x29,
+        (byte) 0xB9, (byte) 0x05, (byte) 0x0F, (byte) 0xB4, (byte) 0x57, (byte) 0xFB, (byte) 0xD3, (byte) 0x95, (byte) 0x5C, (byte) 0x21, (byte) 0xEC, (byte) 0xB5, (byte) 0xEB, (byte) 0x67, (byte) 0xA2, (byte) 0x4F, (byte) 0xC1,
+        (byte) 0x93, (byte) 0xEF, (byte) 0x96, (byte) 0x41, (byte) 0x05, (byte) 0x3D, (byte) 0xC5, (byte) 0x3E, (byte) 0x04, (byte) 0x4D, (byte) 0xC6, (byte) 0xCF, (byte) 0x32, (byte) 0x7C, (byte) 0x1F, (byte) 0x66, (byte) 0xA3,
+        (byte) 0xC5, (byte) 0x27, (byte) 0x79, (byte) 0xEC, (byte) 0x2E, (byte) 0x67, (byte) 0xFA, (byte) 0x19, (byte) 0x5B, (byte) 0xE3, (byte) 0xB1, (byte) 0x69, (byte) 0xDA, (byte) 0x63, (byte) 0xBC, (byte) 0xDA, (byte) 0xD3,
+        (byte) 0xBB, (byte) 0xAD, (byte) 0x8C, (byte) 0x38, (byte) 0x7B, (byte) 0x4A, (byte) 0x9C, (byte) 0xD4, (byte) 0x4D, (byte) 0xD2, (byte) 0x33, (byte) 0xB7, (byte) 0x4E, (byte) 0x04, (byte) 0xB6, (byte) 0xDF, (byte) 0x62,
+        (byte) 0x55, (byte) 0x48, (byte) 0x5C, (byte) 0x94, (byte) 0x02, (byte) 0xF7, (byte) 0x84, (byte) 0xE6, (byte) 0x9B, (byte) 0x57, (byte) 0xFF, (byte) 0x17, (byte) 0x2A, (byte) 0xA1, (byte) 0x74, (byte) 0x8D, (byte) 0x07,
+        (byte) 0xD8, (byte) 0xCE, (byte) 0xF7, (byte) 0x0B, (byte) 0x59, (byte) 0xFB, (byte) 0x13, (byte) 0x6E, (byte) 0xF1, (byte) 0xC3, (byte) 0xAB, (byte) 0x3E, (byte) 0x72, (byte) 0x1B, (byte) 0x62, (byte) 0x09, (byte) 0xE8,
+        (byte) 0xD8, (byte) 0x41, (byte) 0x69, (byte) 0xE1, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01     };
+        private static final byte[] DSA_private = new byte[] {
+        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4B, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2C, (byte) 0x06, (byte) 0x07, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0xCE,
+        (byte) 0x38, (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1F, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81, (byte) 0x1D, (byte) 0x75,
+        (byte) 0x12, (byte) 0x29, (byte) 0x52, (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C, (byte) 0xEF, (byte) 0x44,
+        (byte) 0x00, (byte) 0xC3, (byte) 0x1E, (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB, (byte) 0x59, (byte) 0x3D,
+        (byte) 0x8D, (byte) 0x58, (byte) 0xFA, (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81, (byte) 0x3B, (byte) 0x80,
+        (byte) 0x1D, (byte) 0x34, (byte) 0x6F, (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8, (byte) 0x04, (byte) 0x7B,
+        (byte) 0x10, (byte) 0x22, (byte) 0xC2, (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7, (byte) 0xC6, (byte) 0xA8,
+        (byte) 0xA6, (byte) 0x15, (byte) 0x0F, (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5A, (byte) 0x16,
+        (byte) 0x91, (byte) 0x32, (byte) 0xF6, (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19, (byte) 0x9D, (byte) 0xD1,
+        (byte) 0x48, (byte) 0x01, (byte) 0xC7, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x97, (byte) 0x60, (byte) 0x50, (byte) 0x8F, (byte) 0x15, (byte) 0x23, (byte) 0x0B, (byte) 0xCC, (byte) 0xB2, (byte) 0x92, (byte) 0xB9,
+        (byte) 0x82, (byte) 0xA2, (byte) 0xEB, (byte) 0x84, (byte) 0x0B, (byte) 0xF0, (byte) 0x58, (byte) 0x1C, (byte) 0xF5, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85,
+        (byte) 0xD6, (byte) 0x9B, (byte) 0x3D, (byte) 0xDE, (byte) 0xCB, (byte) 0xBC, (byte) 0xAB, (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA,
+        (byte) 0x3A, (byte) 0xEA, (byte) 0x82, (byte) 0xF9, (byte) 0x57, (byte) 0x4C, (byte) 0x0B, (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4,
+        (byte) 0x59, (byte) 0x4F, (byte) 0xE6, (byte) 0x71, (byte) 0x07, (byte) 0x10, (byte) 0x81, (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16,
+        (byte) 0x13, (byte) 0xB7, (byte) 0xCF, (byte) 0x09, (byte) 0x32, (byte) 0x8C, (byte) 0xC8, (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28,
+        (byte) 0xE0, (byte) 0xA3, (byte) 0xAE, (byte) 0x1E, (byte) 0x2B, (byte) 0xB3, (byte) 0xA6, (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62,
+        (byte) 0xF1, (byte) 0xFB, (byte) 0x62, (byte) 0x7A, (byte) 0x01, (byte) 0x24, (byte) 0x3B, (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83,
+        (byte) 0xDF, (byte) 0xE1, (byte) 0x5A, (byte) 0xE5, (byte) 0x9F, (byte) 0x06, (byte) 0x92, (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C,
+        (byte) 0x3B, (byte) 0xFE, (byte) 0xCF, (byte) 0x49, (byte) 0x2A, (byte) 0x04, (byte) 0x16, (byte) 0x02, (byte) 0x14, (byte) 0x0E, (byte) 0x90, (byte) 0xB7, (byte) 0x92, (byte) 0x01, (byte) 0x98, (byte) 0xCD, (byte) 0x85,
+        (byte) 0x87, (byte) 0x77, (byte) 0x2F, (byte) 0xB4, (byte) 0x31, (byte) 0xFD, (byte) 0xDE, (byte) 0xFA, (byte) 0x08, (byte) 0x6D, (byte) 0x0C, (byte) 0xE3  };
+        private static final byte[] DSA_public = new byte[] {
+        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xB8, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2C, (byte) 0x06, (byte) 0x07, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0xCE, (byte) 0x38, (byte) 0x04, (byte) 0x01,
+        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1F, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81, (byte) 0x1D, (byte) 0x75, (byte) 0x12, (byte) 0x29, (byte) 0x52,
+        (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C, (byte) 0xEF, (byte) 0x44, (byte) 0x00, (byte) 0xC3, (byte) 0x1E,
+        (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB, (byte) 0x59, (byte) 0x3D, (byte) 0x8D, (byte) 0x58, (byte) 0xFA,
+        (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81, (byte) 0x3B, (byte) 0x80, (byte) 0x1D, (byte) 0x34, (byte) 0x6F,
+        (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8, (byte) 0x04, (byte) 0x7B, (byte) 0x10, (byte) 0x22, (byte) 0xC2,
+        (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7, (byte) 0xC6, (byte) 0xA8, (byte) 0xA6, (byte) 0x15, (byte) 0x0F,
+        (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5A, (byte) 0x16, (byte) 0x91, (byte) 0x32, (byte) 0xF6,
+        (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19, (byte) 0x9D, (byte) 0xD1, (byte) 0x48, (byte) 0x01, (byte) 0xC7,
+        (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0x97, (byte) 0x60, (byte) 0x50, (byte) 0x8F, (byte) 0x15, (byte) 0x23, (byte) 0x0B, (byte) 0xCC, (byte) 0xB2, (byte) 0x92, (byte) 0xB9, (byte) 0x82, (byte) 0xA2, (byte) 0xEB,
+        (byte) 0x84, (byte) 0x0B, (byte) 0xF0, (byte) 0x58, (byte) 0x1C, (byte) 0xF5, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85, (byte) 0xD6, (byte) 0x9B, (byte) 0x3D,
+        (byte) 0xDE, (byte) 0xCB, (byte) 0xBC, (byte) 0xAB, (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA, (byte) 0x3A, (byte) 0xEA, (byte) 0x82,
+        (byte) 0xF9, (byte) 0x57, (byte) 0x4C, (byte) 0x0B, (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4, (byte) 0x59, (byte) 0x4F, (byte) 0xE6,
+        (byte) 0x71, (byte) 0x07, (byte) 0x10, (byte) 0x81, (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16, (byte) 0x13, (byte) 0xB7, (byte) 0xCF,
+        (byte) 0x09, (byte) 0x32, (byte) 0x8C, (byte) 0xC8, (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28, (byte) 0xE0, (byte) 0xA3, (byte) 0xAE,
+        (byte) 0x1E, (byte) 0x2B, (byte) 0xB3, (byte) 0xA6, (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62, (byte) 0xF1, (byte) 0xFB, (byte) 0x62,
+        (byte) 0x7A, (byte) 0x01, (byte) 0x24, (byte) 0x3B, (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83, (byte) 0xDF, (byte) 0xE1, (byte) 0x5A,
+        (byte) 0xE5, (byte) 0x9F, (byte) 0x06, (byte) 0x92, (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C, (byte) 0x3B, (byte) 0xFE, (byte) 0xCF,
+        (byte) 0x49, (byte) 0x2A, (byte) 0x03, (byte) 0x81, (byte) 0x85, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x98, (byte) 0x33, (byte) 0x90, (byte) 0x14, (byte) 0x79, (byte) 0xC7, (byte) 0xC8,
+        (byte) 0x57, (byte) 0xE1, (byte) 0x82, (byte) 0x53, (byte) 0x5B, (byte) 0x6E, (byte) 0x01, (byte) 0x07, (byte) 0x1E, (byte) 0xA5, (byte) 0x98, (byte) 0xC4, (byte) 0x57, (byte) 0x5D, (byte) 0x23, (byte) 0xAB, (byte) 0x72,
+        (byte) 0x9A, (byte) 0xB3, (byte) 0x2F, (byte) 0x39, (byte) 0xCB, (byte) 0xC5, (byte) 0xD0, (byte) 0x97, (byte) 0xD5, (byte) 0x62, (byte) 0x8C, (byte) 0xD9, (byte) 0xE6, (byte) 0xE2, (byte) 0x05, (byte) 0xC6, (byte) 0x05,
+        (byte) 0x71, (byte) 0x16, (byte) 0xE3, (byte) 0xE8, (byte) 0x04, (byte) 0xE8, (byte) 0x46, (byte) 0x12, (byte) 0x0C, (byte) 0xF8, (byte) 0xFC, (byte) 0x8E, (byte) 0x15, (byte) 0x26, (byte) 0x32, (byte) 0xF7, (byte) 0x8C,
+        (byte) 0x04, (byte) 0x3B, (byte) 0x53, (byte) 0x68, (byte) 0x9A, (byte) 0xA3, (byte) 0xB7, (byte) 0x4D, (byte) 0x13, (byte) 0x40, (byte) 0x0F, (byte) 0xBE, (byte) 0x03, (byte) 0x87, (byte) 0xD8, (byte) 0xF1, (byte) 0xFE,
+        (byte) 0x4B, (byte) 0xF5, (byte) 0x44, (byte) 0x19, (byte) 0x29, (byte) 0xBB, (byte) 0x0D, (byte) 0x0C, (byte) 0x52, (byte) 0xC6, (byte) 0x84, (byte) 0x33, (byte) 0x62, (byte) 0x73, (byte) 0x5D, (byte) 0x03, (byte) 0xFF,
+        (byte) 0x6F, (byte) 0x0A, (byte) 0x5A, (byte) 0xF3, (byte) 0x9E, (byte) 0x52, (byte) 0xF2, (byte) 0xC2, (byte) 0xC8, (byte) 0x00, (byte) 0x52, (byte) 0xC7, (byte) 0x75, (byte) 0xA4, (byte) 0xFD, (byte) 0x71, (byte) 0x2D,
+        (byte) 0x7B, (byte) 0x7A, (byte) 0x31, (byte) 0x27, (byte) 0x6E, (byte) 0xAC, (byte) 0xB6, (byte) 0x40, (byte) 0x14, (byte) 0x4E, (byte) 0xB4, (byte) 0xBB, (byte) 0xB1, (byte) 0x51, (byte) 0x63, (byte) 0x29, (byte) 0x81,
+        (byte) 0x06, (byte) 0xF9    };
+        private static final byte[] DH_private = new byte[] {
+        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xA8, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1B, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+        (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x0C, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81,
+        (byte) 0x1D, (byte) 0x75, (byte) 0x12, (byte) 0x29, (byte) 0x52, (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C,
+        (byte) 0xEF, (byte) 0x44, (byte) 0x00, (byte) 0xC3, (byte) 0x1E, (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB,
+        (byte) 0x59, (byte) 0x3D, (byte) 0x8D, (byte) 0x58, (byte) 0xFA, (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81,
+        (byte) 0x3B, (byte) 0x80, (byte) 0x1D, (byte) 0x34, (byte) 0x6F, (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8,
+        (byte) 0x04, (byte) 0x7B, (byte) 0x10, (byte) 0x22, (byte) 0xC2, (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7,
+        (byte) 0xC6, (byte) 0xA8, (byte) 0xA6, (byte) 0x15, (byte) 0x0F, (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13,
+        (byte) 0x5A, (byte) 0x16, (byte) 0x91, (byte) 0x32, (byte) 0xF6, (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19,
+        (byte) 0x9D, (byte) 0xD1, (byte) 0x48, (byte) 0x01, (byte) 0xC7, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85, (byte) 0xD6, (byte) 0x9B, (byte) 0x3D, (byte) 0xDE,
+        (byte) 0xCB, (byte) 0xBC, (byte) 0xAB, (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA, (byte) 0x3A, (byte) 0xEA, (byte) 0x82, (byte) 0xF9,
+        (byte) 0x57, (byte) 0x4C, (byte) 0x0B, (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4, (byte) 0x59, (byte) 0x4F, (byte) 0xE6, (byte) 0x71,
+        (byte) 0x07, (byte) 0x10, (byte) 0x81, (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16, (byte) 0x13, (byte) 0xB7, (byte) 0xCF, (byte) 0x09,
+        (byte) 0x32, (byte) 0x8C, (byte) 0xC8, (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28, (byte) 0xE0, (byte) 0xA3, (byte) 0xAE, (byte) 0x1E,
+        (byte) 0x2B, (byte) 0xB3, (byte) 0xA6, (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62, (byte) 0xF1, (byte) 0xFB, (byte) 0x62, (byte) 0x7A,
+        (byte) 0x01, (byte) 0x24, (byte) 0x3B, (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83, (byte) 0xDF, (byte) 0xE1, (byte) 0x5A, (byte) 0xE5,
+        (byte) 0x9F, (byte) 0x06, (byte) 0x92, (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C, (byte) 0x3B, (byte) 0xFE, (byte) 0xCF, (byte) 0x49,
+        (byte) 0x2A, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0xFE, (byte) 0x04, (byte) 0x81, (byte) 0x83, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x35, (byte) 0xFE, (byte) 0x44, (byte) 0x0A, (byte) 0xA3, (byte) 0xA0,
+        (byte) 0xCB, (byte) 0x52, (byte) 0xC2, (byte) 0x32, (byte) 0xCA, (byte) 0x38, (byte) 0x1F, (byte) 0x18, (byte) 0xEB, (byte) 0x27, (byte) 0x6E, (byte) 0x77, (byte) 0x25, (byte) 0x40, (byte) 0x1F, (byte) 0x64, (byte) 0x5D,
+        (byte) 0x4B, (byte) 0x59, (byte) 0x41, (byte) 0xB6, (byte) 0xCB, (byte) 0xDF, (byte) 0x73, (byte) 0xE0, (byte) 0x01, (byte) 0x5A, (byte) 0x79, (byte) 0x0D, (byte) 0x8D, (byte) 0x08, (byte) 0xE6, (byte) 0x7F, (byte) 0x86,
+        (byte) 0x58, (byte) 0xCF, (byte) 0x7F, (byte) 0x4B, (byte) 0x2E, (byte) 0xDB, (byte) 0x4C, (byte) 0xDF, (byte) 0x75, (byte) 0xB5, (byte) 0x16, (byte) 0xC4, (byte) 0xA9, (byte) 0x49, (byte) 0xEE, (byte) 0x00, (byte) 0x56,
+        (byte) 0xA0, (byte) 0x60, (byte) 0x08, (byte) 0x8E, (byte) 0x0D, (byte) 0xC7, (byte) 0xC9, (byte) 0x45, (byte) 0x0C, (byte) 0x5D, (byte) 0xB7, (byte) 0x4C, (byte) 0xC4, (byte) 0x7E, (byte) 0xAB, (byte) 0x1F, (byte) 0xEA,
+        (byte) 0xCF, (byte) 0x08, (byte) 0x6D, (byte) 0x05, (byte) 0xA1, (byte) 0x7F, (byte) 0x63, (byte) 0x6F, (byte) 0xB3, (byte) 0x91, (byte) 0xA3, (byte) 0xE1, (byte) 0xB0, (byte) 0x36, (byte) 0x02, (byte) 0x3F, (byte) 0x55,
+        (byte) 0x71, (byte) 0x38, (byte) 0x37, (byte) 0x9A, (byte) 0x19, (byte) 0xA3, (byte) 0xAF, (byte) 0xC8, (byte) 0xD5, (byte) 0x22, (byte) 0xDD, (byte) 0x00, (byte) 0x81, (byte) 0x19, (byte) 0xB6, (byte) 0x3C, (byte) 0x5F,
+        (byte) 0xD9, (byte) 0xDF, (byte) 0xFD, (byte) 0x58, (byte) 0xB1, (byte) 0xE6, (byte) 0xD1, (byte) 0xD2, (byte) 0x58, (byte) 0xEF, (byte) 0x44, (byte) 0x6E, (byte) 0x66, (byte) 0x92, (byte) 0x1E, (byte) 0x30, (byte) 0x0B,
+        (byte) 0x90, (byte) 0x8E, (byte) 0x29   };
+        private static final byte[] DH_public = new byte[] {
+        (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xA7, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1B, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01,
+        (byte) 0x03, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x0C, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xFD, (byte) 0x7F, (byte) 0x53, (byte) 0x81, (byte) 0x1D, (byte) 0x75, (byte) 0x12,
+        (byte) 0x29, (byte) 0x52, (byte) 0xDF, (byte) 0x4A, (byte) 0x9C, (byte) 0x2E, (byte) 0xEC, (byte) 0xE4, (byte) 0xE7, (byte) 0xF6, (byte) 0x11, (byte) 0xB7, (byte) 0x52, (byte) 0x3C, (byte) 0xEF, (byte) 0x44, (byte) 0x00,
+        (byte) 0xC3, (byte) 0x1E, (byte) 0x3F, (byte) 0x80, (byte) 0xB6, (byte) 0x51, (byte) 0x26, (byte) 0x69, (byte) 0x45, (byte) 0x5D, (byte) 0x40, (byte) 0x22, (byte) 0x51, (byte) 0xFB, (byte) 0x59, (byte) 0x3D, (byte) 0x8D,
+        (byte) 0x58, (byte) 0xFA, (byte) 0xBF, (byte) 0xC5, (byte) 0xF5, (byte) 0xBA, (byte) 0x30, (byte) 0xF6, (byte) 0xCB, (byte) 0x9B, (byte) 0x55, (byte) 0x6C, (byte) 0xD7, (byte) 0x81, (byte) 0x3B, (byte) 0x80, (byte) 0x1D,
+        (byte) 0x34, (byte) 0x6F, (byte) 0xF2, (byte) 0x66, (byte) 0x60, (byte) 0xB7, (byte) 0x6B, (byte) 0x99, (byte) 0x50, (byte) 0xA5, (byte) 0xA4, (byte) 0x9F, (byte) 0x9F, (byte) 0xE8, (byte) 0x04, (byte) 0x7B, (byte) 0x10,
+        (byte) 0x22, (byte) 0xC2, (byte) 0x4F, (byte) 0xBB, (byte) 0xA9, (byte) 0xD7, (byte) 0xFE, (byte) 0xB7, (byte) 0xC6, (byte) 0x1B, (byte) 0xF8, (byte) 0x3B, (byte) 0x57, (byte) 0xE7, (byte) 0xC6, (byte) 0xA8, (byte) 0xA6,
+        (byte) 0x15, (byte) 0x0F, (byte) 0x04, (byte) 0xFB, (byte) 0x83, (byte) 0xF6, (byte) 0xD3, (byte) 0xC5, (byte) 0x1E, (byte) 0xC3, (byte) 0x02, (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5A, (byte) 0x16, (byte) 0x91,
+        (byte) 0x32, (byte) 0xF6, (byte) 0x75, (byte) 0xF3, (byte) 0xAE, (byte) 0x2B, (byte) 0x61, (byte) 0xD7, (byte) 0x2A, (byte) 0xEF, (byte) 0xF2, (byte) 0x22, (byte) 0x03, (byte) 0x19, (byte) 0x9D, (byte) 0xD1, (byte) 0x48,
+        (byte) 0x01, (byte) 0xC7, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xF7, (byte) 0xE1, (byte) 0xA0, (byte) 0x85, (byte) 0xD6, (byte) 0x9B, (byte) 0x3D, (byte) 0xDE, (byte) 0xCB, (byte) 0xBC, (byte) 0xAB,
+        (byte) 0x5C, (byte) 0x36, (byte) 0xB8, (byte) 0x57, (byte) 0xB9, (byte) 0x79, (byte) 0x94, (byte) 0xAF, (byte) 0xBB, (byte) 0xFA, (byte) 0x3A, (byte) 0xEA, (byte) 0x82, (byte) 0xF9, (byte) 0x57, (byte) 0x4C, (byte) 0x0B,
+        (byte) 0x3D, (byte) 0x07, (byte) 0x82, (byte) 0x67, (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8E, (byte) 0xBA, (byte) 0xD4, (byte) 0x59, (byte) 0x4F, (byte) 0xE6, (byte) 0x71, (byte) 0x07, (byte) 0x10, (byte) 0x81,
+        (byte) 0x80, (byte) 0xB4, (byte) 0x49, (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xE8, (byte) 0x4C, (byte) 0x28, (byte) 0x16, (byte) 0x13, (byte) 0xB7, (byte) 0xCF, (byte) 0x09, (byte) 0x32, (byte) 0x8C, (byte) 0xC8,
+        (byte) 0xA6, (byte) 0xE1, (byte) 0x3C, (byte) 0x16, (byte) 0x7A, (byte) 0x8B, (byte) 0x54, (byte) 0x7C, (byte) 0x8D, (byte) 0x28, (byte) 0xE0, (byte) 0xA3, (byte) 0xAE, (byte) 0x1E, (byte) 0x2B, (byte) 0xB3, (byte) 0xA6,
+        (byte) 0x75, (byte) 0x91, (byte) 0x6E, (byte) 0xA3, (byte) 0x7F, (byte) 0x0B, (byte) 0xFA, (byte) 0x21, (byte) 0x35, (byte) 0x62, (byte) 0xF1, (byte) 0xFB, (byte) 0x62, (byte) 0x7A, (byte) 0x01, (byte) 0x24, (byte) 0x3B,
+        (byte) 0xCC, (byte) 0xA4, (byte) 0xF1, (byte) 0xBE, (byte) 0xA8, (byte) 0x51, (byte) 0x90, (byte) 0x89, (byte) 0xA8, (byte) 0x83, (byte) 0xDF, (byte) 0xE1, (byte) 0x5A, (byte) 0xE5, (byte) 0x9F, (byte) 0x06, (byte) 0x92,
+        (byte) 0x8B, (byte) 0x66, (byte) 0x5E, (byte) 0x80, (byte) 0x7B, (byte) 0x55, (byte) 0x25, (byte) 0x64, (byte) 0x01, (byte) 0x4C, (byte) 0x3B, (byte) 0xFE, (byte) 0xCF, (byte) 0x49, (byte) 0x2A, (byte) 0x02, (byte) 0x02,
+        (byte) 0x03, (byte) 0xFE, (byte) 0x03, (byte) 0x81, (byte) 0x85, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xD4, (byte) 0xC2, (byte) 0xC2, (byte) 0x84, (byte) 0xEB, (byte) 0xEC, (byte) 0xB6,
+        (byte) 0xF1, (byte) 0x29, (byte) 0x2B, (byte) 0xAB, (byte) 0x8F, (byte) 0xC1, (byte) 0x48, (byte) 0x4C, (byte) 0x47, (byte) 0xCE, (byte) 0x0B, (byte) 0x97, (byte) 0x4C, (byte) 0xFC, (byte) 0x27, (byte) 0x10, (byte) 0x0A,
+        (byte) 0x5F, (byte) 0x3E, (byte) 0xE6, (byte) 0xF9, (byte) 0x9B, (byte) 0x15, (byte) 0xDF, (byte) 0x83, (byte) 0x01, (byte) 0xFA, (byte) 0x69, (byte) 0x57, (byte) 0xEC, (byte) 0x6B, (byte) 0x68, (byte) 0xC7, (byte) 0x96,
+        (byte) 0x33, (byte) 0x98, (byte) 0xA4, (byte) 0xB0, (byte) 0xA3, (byte) 0x18, (byte) 0x01, (byte) 0x66, (byte) 0x7A, (byte) 0x4A, (byte) 0xF3, (byte) 0x3C, (byte) 0xD9, (byte) 0x2A, (byte) 0x48, (byte) 0xFD, (byte) 0x3A,
+        (byte) 0x31, (byte) 0xFC, (byte) 0x97, (byte) 0x52, (byte) 0x36, (byte) 0x20, (byte) 0x0E, (byte) 0x69, (byte) 0xB6, (byte) 0x32, (byte) 0x8B, (byte) 0x4E, (byte) 0xDA, (byte) 0x8B, (byte) 0x04, (byte) 0x88, (byte) 0xF8,
+        (byte) 0x30, (byte) 0xA9, (byte) 0x65, (byte) 0x68, (byte) 0x47, (byte) 0xBB, (byte) 0xA1, (byte) 0xF6, (byte) 0xD6, (byte) 0x18, (byte) 0x11, (byte) 0x48, (byte) 0x8D, (byte) 0x8F, (byte) 0x4B, (byte) 0xC1, (byte) 0xE1,
+        (byte) 0xA4, (byte) 0x43, (byte) 0x83, (byte) 0x1F, (byte) 0x6B, (byte) 0x6D, (byte) 0xEE, (byte) 0xA7, (byte) 0xA3, (byte) 0x5F, (byte) 0xD2, (byte) 0x95, (byte) 0x09, (byte) 0xD4, (byte) 0xEA, (byte) 0x85, (byte) 0x0C,
+        (byte) 0xA5, (byte) 0xC9, (byte) 0x93, (byte) 0xCE, (byte) 0xC1, (byte) 0x1D, (byte) 0x30, (byte) 0x73, (byte) 0xA3, (byte) 0xE1, (byte) 0x69, (byte) 0xA8, (byte) 0x11, (byte) 0x98, (byte) 0x78, (byte) 0xF3, (byte) 0xF9,
+        (byte) 0x8F, (byte) 0x04    };
+
+
+
+    private static final HashMap<String, KeySpec> keys = new HashMap<String, KeySpec>();
+    static {
+        keys.put("DH_public", new X509EncodedKeySpec(DH_public));
+        keys.put("DH_private", new PKCS8EncodedKeySpec(DH_private));
+        keys.put("DSA_public", new X509EncodedKeySpec(DSA_public));
+        keys.put("DSA_private", new PKCS8EncodedKeySpec(DSA_private));
+        keys.put("RSA_public", new X509EncodedKeySpec(RSA_public));
+        keys.put("RSA_private", new PKCS8EncodedKeySpec(RSA_private));
+    }
+
+    public static PrivateKey getPrivateKey(String algorithmName) throws NoSuchAlgorithmException, InvalidKeySpecException
+    {
+        KeyFactory factory = KeyFactory.getInstance(algorithmName);
+        return factory.generatePrivate(keys.get(algorithmName + "_private"));
+    }
+
+    public static PublicKey getPublicKey(String algorithmName) throws NoSuchAlgorithmException, InvalidKeySpecException
+    {
+        KeyFactory factory = KeyFactory.getInstance(algorithmName);
+        return factory.generatePublic(keys.get(algorithmName + "_public"));
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/KeyAgreementHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/KeyAgreementHelper.java
new file mode 100644
index 0000000..7580aea
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/KeyAgreementHelper.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import javax.crypto.KeyAgreement;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class KeyAgreementHelper extends TestHelper<KeyPair> {
+
+    private final String algorithmName;
+
+    public KeyAgreementHelper(String algorithmName) {
+        this.algorithmName = algorithmName;
+    }
+
+    @Override public void test(KeyPair keyPair) throws Exception {
+        test(keyPair.getPrivate(), keyPair.getPublic());
+    }
+
+    void test(PrivateKey encryptKey, PublicKey decryptKey) throws Exception {
+        KeyAgreement keyAgreement = KeyAgreement.getInstance(algorithmName);
+        keyAgreement.init(encryptKey);
+        keyAgreement.doPhase(decryptKey, true);
+        assertNotNull("generated secret is null", keyAgreement.generateSecret());
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/SignatureHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/SignatureHelper.java
new file mode 100644
index 0000000..9717a58
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/SignatureHelper.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SignatureHelper extends TestHelper<KeyPair> {
+
+    private final String algorithmName;
+    private final String plainData = "some data do sign and verify";
+
+    public SignatureHelper(String algorithmName) {
+        this.algorithmName = algorithmName;
+    }
+
+    @Override
+    public void test(KeyPair keyPair) throws Exception {
+        test(keyPair.getPrivate(), keyPair.getPublic());
+    }
+
+    public void test(PrivateKey encryptKey, PublicKey decryptKey) throws Exception {
+        Signature signature = Signature.getInstance(algorithmName);
+        signature.initSign(encryptKey);
+        signature.update(plainData.getBytes("UTF-8"));
+        byte[] signed = signature.sign();
+
+        signature.initVerify(decryptKey);
+        signature.update(plainData.getBytes("UTF-8"));
+        assertTrue("signature could not be verified", signature.verify(signed));
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java
new file mode 100644
index 0000000..917df97
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/StandardNames.java
@@ -0,0 +1,455 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class defines expected string names for protocols, key types,
+ * client and server auth types, cipher suites.
+ *
+ * Initially based on "Appendix A: Standard Names" of
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
+ * Java &trade; Secure Socket Extension (JSSE) Reference Guide
+ * for the Java &trade; 2 Platform Standard Edition 5
+ * </a>.
+ *
+ * Updated based on the
+ * <a href="http://download.java.net/jdk8/docs/technotes/guides/security/SunProviders.html">
+ * Java &trade; Cryptography Architecture Oracle Providers Documentation
+ * for Java &trade; Platform Standard Edition 7
+ * </a>.
+ * See also the
+ * <a href="http://download.java.net/jdk8/docs/technotes/guides/security/StandardNames.html">
+ * Java &trade; Cryptography Architecture Standard Algorithm Name Documentation
+ * </a>.
+ *
+ * Further updates based on the
+ * <a href=http://java.sun.com/javase/6/docs/technotes/guides/security/p11guide.html">
+ * Java &trade; PKCS#11 Reference Guide
+ * </a>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class StandardNames {
+    public static final boolean IS_RI =
+            !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
+    public static final String JSSE_PROVIDER_NAME = IS_RI ? "Conscrypt" : "AndroidOpenSSL";
+
+    public static final String KEY_MANAGER_FACTORY_DEFAULT = IS_RI ? "SunX509" : "PKIX";
+    public static final String TRUST_MANAGER_FACTORY_DEFAULT = "PKIX";
+
+    public static final String KEY_STORE_ALGORITHM = IS_RI ? "JKS" : "BKS";
+
+    /**
+     * RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
+     */
+    public static final String CIPHER_SUITE_SECURE_RENEGOTIATION =
+            "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
+
+    /**
+     * From https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 it is a
+     * signaling cipher suite value (SCSV) to indicate that this request is a
+     * protocol fallback (e.g., TLS 1.0 -> SSL 3.0) because the server didn't respond
+     * to the first request.
+     */
+    public static final String CIPHER_SUITE_FALLBACK = "TLS_FALLBACK_SCSV";
+
+    private static final HashMap<String, HashSet<String>> CIPHER_MODES =
+            new HashMap<String, HashSet<String>>();
+
+    private static final HashMap<String, HashSet<String>> CIPHER_PADDINGS =
+            new HashMap<String, HashSet<String>>();
+
+    private static final HashMap<String, String[]> SSL_CONTEXT_PROTOCOLS_ENABLED =
+            new HashMap<String, String[]>();
+
+    private static void provideCipherModes(String algorithm, String newModes[]) {
+        HashSet<String> modes = CIPHER_MODES.get(algorithm);
+        if (modes == null) {
+            modes = new HashSet<String>();
+            CIPHER_MODES.put(algorithm, modes);
+        }
+        modes.addAll(Arrays.asList(newModes));
+    }
+    private static void provideCipherPaddings(String algorithm, String newPaddings[]) {
+        HashSet<String> paddings = CIPHER_PADDINGS.get(algorithm);
+        if (paddings == null) {
+            paddings = new HashSet<String>();
+            CIPHER_PADDINGS.put(algorithm, paddings);
+        }
+        paddings.addAll(Arrays.asList(newPaddings));
+    }
+    private static void provideSslContextEnabledProtocols(
+            String algorithm, TLSVersion minimum, TLSVersion maximum) {
+        if (minimum.ordinal() > maximum.ordinal()) {
+            throw new RuntimeException("TLS version: minimum > maximum");
+        }
+        int versionsLength = maximum.ordinal() - minimum.ordinal() + 1;
+        String[] versionNames = new String[versionsLength];
+        for (int i = 0; i < versionsLength; i++) {
+            versionNames[i] = TLSVersion.values()[i + minimum.ordinal()].name;
+        }
+        SSL_CONTEXT_PROTOCOLS_ENABLED.put(algorithm, versionNames);
+    }
+    static {
+        // TODO: provideCipherModes and provideCipherPaddings for other Ciphers
+        provideCipherModes("AES", new String[] {"CBC", "CFB", "CTR", "CTS", "ECB", "OFB"});
+        provideCipherPaddings("AES", new String[] {"NoPadding", "PKCS5Padding"});
+        // TODO: None?
+        provideCipherModes("RSA", new String[] {"ECB"});
+        // TODO: OAEPPadding
+        provideCipherPaddings("RSA", new String[] {"NoPadding", "PKCS1Padding"});
+
+        // Fixups for dalvik
+        if (!IS_RI) {
+            provideCipherPaddings("AES", new String[] {"PKCS7Padding"});
+        }
+
+        provideSslContextEnabledProtocols("TLS", TLSVersion.TLSv1, TLSVersion.TLSv13);
+        provideSslContextEnabledProtocols("TLSv1", TLSVersion.TLSv1, TLSVersion.TLSv12);
+        provideSslContextEnabledProtocols("TLSv1.1", TLSVersion.TLSv1, TLSVersion.TLSv12);
+        provideSslContextEnabledProtocols("TLSv1.2", TLSVersion.TLSv1, TLSVersion.TLSv12);
+        provideSslContextEnabledProtocols("TLSv1.3", TLSVersion.TLSv1, TLSVersion.TLSv13);
+        provideSslContextEnabledProtocols("Default", TLSVersion.TLSv1, TLSVersion.TLSv13);
+    }
+
+    public static final String SSL_CONTEXT_PROTOCOLS_DEFAULT = "Default";
+    public static final Set<String> SSL_CONTEXT_PROTOCOLS = new HashSet<String>(
+            Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
+    public static final Set<String> SSL_CONTEXT_PROTOCOLS_WITH_DEFAULT_CONFIG = new HashSet<String>(
+            Arrays.asList(SSL_CONTEXT_PROTOCOLS_DEFAULT, "TLS", "TLSv1.3"));
+
+    public static final Set<String> KEY_TYPES = new HashSet<String>(
+            Arrays.asList("RSA", "DSA", "DH_RSA", "DH_DSA", "EC", "EC_EC", "EC_RSA"));
+    static {
+        if (IS_RI) {
+            // DH_* are specified by standard names, but do not seem to be supported by RI
+            KEY_TYPES.remove("DH_RSA");
+            KEY_TYPES.remove("DH_DSA");
+        }
+    }
+
+    public static final Set<String> SSL_SOCKET_PROTOCOLS =
+            new HashSet<String>(Arrays.asList("TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"));
+
+    private enum TLSVersion {
+        SSLv3("SSLv3"),
+        TLSv1("TLSv1"),
+        TLSv11("TLSv1.1"),
+        TLSv12("TLSv1.2"),
+        TLSv13("TLSv1.3"),
+        ;
+
+        private final String name;
+
+        TLSVersion(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     * Valid values for X509TrustManager.checkClientTrusted authType,
+     * either the algorithm of the public key or UNKNOWN.
+     */
+    public static final Set<String> CLIENT_AUTH_TYPES =
+            new HashSet<String>(Arrays.asList("RSA", "DSA", "EC", "UNKNOWN"));
+
+    /**
+     * Valid values for X509TrustManager.checkServerTrusted authType,
+     * either key exchange algorithm part of the cipher suite, UNKNOWN,
+     * or GENERIC (for TLS 1.3 cipher suites that don't imply a specific
+     * key exchange method).
+     */
+    public static final Set<String> SERVER_AUTH_TYPES = new HashSet<String>(Arrays.asList("DHE_DSS",
+            "DHE_DSS_EXPORT", "DHE_RSA", "DHE_RSA_EXPORT", "DH_DSS_EXPORT", "DH_RSA_EXPORT",
+            "DH_anon", "DH_anon_EXPORT", "KRB5", "KRB5_EXPORT", "RSA", "RSA_EXPORT",
+            "RSA_EXPORT1024", "ECDH_ECDSA", "ECDH_RSA", "ECDHE_ECDSA", "ECDHE_RSA", "UNKNOWN",
+            "GENERIC"));
+
+    public static final String CIPHER_SUITE_INVALID = "SSL_NULL_WITH_NULL_NULL";
+
+    private static final Set<String> CIPHER_SUITES = new LinkedHashSet<String>();
+
+    private static void addOpenSsl(String cipherSuite) {
+        CIPHER_SUITES.add(cipherSuite);
+    }
+
+    static {
+        addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
+        addOpenSsl("TLS_RSA_WITH_AES_256_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
+        addOpenSsl("TLS_RSA_WITH_AES_128_CBC_SHA");
+        addOpenSsl("SSL_RSA_WITH_3DES_EDE_CBC_SHA");
+
+        // TLSv1.2 cipher suites
+        addOpenSsl("TLS_RSA_WITH_AES_128_GCM_SHA256");
+        addOpenSsl("TLS_RSA_WITH_AES_256_GCM_SHA384");
+        addOpenSsl("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+        addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
+        addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
+        addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
+        addOpenSsl("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256");
+        addOpenSsl("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256");
+
+        // Pre-Shared Key (PSK) cipher suites
+        addOpenSsl("TLS_PSK_WITH_AES_128_CBC_SHA");
+        addOpenSsl("TLS_PSK_WITH_AES_256_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
+        addOpenSsl("TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256");
+
+        // TLS 1.3 cipher suites
+        addOpenSsl("TLS_AES_128_GCM_SHA256");
+        addOpenSsl("TLS_AES_256_GCM_SHA384");
+        addOpenSsl("TLS_CHACHA20_POLY1305_SHA256");
+
+        // RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
+        addOpenSsl(CIPHER_SUITE_SECURE_RENEGOTIATION);
+
+        // From https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 to indicate
+        // TLS fallback request
+        addOpenSsl(CIPHER_SUITE_FALLBACK);
+    }
+
+    /**
+     * Cipher suites that are not negotiated when TLSv1.2 is selected on the RI.
+     */
+    public static final List<String> CIPHER_SUITES_OBSOLETE_TLS12 = Arrays.asList(
+            "SSL_RSA_WITH_DES_CBC_SHA",
+            "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+            "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+            "SSL_DH_anon_WITH_DES_CBC_SHA",
+            "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+            "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+            "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+            "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+            "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+            "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
+
+    /**
+     * Cipher suites that are only supported with TLS 1.3.
+     */
+    public static final List<String> CIPHER_SUITES_TLS13 = Arrays.asList(
+            "TLS_AES_128_GCM_SHA256",
+            "TLS_AES_256_GCM_SHA384",
+            "TLS_CHACHA20_POLY1305_SHA256");
+
+    // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+    // javax.net.ssl.SSLEngine.
+    private static final List<String> CIPHER_SUITES_AES_HARDWARE = Arrays.asList(
+            "TLS_AES_128_GCM_SHA256",
+            "TLS_AES_256_GCM_SHA384",
+            "TLS_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+            "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+            "TLS_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_RSA_WITH_AES_256_GCM_SHA384",
+            "TLS_RSA_WITH_AES_128_CBC_SHA",
+            "TLS_RSA_WITH_AES_256_CBC_SHA",
+            CIPHER_SUITE_SECURE_RENEGOTIATION);
+
+    // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+    // javax.net.ssl.SSLEngine.
+    private static final List<String> CIPHER_SUITES_SOFTWARE = Arrays.asList(
+            "TLS_AES_128_GCM_SHA256",
+            "TLS_AES_256_GCM_SHA384",
+            "TLS_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+            "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+            "TLS_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_RSA_WITH_AES_256_GCM_SHA384",
+            "TLS_RSA_WITH_AES_128_CBC_SHA",
+            "TLS_RSA_WITH_AES_256_CBC_SHA",
+            CIPHER_SUITE_SECURE_RENEGOTIATION);
+
+    // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+    // javax.net.ssl.SSLEngine.
+    public static final List<String> CIPHER_SUITES_DEFAULT = CpuFeatures.isAESHardwareAccelerated()
+            ? CIPHER_SUITES_AES_HARDWARE
+            : CIPHER_SUITES_SOFTWARE;
+
+    // NOTE: This list needs to be kept in sync with Javadoc of javax.net.ssl.SSLSocket and
+    // javax.net.ssl.SSLEngine.
+    public static final List<String> CIPHER_SUITES_DEFAULT_PSK = Arrays.asList(
+            "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
+            "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
+            "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
+            "TLS_PSK_WITH_AES_128_CBC_SHA",
+            "TLS_PSK_WITH_AES_256_CBC_SHA");
+
+    // Should be updated to match BoringSSL's defaults when they change.
+    // https://boringssl.googlesource.com/boringssl/+/master/ssl/t1_lib.cc#289
+    private static final List<String> ELLIPTIC_CURVES_DEFAULT =
+            Arrays.asList("x25519 (29)", "secp256r1 (23)", "secp384r1 (24)");
+
+    /**
+     * Asserts that the cipher suites array is non-null and that it
+     * all of its contents are cipher suites known to this
+     * implementation. As a convenience, returns any unenabled cipher
+     * suites in a test for those that want to verify separately that
+     * all cipher suites were included.
+     */
+    private static Set<String> assertValidCipherSuites(
+            Set<String> expected, String[] cipherSuites) {
+        assertNotNull(cipherSuites);
+        assertTrue(cipherSuites.length != 0);
+
+        // Make sure all cipherSuites names are expected
+        HashSet<String> remainingCipherSuites = new HashSet<String>(expected);
+        HashSet<String> unknownCipherSuites = new HashSet<String>();
+        for (String cipherSuite : cipherSuites) {
+            boolean removed = remainingCipherSuites.remove(cipherSuite);
+            if (!removed) {
+                unknownCipherSuites.add(cipherSuite);
+            }
+        }
+        assertEquals("Unknown cipher suites", Collections.EMPTY_SET, unknownCipherSuites);
+        return remainingCipherSuites;
+    }
+
+    /**
+     * After using assertValidCipherSuites on cipherSuites,
+     * assertSupportedCipherSuites additionally verifies that all
+     * supported cipher suites where in the input array.
+     */
+    private static void assertSupportedCipherSuites(Set<String> expected, String[] cipherSuites) {
+        Set<String> remainingCipherSuites = assertValidCipherSuites(expected, cipherSuites);
+        assertEquals("Missing cipher suites", Collections.EMPTY_SET, remainingCipherSuites);
+        assertEquals(expected.size(), cipherSuites.length);
+    }
+
+    /**
+     * Asserts that the protocols array is non-null and that it all of
+     * its contents are protocols known to this implementation. As a
+     * convenience, returns any unenabled protocols in a test for
+     * those that want to verify separately that all protocols were
+     * included.
+     */
+    private static Set<String> assertValidProtocols(Set<String> expected, String[] protocols) {
+        assertNotNull(protocols);
+        assertTrue(protocols.length != 0);
+
+        // Make sure all protocols names are expected
+        HashSet<String> remainingProtocols = new HashSet<String>(expected);
+        HashSet<String> unknownProtocols = new HashSet<String>();
+        for (String protocol : protocols) {
+            if (!remainingProtocols.remove(protocol)) {
+                unknownProtocols.add(protocol);
+            }
+        }
+        assertEquals("Unknown protocols", Collections.EMPTY_SET, unknownProtocols);
+        return remainingProtocols;
+    }
+
+    /**
+     * After using assertValidProtocols on protocols,
+     * assertSupportedProtocols additionally verifies that all
+     * supported protocols where in the input array.
+     */
+    private static void assertSupportedProtocols(Set<String> expected, String[] protocols) {
+        Set<String> remainingProtocols = assertValidProtocols(expected, protocols);
+        assertEquals("Missing protocols", Collections.EMPTY_SET, remainingProtocols);
+        assertEquals(expected.size(), protocols.length);
+    }
+
+    /**
+     * Asserts that the provided list of protocols matches the supported list of protocols.
+     */
+    public static void assertSupportedProtocols(String[] protocols) {
+        assertSupportedProtocols(SSL_SOCKET_PROTOCOLS, protocols);
+    }
+
+    /**
+     * Assert that the provided list of cipher suites contains only the supported cipher suites.
+     */
+    public static void assertValidCipherSuites(String[] cipherSuites) {
+        assertValidCipherSuites(CIPHER_SUITES, cipherSuites);
+    }
+
+    /**
+     * Assert that the provided list of cipher suites matches the supported list.
+     */
+    public static void assertSupportedCipherSuites(String[] cipherSuites) {
+        assertSupportedCipherSuites(CIPHER_SUITES, cipherSuites);
+    }
+
+    /**
+     * Assert cipher suites match the default list in content and priority order and contain
+     * only cipher suites permitted by default.
+     */
+    public static void assertDefaultCipherSuites(String[] cipherSuites) {
+        assertValidCipherSuites(cipherSuites);
+
+        Set<String> expected = new TreeSet<String>(CIPHER_SUITES_DEFAULT);
+        Set<String> actual = new TreeSet<String>(Arrays.asList(cipherSuites));
+        assertEquals(expected, actual);
+    }
+
+    public static void assertDefaultEllipticCurves(String[] curves) {
+        assertEquals(ELLIPTIC_CURVES_DEFAULT, Arrays.asList(curves));
+    }
+
+    public static void assertSSLContextEnabledProtocols(String version, String[] protocols) {
+        assertEquals("For protocol \"" + version + "\"",
+                Arrays.toString(SSL_CONTEXT_PROTOCOLS_ENABLED.get(version)),
+                Arrays.toString(protocols));
+    }
+
+    /**
+     * Get all supported mode names for the given cipher.
+     */
+    public static Set<String> getModesForCipher(String cipher) {
+        return CIPHER_MODES.get(cipher);
+    }
+
+    /**
+     * Get all supported padding names for the given cipher.
+     */
+    public static Set<String> getPaddingsForCipher(String cipher) {
+        return CIPHER_PADDINGS.get(cipher);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/TestHelper.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/TestHelper.java
new file mode 100644
index 0000000..92f3120
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/TestHelper.java
@@ -0,0 +1,25 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.java.security;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class TestHelper<T> {
+    public abstract void test(T testObject) throws Exception;
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/TestKeyStore.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/TestKeyStore.java
new file mode 100644
index 0000000..86568a3
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/TestKeyStore.java
@@ -0,0 +1,1155 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.java.security;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStore.PasswordProtection;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStore.TrustedCertificateEntry;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.UnrecoverableEntryException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import javax.crypto.spec.DHParameterSpec;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.security.auth.x500.X500Principal;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.CRLReason;
+import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.GeneralSubtree;
+import org.bouncycastle.asn1.x509.KeyPurposeId;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.asn1.x509.NameConstraints;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.CertificateID;
+import org.bouncycastle.cert.ocsp.CertificateStatus;
+import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.RevokedStatus;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.DigestCalculatorProvider;
+import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import com.android.org.conscrypt.javax.net.ssl.TestKeyManager;
+import com.android.org.conscrypt.javax.net.ssl.TestTrustManager;
+
+/**
+ * TestKeyStore is a convenience class for other tests that
+ * want a canned KeyStore with a variety of key pairs.
+ *
+ * Creating a key store is relatively slow, so a singleton instance is
+ * accessible via TestKeyStore.get().
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestKeyStore {
+    /** Size of DSA keys to generate for testing. */
+    private static final int DSA_KEY_SIZE_BITS = 1024;
+
+    /** Size of EC keys to generate for testing. */
+    private static final int EC_KEY_SIZE_BITS = 256;
+
+    /** Size of RSA keys to generate for testing. */
+    private static final int RSA_KEY_SIZE_BITS = 1024;
+
+    // Generated with: openssl dhparam -C 1024
+    private static final BigInteger DH_PARAMS_P = new BigInteger(1,
+            new byte[] {
+                    (byte) 0xA2, (byte) 0x31, (byte) 0xB4, (byte) 0xB3, (byte) 0x6D, (byte) 0x9B,
+                    (byte) 0x7E, (byte) 0xF4, (byte) 0xE7, (byte) 0x21, (byte) 0x51, (byte) 0x40,
+                    (byte) 0xEB, (byte) 0xC6, (byte) 0xB6, (byte) 0xD6, (byte) 0x54, (byte) 0x56,
+                    (byte) 0x72, (byte) 0xBE, (byte) 0x43, (byte) 0x18, (byte) 0x30, (byte) 0x5C,
+                    (byte) 0x15, (byte) 0x5A, (byte) 0xF9, (byte) 0x19, (byte) 0x62, (byte) 0xAD,
+                    (byte) 0xF4, (byte) 0x29, (byte) 0xCB, (byte) 0xC6, (byte) 0xF6, (byte) 0x64,
+                    (byte) 0x0B, (byte) 0x9D, (byte) 0x23, (byte) 0x80, (byte) 0xF9, (byte) 0x5B,
+                    (byte) 0x1C, (byte) 0x1C, (byte) 0x6A, (byte) 0xB4, (byte) 0xEA, (byte) 0xB9,
+                    (byte) 0x80, (byte) 0x98, (byte) 0x8B, (byte) 0xAF, (byte) 0x15, (byte) 0xA8,
+                    (byte) 0x5C, (byte) 0xC4, (byte) 0xB0, (byte) 0x41, (byte) 0x29, (byte) 0x66,
+                    (byte) 0x9F, (byte) 0x9F, (byte) 0x1F, (byte) 0x88, (byte) 0x50, (byte) 0x97,
+                    (byte) 0x38, (byte) 0x0B, (byte) 0x01, (byte) 0x16, (byte) 0xD6, (byte) 0x84,
+                    (byte) 0x1D, (byte) 0x48, (byte) 0x6F, (byte) 0x7C, (byte) 0x06, (byte) 0x8C,
+                    (byte) 0x6E, (byte) 0x68, (byte) 0xCD, (byte) 0x38, (byte) 0xE6, (byte) 0x22,
+                    (byte) 0x30, (byte) 0x61, (byte) 0x37, (byte) 0x02, (byte) 0x3D, (byte) 0x47,
+                    (byte) 0x62, (byte) 0xCE, (byte) 0xB9, (byte) 0x1A, (byte) 0x69, (byte) 0x9D,
+                    (byte) 0xA1, (byte) 0x9F, (byte) 0x10, (byte) 0xA1, (byte) 0xAA, (byte) 0x70,
+                    (byte) 0xF7, (byte) 0x27, (byte) 0x9C, (byte) 0xD4, (byte) 0xA5, (byte) 0x15,
+                    (byte) 0xE2, (byte) 0x15, (byte) 0x0C, (byte) 0x20, (byte) 0x90, (byte) 0x08,
+                    (byte) 0xB6, (byte) 0xF5, (byte) 0xDF, (byte) 0x1C, (byte) 0xCB, (byte) 0x82,
+                    (byte) 0x6D, (byte) 0xC0, (byte) 0xE1, (byte) 0xBD, (byte) 0xCC, (byte) 0x4A,
+                    (byte) 0x76, (byte) 0xE3,
+            });
+
+    // generator of 2
+    private static final BigInteger DH_PARAMS_G = BigInteger.valueOf(2);
+
+    private static TestKeyStore ROOT_CA;
+    private static TestKeyStore INTERMEDIATE_CA;
+    private static TestKeyStore INTERMEDIATE_CA_2;
+    private static TestKeyStore INTERMEDIATE_CA_EC;
+
+    private static TestKeyStore SERVER;
+    private static TestKeyStore SERVER_HOSTNAME;
+    private static TestKeyStore CLIENT;
+    private static TestKeyStore CLIENT_CERTIFICATE;
+    private static TestKeyStore CLIENT_EC_RSA_CERTIFICATE;
+    private static TestKeyStore CLIENT_EC_EC_CERTIFICATE;
+
+    private static TestKeyStore CLIENT_2;
+
+    static {
+        if (!StandardNames.IS_RI
+                && !BouncyCastleProvider.class.getName().startsWith("com.android")) {
+            // If we run outside of the Android system, we need to make sure
+            // that the BouncyCastleProvider's static field keyInfoConverters
+            // is initialized. This happens in the default constructor only.
+            new BouncyCastleProvider();
+        }
+    }
+
+    private static final byte[] LOCAL_HOST_ADDRESS = {127, 0, 0, 1};
+    private static final String LOCAL_HOST_NAME = "localhost";
+    private static final String LOCAL_HOST_NAME_IPV6 = "ip6-localhost";
+    public static final String CERT_HOSTNAME = "example.com";
+
+    public final KeyStore keyStore;
+    public final char[] storePassword;
+    public final char[] keyPassword;
+    public final KeyManager[] keyManagers;
+    public final TrustManager[] trustManagers;
+    public final TrustManager trustManager;
+
+    private TestKeyStore(KeyStore keyStore, char[] storePassword, char[] keyPassword) {
+        this.keyStore = keyStore;
+        this.storePassword = storePassword;
+        this.keyPassword = keyPassword;
+        this.keyManagers = createKeyManagers(keyStore, storePassword);
+        this.trustManagers = createTrustManagers(keyStore);
+        this.trustManager = trustManagers[0];
+    }
+
+    public static KeyManager[] createKeyManagers(KeyStore keyStore, char[] storePassword) {
+        try {
+            String kmfa = KeyManagerFactory.getDefaultAlgorithm();
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfa);
+            kmf.init(keyStore, storePassword);
+            return TestKeyManager.wrap(kmf.getKeyManagers());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static TrustManager[] createTrustManagers(final KeyStore keyStore) {
+        try {
+            String tmfa = TrustManagerFactory.getDefaultAlgorithm();
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa);
+            tmf.init(keyStore);
+            return TestTrustManager.wrap(tmf.getTrustManagers());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Lazily create shared test certificates.
+     */
+    private static synchronized void initCerts() {
+        if (ROOT_CA != null) {
+            return;
+        }
+        ROOT_CA = new Builder()
+                          .aliasPrefix("RootCA")
+                          .subject("CN=Test Root Certificate Authority")
+                          .ca(true)
+                          .certificateSerialNumber(BigInteger.valueOf(1))
+                          .build();
+        INTERMEDIATE_CA_EC = new Builder()
+                                     .aliasPrefix("IntermediateCA-EC")
+                                     .keyAlgorithms("EC")
+                                     .subject("CN=Test Intermediate Certificate Authority ECDSA")
+                                     .ca(true)
+                                     .signer(ROOT_CA.getPrivateKey("RSA", "RSA"))
+                                     .rootCa(ROOT_CA.getRootCertificate("RSA"))
+                                     .certificateSerialNumber(BigInteger.valueOf(2))
+                                     .build();
+        INTERMEDIATE_CA = new Builder()
+                                  .aliasPrefix("IntermediateCA")
+                                  .subject("CN=Test Intermediate Certificate Authority")
+                                  .ca(true)
+                                  .signer(ROOT_CA.getPrivateKey("RSA", "RSA"))
+                                  .rootCa(ROOT_CA.getRootCertificate("RSA"))
+                                  .certificateSerialNumber(BigInteger.valueOf(2))
+                                  .build();
+        SERVER = new Builder()
+                         .aliasPrefix("server")
+                         .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA"))
+                         .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA"))
+                         .addSubjectAltNameIpAddress(LOCAL_HOST_ADDRESS)
+                         .certificateSerialNumber(BigInteger.valueOf(3))
+                         .build();
+        SERVER_HOSTNAME = new Builder()
+                                  .aliasPrefix("server-hostname")
+                                  .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA"))
+                                  .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA"))
+                                  .addSubjectAltNameDnsName(CERT_HOSTNAME)
+                                  .certificateSerialNumber(BigInteger.valueOf(4))
+                                  .build();
+        CLIENT = new TestKeyStore(createClient(INTERMEDIATE_CA.keyStore), null, null);
+        CLIENT_EC_RSA_CERTIFICATE = new Builder()
+                                            .aliasPrefix("client-ec")
+                                            .keyAlgorithms("EC")
+                                            .subject("emailAddress=test-ec@user")
+                                            .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA"))
+                                            .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA"))
+                                            .build();
+        CLIENT_EC_EC_CERTIFICATE = new Builder()
+                                           .aliasPrefix("client-ec")
+                                           .keyAlgorithms("EC")
+                                           .subject("emailAddress=test-ec@user")
+                                           .signer(INTERMEDIATE_CA_EC.getPrivateKey("EC", "RSA"))
+                                           .rootCa(INTERMEDIATE_CA_EC.getRootCertificate("RSA"))
+                                           .build();
+        CLIENT_CERTIFICATE = new Builder()
+                                     .aliasPrefix("client")
+                                     .subject("emailAddress=test@user")
+                                     .signer(INTERMEDIATE_CA.getPrivateKey("RSA", "RSA"))
+                                     .rootCa(INTERMEDIATE_CA.getRootCertificate("RSA"))
+                                     .build();
+        TestKeyStore rootCa2 = new Builder()
+                                       .aliasPrefix("RootCA2")
+                                       .subject("CN=Test Root Certificate Authority 2")
+                                       .ca(true)
+                                       .build();
+        INTERMEDIATE_CA_2 = new Builder()
+                                    .aliasPrefix("IntermediateCA")
+                                    .subject("CN=Test Intermediate Certificate Authority")
+                                    .ca(true)
+                                    .signer(rootCa2.getPrivateKey("RSA", "RSA"))
+                                    .rootCa(rootCa2.getRootCertificate("RSA"))
+                                    .build();
+        CLIENT_2 = new TestKeyStore(createClient(rootCa2.keyStore), null, null);
+    }
+
+    /**
+     * Return an root CA that can be used to issue new certificates.
+     */
+    public static TestKeyStore getRootCa() {
+        initCerts();
+        return ROOT_CA;
+    }
+
+    /**
+     * Return an intermediate CA that can be used to issue new certificates.
+     */
+    public static TestKeyStore getIntermediateCa() {
+        initCerts();
+        return INTERMEDIATE_CA;
+    }
+
+    /**
+     * Return an intermediate CA that can be used to issue new certificates.
+     */
+    public static TestKeyStore getIntermediateCa2() {
+        initCerts();
+        return INTERMEDIATE_CA_2;
+    }
+
+    /**
+     * Return a server keystore with a matched RSA certificate and
+     * private key as well as a CA certificate.
+     */
+    public static TestKeyStore getServer() {
+        initCerts();
+        return SERVER;
+    }
+
+    /**
+     * Return a server keystore with a matched RSA certificate with SAN hostname and private key
+     * as well as a CA certificate.
+     */
+    public static TestKeyStore getServerHostname() {
+        initCerts();
+        return SERVER_HOSTNAME;
+    }
+
+    /**
+     * Return a keystore with a CA certificate
+     */
+    public static TestKeyStore getClient() {
+        initCerts();
+        return CLIENT;
+    }
+
+    /**
+     * Return a client keystore with a matched RSA certificate and
+     * private key as well as a CA certificate.
+     */
+    public static TestKeyStore getClientCertificate() {
+        initCerts();
+        return CLIENT_CERTIFICATE;
+    }
+
+    /**
+     * Return a client keystore with a matched RSA certificate and
+     * private key as well as a CA certificate.
+     */
+    public static TestKeyStore getClientEcRsaCertificate() {
+        initCerts();
+        return CLIENT_EC_RSA_CERTIFICATE;
+    }
+
+    /**
+     * Return a client keystore with a matched RSA certificate and
+     * private key as well as a CA certificate.
+     */
+    public static TestKeyStore getClientEcEcCertificate() {
+        initCerts();
+        return CLIENT_EC_EC_CERTIFICATE;
+    }
+
+    /**
+     * Return a keystore with a second CA certificate that does not
+     * trust the server certificate returned by getServer for negative
+     * testing.
+     */
+    public static TestKeyStore getClientCA2() {
+        initCerts();
+        return CLIENT_2;
+    }
+
+    /**
+     * Creates KeyStores containing the requested key types. Since key
+     * generation can be expensive, most tests should reuse the RSA-only
+     * singleton instance returned by TestKeyStore.get.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class Builder {
+        private String[] keyAlgorithms = {"RSA"};
+        private char[] storePassword;
+        private char[] keyPassword;
+        private String aliasPrefix;
+        private X500Principal subject;
+        private int keyUsage;
+        private boolean ca;
+        private PrivateKeyEntry privateEntry;
+        private PrivateKeyEntry signer;
+        private Certificate rootCa;
+        private final List<KeyPurposeId> extendedKeyUsages = new ArrayList<KeyPurposeId>();
+        private final List<Boolean> criticalExtendedKeyUsages = new ArrayList<Boolean>();
+        private final List<GeneralName> subjectAltNames = new ArrayList<GeneralName>();
+        private final List<GeneralSubtree> permittedNameConstraints =
+                new ArrayList<GeneralSubtree>();
+        private final List<GeneralSubtree> excludedNameConstraints =
+                new ArrayList<GeneralSubtree>();
+        // Generated randomly if not set
+        private BigInteger certificateSerialNumber = null;
+
+        public Builder() {
+        }
+
+        /**
+         * Sets the requested key types to generate and include. The default is
+         * RSA only.
+         */
+        public Builder keyAlgorithms(String... keyAlgorithms) {
+            this.keyAlgorithms = keyAlgorithms;
+            return this;
+        }
+
+        /** A unique prefix to identify the key aliases */
+        public Builder aliasPrefix(String aliasPrefix) {
+            this.aliasPrefix = aliasPrefix;
+            return this;
+        }
+
+        /**
+         * Sets the subject common name. The default is the local host's
+         * canonical name.
+         */
+        public Builder subject(X500Principal subject) {
+            this.subject = subject;
+            return this;
+        }
+
+        public Builder subject(String commonName) {
+            return subject(new X500Principal(commonName));
+        }
+
+        /** {@link KeyUsage} bit mask for 2.5.29.15 extension */
+        public Builder keyUsage(int keyUsage) {
+            this.keyUsage = keyUsage;
+            return this;
+        }
+
+        /** true If the keys being created are for a CA */
+        public Builder ca(boolean ca) {
+            this.ca = ca;
+            return this;
+        }
+
+        /** a private key entry to use for the generation of the certificate */
+        public Builder privateEntry(PrivateKeyEntry privateEntry) {
+            this.privateEntry = privateEntry;
+            return this;
+        }
+
+        /** a private key entry to be used for signing, otherwise self-sign */
+        public Builder signer(PrivateKeyEntry signer) {
+            this.signer = signer;
+            return this;
+        }
+
+        /** a root CA to include in the final store */
+        public Builder rootCa(Certificate rootCa) {
+            this.rootCa = rootCa;
+            return this;
+        }
+
+        public Builder addExtendedKeyUsage(KeyPurposeId keyPurposeId, boolean critical) {
+            extendedKeyUsages.add(keyPurposeId);
+            criticalExtendedKeyUsages.add(critical);
+            return this;
+        }
+
+        public Builder addSubjectAltName(GeneralName generalName) {
+            subjectAltNames.add(generalName);
+            return this;
+        }
+
+        public Builder addSubjectAltNameDnsName(String dnsName) {
+            return addSubjectAltName(
+                    new GeneralName(GeneralName.dNSName, dnsName));
+        }
+
+        public Builder addSubjectAltNameIpAddress(byte[] ipAddress) {
+            return addSubjectAltName(
+                    new GeneralName(GeneralName.iPAddress, new DEROctetString(ipAddress)));
+        }
+
+        private Builder addNameConstraint(boolean permitted, GeneralName generalName) {
+            if (permitted) {
+                permittedNameConstraints.add(new GeneralSubtree(generalName));
+            } else {
+                excludedNameConstraints.add(new GeneralSubtree(generalName));
+            }
+            return this;
+        }
+
+        public Builder addNameConstraint(boolean permitted, byte[] ipAddress) {
+            return addNameConstraint(permitted,
+                    new GeneralName(GeneralName.iPAddress, new DEROctetString(ipAddress)));
+        }
+
+        public Builder certificateSerialNumber(BigInteger certificateSerialNumber) {
+            this.certificateSerialNumber = certificateSerialNumber;
+            return this;
+        }
+
+        public TestKeyStore build() {
+            try {
+                if (StandardNames.IS_RI) {
+                    // JKS does not allow null password
+                    if (storePassword == null) {
+                        storePassword = "password".toCharArray();
+                    }
+                    if (keyPassword == null) {
+                        keyPassword = "password".toCharArray();
+                    }
+                }
+
+                /*
+                 * This is not implemented for other key types because the logic
+                 * would be long to write and it's not needed currently.
+                 */
+                if (privateEntry != null
+                        && (keyAlgorithms.length != 1 || !"RSA".equals(keyAlgorithms[0]))) {
+                    throw new IllegalStateException(
+                            "Only reusing an existing key is implemented for RSA");
+                }
+
+                KeyStore keyStore = createKeyStore();
+                for (String keyAlgorithm : keyAlgorithms) {
+                    String publicAlias = aliasPrefix + "-public-" + keyAlgorithm;
+                    String privateAlias = aliasPrefix + "-private-" + keyAlgorithm;
+                    if ((keyAlgorithm.equals("EC_RSA") || keyAlgorithm.equals("DH_RSA"))
+                            && signer == null && rootCa == null) {
+                        createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, null,
+                                privateKey(keyStore, keyPassword, "RSA", "RSA"));
+                        continue;
+                    } else if (keyAlgorithm.equals("DH_DSA") && signer == null && rootCa == null) {
+                        createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, null,
+                                privateKey(keyStore, keyPassword, "DSA", "DSA"));
+                        continue;
+                    }
+                    createKeys(keyStore, keyAlgorithm, publicAlias, privateAlias, privateEntry,
+                            signer);
+                }
+                if (rootCa != null) {
+                    keyStore.setCertificateEntry(
+                            aliasPrefix + "-root-ca-" + rootCa.getPublicKey().getAlgorithm(),
+                            rootCa);
+                }
+                return new TestKeyStore(keyStore, storePassword, keyPassword);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /**
+         * Add newly generated keys of a given key type to an existing
+         * KeyStore. The PrivateKey will be stored under the specified
+         * private alias name. The X509Certificate will be stored on the
+         * public alias name and have the given subject distinguished
+         * name.
+         *
+         * If a CA is provided, it will be used to sign the generated
+         * certificate and OCSP responses. Otherwise, the certificate
+         * will be self signed. The certificate will be valid for one
+         * day before and one day after the time of creation.
+         *
+         * Based on:
+         * org.bouncycastle.jce.provider.test.SigTest
+         * org.bouncycastle.jce.provider.test.CertTest
+         */
+        private KeyStore createKeys(KeyStore keyStore, String keyAlgorithm, String publicAlias,
+                String privateAlias, PrivateKeyEntry privateEntry, PrivateKeyEntry signer)
+                throws Exception {
+            PrivateKey caKey;
+            X509Certificate caCert;
+            X509Certificate[] caCertChain;
+            if (signer == null) {
+                caKey = null;
+                caCert = null;
+                caCertChain = null;
+            } else {
+                caKey = signer.getPrivateKey();
+                caCert = (X509Certificate) signer.getCertificate();
+                caCertChain = (X509Certificate[]) signer.getCertificateChain();
+            }
+
+            // Default to localhost if nothing was specified.
+            if (subject == null) {
+                subject = localhost();
+                addSubjectAltNameDnsName(LOCAL_HOST_NAME);
+                addSubjectAltNameDnsName(LOCAL_HOST_NAME_IPV6);
+            }
+
+            final PrivateKey privateKey;
+            final PublicKey publicKey;
+            X509Certificate x509c;
+            if (publicAlias == null && privateAlias == null) {
+                // don't want anything apparently
+                privateKey = null;
+                publicKey = null;
+                x509c = null;
+            } else {
+                if (privateEntry == null) {
+                    // 1a.) we make the keys
+                    int keySize = -1;
+                    AlgorithmParameterSpec spec = null;
+                    if (keyAlgorithm.equals("RSA")) {
+                        keySize = RSA_KEY_SIZE_BITS;
+                    } else if (keyAlgorithm.equals("DH_RSA")) {
+                        spec = new DHParameterSpec(DH_PARAMS_P, DH_PARAMS_G);
+                        keyAlgorithm = "DH";
+                    } else if (keyAlgorithm.equals("DSA")) {
+                        keySize = DSA_KEY_SIZE_BITS;
+                    } else if (keyAlgorithm.equals("DH_DSA")) {
+                        spec = new DHParameterSpec(DH_PARAMS_P, DH_PARAMS_G);
+                        keyAlgorithm = "DH";
+                    } else if (keyAlgorithm.equals("EC")) {
+                        keySize = EC_KEY_SIZE_BITS;
+                    } else if (keyAlgorithm.equals("EC_RSA")) {
+                        keySize = EC_KEY_SIZE_BITS;
+                        keyAlgorithm = "EC";
+                    } else {
+                        throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm);
+                    }
+
+                    KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgorithm);
+                    if (spec != null) {
+                        kpg.initialize(spec);
+                    } else if (keySize != -1) {
+                        kpg.initialize(keySize);
+                    } else {
+                        throw new AssertionError(
+                                "Must either have set algorithm parameters or key size!");
+                    }
+
+                    KeyPair kp = kpg.generateKeyPair();
+                    privateKey = kp.getPrivate();
+                    publicKey = kp.getPublic();
+                } else {
+                    // 1b.) we use the previous keys
+                    privateKey = privateEntry.getPrivateKey();
+                    publicKey = privateEntry.getCertificate().getPublicKey();
+                }
+
+                // 2.) use keys to make certificate
+                X500Principal issuer =
+                        ((caCert != null) ? caCert.getSubjectX500Principal() : subject);
+                PrivateKey signingKey = (caKey == null) ? privateKey : caKey;
+                x509c = createCertificate(publicKey, signingKey, subject, issuer, keyUsage, ca,
+                        extendedKeyUsages, criticalExtendedKeyUsages, subjectAltNames,
+                        permittedNameConstraints, excludedNameConstraints, certificateSerialNumber);
+            }
+
+            X509Certificate[] x509cc;
+            if (privateAlias == null) {
+                // don't need certificate chain
+                x509cc = null;
+            } else if (caCertChain == null) {
+                x509cc = new X509Certificate[] {x509c};
+            } else {
+                x509cc = new X509Certificate[caCertChain.length + 1];
+                x509cc[0] = x509c;
+                System.arraycopy(caCertChain, 0, x509cc, 1, caCertChain.length);
+            }
+
+            // 3.) put certificate and private key into the key store
+            if (privateAlias != null) {
+                keyStore.setKeyEntry(privateAlias, privateKey, keyPassword, x509cc);
+            }
+            if (publicAlias != null) {
+                keyStore.setCertificateEntry(publicAlias, x509c);
+            }
+            return keyStore;
+        }
+
+        private X500Principal localhost() {
+            return new X500Principal("CN=" + LOCAL_HOST_NAME);
+        }
+    }
+
+    public static X509Certificate createCa(
+            PublicKey publicKey, PrivateKey privateKey, String subject) {
+        try {
+            X500Principal principal = new X500Principal(subject);
+            return createCertificate(publicKey, privateKey, principal, principal, 0, true,
+                    new ArrayList<KeyPurposeId>(), new ArrayList<Boolean>(),
+                    new ArrayList<GeneralName>(), new ArrayList<GeneralSubtree>(),
+                    new ArrayList<GeneralSubtree>(), null /* serialNumber, generated randomly */);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static X509Certificate createCertificate(PublicKey publicKey, PrivateKey privateKey,
+            X500Principal subject, X500Principal issuer, int keyUsage, boolean ca,
+            List<KeyPurposeId> extendedKeyUsages, List<Boolean> criticalExtendedKeyUsages,
+            List<GeneralName> subjectAltNames, List<GeneralSubtree> permittedNameConstraints,
+            List<GeneralSubtree> excludedNameConstraints, BigInteger serialNumber)
+            throws Exception {
+        // Note that there is no way to programmatically make a
+        // Certificate using java.* or javax.* APIs. The
+        // CertificateFactory interface assumes you want to read
+        // in a stream of bytes, typically the X.509 factory would
+        // allow ASN.1 DER encoded bytes and optionally some PEM
+        // formats. Here we use Bouncy Castle's
+        // X509V3CertificateGenerator and related classes.
+
+        long millisPerDay = 24 * 60 * 60 * 1000;
+        long now = System.currentTimeMillis();
+        Date start = new Date(now - millisPerDay);
+        Date end = new Date(now + millisPerDay);
+
+        String keyAlgorithm = privateKey.getAlgorithm();
+        String signatureAlgorithm;
+        if (keyAlgorithm.equals("RSA")) {
+            signatureAlgorithm = "sha256WithRSA";
+        } else if (keyAlgorithm.equals("DSA")) {
+            signatureAlgorithm = "sha256WithDSA";
+        } else if (keyAlgorithm.equals("EC")) {
+            signatureAlgorithm = "sha256WithECDSA";
+        } else if (keyAlgorithm.equals("EC_RSA")) {
+            signatureAlgorithm = "sha256WithRSA";
+        } else {
+            throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm);
+        }
+
+        if (serialNumber == null) {
+            byte[] serialBytes = new byte[16];
+            new SecureRandom().nextBytes(serialBytes);
+            serialNumber = new BigInteger(1, serialBytes);
+        }
+
+        X509v3CertificateBuilder x509cg =
+                new X509v3CertificateBuilder(X500Name.getInstance(issuer.getEncoded()),
+                        serialNumber, start, end, X500Name.getInstance(subject.getEncoded()),
+                        SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+        if (keyUsage != 0) {
+            x509cg.addExtension(Extension.keyUsage, true, new KeyUsage(keyUsage));
+        }
+        if (ca) {
+            x509cg.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));
+        }
+        for (int i = 0; i < extendedKeyUsages.size(); i++) {
+            KeyPurposeId keyPurposeId = extendedKeyUsages.get(i);
+            boolean critical = criticalExtendedKeyUsages.get(i);
+            x509cg.addExtension(
+                    Extension.extendedKeyUsage, critical, new ExtendedKeyUsage(keyPurposeId));
+        }
+        if (!subjectAltNames.isEmpty()) {
+            x509cg.addExtension(Extension.subjectAlternativeName, false,
+                    new GeneralNames(subjectAltNames.toArray(new GeneralName[0])).getEncoded());
+        }
+        if (!permittedNameConstraints.isEmpty() || !excludedNameConstraints.isEmpty()) {
+            x509cg.addExtension(Extension.nameConstraints, true,
+                    new NameConstraints(
+                            permittedNameConstraints.toArray(
+                                    new GeneralSubtree[permittedNameConstraints.size()]),
+                            excludedNameConstraints.toArray(
+                                    new GeneralSubtree[excludedNameConstraints.size()])));
+        }
+
+        X509CertificateHolder x509holder =
+                x509cg.build(new JcaContentSignerBuilder(signatureAlgorithm).build(privateKey));
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        X509Certificate x509c = (X509Certificate) certFactory.generateCertificate(
+                new ByteArrayInputStream(x509holder.getEncoded()));
+        if (StandardNames.IS_RI) {
+            /*
+             * The RI can't handle the BC EC signature algorithm
+             * string of "ECDSA", since it expects "...WITHEC...",
+             * so convert from BC to RI X509Certificate
+             * implementation via bytes.
+             */
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            ByteArrayInputStream bais = new ByteArrayInputStream(x509c.getEncoded());
+            Certificate c = cf.generateCertificate(bais);
+            x509c = (X509Certificate) c;
+        }
+        return x509c;
+    }
+
+    /**
+     * Return the key algorithm for a possible compound algorithm
+     * identifier containing an underscore. If not underscore is
+     * present, the argument is returned unmodified. However for an
+     * algorithm such as EC_RSA, return EC.
+     */
+    public static String keyAlgorithm(String algorithm) {
+        int index = algorithm.indexOf('_');
+        if (index == -1) {
+            return algorithm;
+        }
+        return algorithm.substring(0, index);
+    }
+
+    /**
+     * Return the signature algorithm for a possible compound
+     * algorithm identifier containing an underscore. If not
+     * underscore is present, the argument is returned
+     * unmodified. However for an algorithm such as EC_RSA, return
+     * RSA.
+     */
+    public static String signatureAlgorithm(String algorithm) {
+        int index = algorithm.indexOf('_');
+        if (index == -1) {
+            return algorithm;
+        }
+        return algorithm.substring(index + 1, algorithm.length());
+    }
+
+    /**
+     * Create an empty KeyStore
+     */
+    public static KeyStore createKeyStore() {
+        try {
+            KeyStore keyStore = KeyStore.getInstance(StandardNames.KEY_STORE_ALGORITHM);
+            keyStore.load(null, null);
+            return keyStore;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Return the only private key in a TestKeyStore for the given
+     * algorithms. Throws IllegalStateException if there are are more
+     * or less than one.
+     */
+    public PrivateKeyEntry getPrivateKey(String keyAlgorithm, String signatureAlgorithm) {
+        return privateKey(keyStore, keyPassword, keyAlgorithm, signatureAlgorithm);
+    }
+
+    /**
+     * Return the only private key in a keystore for the given
+     * algorithms. Throws IllegalStateException if there are are more
+     * or less than one.
+     */
+    public static PrivateKeyEntry privateKey(
+            KeyStore keyStore, char[] keyPassword, String keyAlgorithm, String signatureAlgorithm) {
+        try {
+            PrivateKeyEntry found = null;
+            PasswordProtection password = new PasswordProtection(keyPassword);
+            for (String alias : Collections.list(keyStore.aliases())) {
+                if (!keyStore.entryInstanceOf(alias, PrivateKeyEntry.class)) {
+                    continue;
+                }
+                PrivateKeyEntry privateKey = (PrivateKeyEntry) keyStore.getEntry(alias, password);
+                if (!privateKey.getPrivateKey().getAlgorithm().equals(keyAlgorithm)) {
+                    continue;
+                }
+                X509Certificate certificate = (X509Certificate) privateKey.getCertificate();
+                if (!certificate.getSigAlgName().contains(signatureAlgorithm)) {
+                    continue;
+                }
+                if (found != null) {
+                    throw new IllegalStateException("KeyStore has more than one private key for"
+                            + " keyAlgorithm: " + keyAlgorithm + " signatureAlgorithm: "
+                            + signatureAlgorithm + "\nfirst: " + found.getPrivateKey()
+                            + "\nsecond: " + privateKey.getPrivateKey());
+                }
+                found = privateKey;
+            }
+            if (found == null) {
+                throw new IllegalStateException("KeyStore contained no private key for"
+                        + " keyAlgorithm: " + keyAlgorithm
+                        + " signatureAlgorithm: " + signatureAlgorithm);
+            }
+            return found;
+        } catch (Exception e) {
+            throw new RuntimeException("Problem getting key for " + keyAlgorithm + " and signature "
+                            + signatureAlgorithm,
+                    e);
+        }
+    }
+
+    /**
+     * Return the issuing CA certificate of the given
+     * certificate. Throws IllegalStateException if there are are more
+     * or less than one.
+     */
+    public Certificate getIssuer(Certificate cert) throws Exception {
+        return issuer(keyStore, cert);
+    }
+
+    /**
+     * Return the issuing CA certificate of the given
+     * certificate. Throws IllegalStateException if there are are more
+     * or less than one.
+     */
+    public static Certificate issuer(KeyStore keyStore, Certificate c) throws Exception {
+        if (!(c instanceof X509Certificate)) {
+            throw new IllegalStateException("issuer requires an X509Certificate, found " + c);
+        }
+        X509Certificate cert = (X509Certificate) c;
+
+        Certificate found = null;
+        for (String alias : Collections.list(keyStore.aliases())) {
+            if (!keyStore.entryInstanceOf(alias, TrustedCertificateEntry.class)) {
+                continue;
+            }
+            TrustedCertificateEntry certificateEntry =
+                    (TrustedCertificateEntry) keyStore.getEntry(alias, null);
+            Certificate certificate = certificateEntry.getTrustedCertificate();
+            if (!(certificate instanceof X509Certificate)) {
+                continue;
+            }
+            X509Certificate x = (X509Certificate) certificate;
+            if (!cert.getIssuerDN().equals(x.getSubjectDN())) {
+                continue;
+            }
+            if (found != null) {
+                throw new IllegalStateException("KeyStore has more than one issuing CA for " + cert
+                        + "\nfirst: " + found + "\nsecond: " + certificate);
+            }
+            found = certificate;
+        }
+        if (found == null) {
+            throw new IllegalStateException("KeyStore contained no issuing CA for " + cert);
+        }
+        return found;
+    }
+
+    /**
+     * Return the only self-signed root certificate in a TestKeyStore
+     * for the given algorithm. Throws IllegalStateException if there
+     * are are more or less than one.
+     */
+    public X509Certificate getRootCertificate(String algorithm) {
+        return rootCertificate(keyStore, algorithm);
+    }
+
+    private static OCSPResp generateOCSPResponse(PrivateKeyEntry server, PrivateKeyEntry issuer,
+            CertificateStatus status) throws CertificateException {
+        try {
+            X509Certificate serverCertJca = (X509Certificate) server.getCertificate();
+            X509Certificate caCertJca = (X509Certificate) issuer.getCertificate();
+
+            X509CertificateHolder caCert = new JcaX509CertificateHolder(caCertJca);
+
+            DigestCalculatorProvider digCalcProv = new BcDigestCalculatorProvider();
+            BasicOCSPRespBuilder basicBuilder = new BasicOCSPRespBuilder(
+                    SubjectPublicKeyInfo.getInstance(caCertJca.getPublicKey().getEncoded()),
+                    digCalcProv.get(CertificateID.HASH_SHA1));
+
+            CertificateID certId = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1),
+                    caCert, serverCertJca.getSerialNumber());
+
+            basicBuilder.addResponse(certId, status);
+
+            BasicOCSPResp resp = basicBuilder.build(
+                    new JcaContentSignerBuilder("SHA256withRSA").build(issuer.getPrivateKey()),
+                    null, new Date());
+
+            OCSPRespBuilder builder = new OCSPRespBuilder();
+            return builder.build(OCSPRespBuilder.SUCCESSFUL, resp);
+        } catch (Exception e) {
+            throw new CertificateException("cannot generate OCSP response", e);
+        }
+    }
+
+    public static byte[] getOCSPResponseForGood(PrivateKeyEntry server, PrivateKeyEntry issuer)
+            throws CertificateException {
+        try {
+            return generateOCSPResponse(server, issuer, CertificateStatus.GOOD).getEncoded();
+        } catch (IOException e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    public static byte[] getOCSPResponseForRevoked(PrivateKeyEntry server, PrivateKeyEntry issuer)
+            throws CertificateException {
+        try {
+            return generateOCSPResponse(
+                    server, issuer, new RevokedStatus(new Date(), CRLReason.keyCompromise))
+                    .getEncoded();
+        } catch (IOException e) {
+            throw new CertificateException(e);
+        }
+    }
+
+    /**
+     * Return the only self-signed root certificate in a keystore for
+     * the given algorithm. Throws IllegalStateException if there are
+     * are more or less than one.
+     */
+    public static X509Certificate rootCertificate(KeyStore keyStore, String algorithm) {
+        try {
+            X509Certificate found = null;
+            for (String alias : Collections.list(keyStore.aliases())) {
+                if (!keyStore.entryInstanceOf(alias, TrustedCertificateEntry.class)) {
+                    continue;
+                }
+                TrustedCertificateEntry certificateEntry =
+                        (TrustedCertificateEntry) keyStore.getEntry(alias, null);
+                Certificate certificate = certificateEntry.getTrustedCertificate();
+                if (!certificate.getPublicKey().getAlgorithm().equals(algorithm)) {
+                    continue;
+                }
+                if (!(certificate instanceof X509Certificate)) {
+                    continue;
+                }
+                X509Certificate x = (X509Certificate) certificate;
+                if (!x.getIssuerDN().equals(x.getSubjectDN())) {
+                    continue;
+                }
+                if (found != null) {
+                    throw new IllegalStateException("KeyStore has more than one root CA for "
+                            + algorithm + "\nfirst: " + found + "\nsecond: " + certificate);
+                }
+                found = x;
+            }
+            if (found == null) {
+                throw new IllegalStateException("KeyStore contained no root CA for " + algorithm);
+            }
+            return found;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Return an {@code X509Certificate} that matches the given {@code alias}.
+     */
+    public KeyStore.Entry getEntryByAlias(String alias) {
+        return entryByAlias(keyStore, alias);
+    }
+
+    /**
+     * Finds an entry in the keystore by the given alias.
+     */
+    public static KeyStore.Entry entryByAlias(KeyStore keyStore, String alias) {
+        try {
+            return keyStore.getEntry(alias, null);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        } catch (UnrecoverableEntryException e) {
+            throw new RuntimeException(e);
+        } catch (KeyStoreException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Create a client key store that only contains self-signed certificates but no private keys
+     */
+    public static KeyStore createClient(KeyStore caKeyStore) {
+        KeyStore clientKeyStore = createKeyStore();
+        copySelfSignedCertificates(clientKeyStore, caKeyStore);
+        return clientKeyStore;
+    }
+
+    /**
+     * Copy self-signed certificates from one key store to another.
+     * Returns true if successful, false if no match found.
+     */
+    public static boolean copySelfSignedCertificates(KeyStore dst, KeyStore src) {
+        try {
+            boolean copied = false;
+            for (String alias : Collections.list(src.aliases())) {
+                if (!src.isCertificateEntry(alias)) {
+                    continue;
+                }
+                X509Certificate cert = (X509Certificate) src.getCertificate(alias);
+                if (!cert.getSubjectDN().equals(cert.getIssuerDN())) {
+                    continue;
+                }
+                dst.setCertificateEntry(alias, cert);
+                copied = true;
+            }
+            return copied;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Copy named certificates from one key store to another.
+     * Returns true if successful, false if no match found.
+     */
+    public static boolean copyCertificate(Principal subject, KeyStore dst, KeyStore src)
+            throws Exception {
+        for (String alias : Collections.list(src.aliases())) {
+            if (!src.isCertificateEntry(alias)) {
+                continue;
+            }
+            X509Certificate cert = (X509Certificate) src.getCertificate(alias);
+            if (!cert.getSubjectDN().equals(subject)) {
+                continue;
+            }
+            dst.setCertificateEntry(alias, cert);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Dump a key store for debugging.
+     */
+    public void dump(String context) throws KeyStoreException, NoSuchAlgorithmException {
+        dump(context, keyStore, keyPassword);
+    }
+
+    /**
+     * Dump a key store for debugging.
+     */
+    public static void dump(String context, KeyStore keyStore, char[] keyPassword)
+            throws KeyStoreException, NoSuchAlgorithmException {
+        PrintStream out = System.out;
+        out.println("context=" + context);
+        out.println("\tkeyStore=" + keyStore);
+        out.println("\tkeyStore.type=" + keyStore.getType());
+        out.println("\tkeyStore.provider=" + keyStore.getProvider());
+        out.println("\tkeyPassword=" + ((keyPassword == null) ? null : new String(keyPassword)));
+        out.println("\tsize=" + keyStore.size());
+        for (String alias : Collections.list(keyStore.aliases())) {
+            out.println("alias=" + alias);
+            out.println("\tcreationDate=" + keyStore.getCreationDate(alias));
+            if (keyStore.isCertificateEntry(alias)) {
+                out.println("\tcertificate:");
+                out.println("==========================================");
+                out.println(keyStore.getCertificate(alias));
+                out.println("==========================================");
+                continue;
+            }
+            if (keyStore.isKeyEntry(alias)) {
+                out.println("\tkey:");
+                out.println("==========================================");
+                String key;
+                try {
+                    key = ("Key retrieved using password\n" + keyStore.getKey(alias, keyPassword));
+                } catch (UnrecoverableKeyException e1) {
+                    try {
+                        key = ("Key retrieved without password\n" + keyStore.getKey(alias, null));
+                    } catch (UnrecoverableKeyException e2) {
+                        key = "Key could not be retrieved";
+                    }
+                }
+                out.println(key);
+                out.println("==========================================");
+                Certificate[] chain = keyStore.getCertificateChain(alias);
+                if (chain == null) {
+                    out.println("No certificate chain associated with key");
+                    out.println("==========================================");
+                } else {
+                    for (int i = 0; i < chain.length; i++) {
+                        out.println("Certificate chain element #" + i);
+                        out.println(chain[i]);
+                        out.println("==========================================");
+                    }
+                }
+                continue;
+            }
+            out.println("\tunknown entry type");
+        }
+    }
+
+    public static void assertChainLength(Object[] chain) {
+        /*
+         * Note chain is Object[] to support both
+         * java.security.cert.X509Certificate and
+         * javax.security.cert.X509Certificate
+         */
+        assertEquals(3, chain.length);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/FakeSSLSession.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/FakeSSLSession.java
new file mode 100644
index 0000000..ecd8b24
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/FakeSSLSession.java
@@ -0,0 +1,141 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2009 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 com.android.org.conscrypt.javax.net.ssl;
+
+import java.nio.charset.Charset;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class FakeSSLSession implements SSLSession {
+    private static final Charset UTF_8 = Charset.forName("UTF-8");
+    final String host;
+
+    public FakeSSLSession(String host) {
+        this.host = host;
+    }
+
+    @Override
+    public int getApplicationBufferSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getCipherSuite() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCreationTime() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public byte[] getId() {
+        return host.getBytes(UTF_8);
+    }
+
+    @Override
+    public long getLastAccessedTime() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Certificate[] getLocalCertificates() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Principal getLocalPrincipal() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPacketBufferSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Certificate[] getPeerCertificates() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPeerHost() {
+        return host;
+    }
+
+    @Override
+    public int getPeerPort() {
+        return 443;
+    }
+
+    @Override
+    public Principal getPeerPrincipal() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getProtocol() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public SSLSessionContext getSessionContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Object getValue(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getValueNames() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void invalidate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isValid() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void putValue(String name, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeValue(String name) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/ForwardingX509ExtendedKeyManager.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/ForwardingX509ExtendedKeyManager.java
new file mode 100644
index 0000000..9ad3db5
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/ForwardingX509ExtendedKeyManager.java
@@ -0,0 +1,66 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt.javax.net.ssl;
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+/**
+ * {@link X509ExtendedKeyManager} which delegates all calls to the provided
+ * {@code X509ExtendedKeyManager} instance.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ForwardingX509ExtendedKeyManager extends X509ExtendedKeyManager {
+    private final X509ExtendedKeyManager delegate;
+    public ForwardingX509ExtendedKeyManager(X509ExtendedKeyManager delegate) {
+        this.delegate = delegate;
+    }
+    @Override
+    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+        return delegate.chooseClientAlias(keyType, issuers, socket);
+    }
+    @Override
+    public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+        return delegate.chooseServerAlias(keyType, issuers, socket);
+    }
+    @Override
+    public X509Certificate[] getCertificateChain(String alias) {
+        return delegate.getCertificateChain(alias);
+    }
+    @Override
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        return delegate.getClientAliases(keyType, issuers);
+    }
+    @Override
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        return delegate.getServerAliases(keyType, issuers);
+    }
+    @Override
+    public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
+        return delegate.chooseEngineClientAlias(keyType, issuers, engine);
+    }
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
+        return delegate.chooseEngineServerAlias(keyType, issuers, engine);
+    }
+    @Override
+    public PrivateKey getPrivateKey(String alias) {
+        return delegate.getPrivateKey(alias);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/PSKKeyManagerProxy.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/PSKKeyManagerProxy.java
new file mode 100644
index 0000000..d4275c6
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/PSKKeyManagerProxy.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.javax.net.ssl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.Socket;
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLEngine;
+import com.android.org.conscrypt.TestUtils;
+
+/**
+ * Reflection-based implementation of {@code PSKKeyManager} from Conscrypt on which these tests
+ * cannot depend directly.
+ */
+class PSKKeyManagerProxy implements InvocationHandler {
+    static KeyManager getConscryptPSKKeyManager(PSKKeyManagerProxy delegate) {
+        Class<?> pskKeyManagerInterface;
+        try {
+            pskKeyManagerInterface = TestUtils.conscryptClass("PSKKeyManager");
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        return (KeyManager) Proxy.newProxyInstance(
+                PSKKeyManagerProxy.class.getClassLoader(),
+                new Class<?>[] {pskKeyManagerInterface},
+                delegate);
+    }
+    @SuppressWarnings("unused")
+    protected SecretKey getKey(String identityHint, String identity, Socket socket) {
+        return null;
+    }
+    @SuppressWarnings("unused")
+    protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
+        return null;
+    }
+    @SuppressWarnings("unused")
+    protected String chooseServerKeyIdentityHint(Socket socket) {
+        return null;
+    }
+    @SuppressWarnings("unused")
+    protected String chooseServerKeyIdentityHint(SSLEngine engine) {
+        return null;
+    }
+    @SuppressWarnings("unused")
+    protected String chooseClientKeyIdentity(String identityHint, Socket socket) {
+        return null;
+    }
+    @SuppressWarnings("unused")
+    protected String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
+        return null;
+    }
+    @Override
+    public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        String methodName = method.getName();
+        Class<?>[] parameterTypes = method.getParameterTypes();
+        boolean sslEngineVariant = (parameterTypes.length > 0)
+                && SSLEngine.class.equals(parameterTypes[parameterTypes.length - 1]);
+        if ("getKey".equals(methodName)) {
+            if (sslEngineVariant) {
+                return getKey((String) args[0], (String) args[1], (SSLEngine) args[2]);
+            } else {
+                return getKey((String) args[0], (String) args[1], (Socket) args[2]);
+            }
+        } else if ("chooseServerKeyIdentityHint".equals(methodName)) {
+            if (sslEngineVariant) {
+                return chooseServerKeyIdentityHint((SSLEngine) args[0]);
+            } else {
+                return chooseServerKeyIdentityHint((Socket) args[0]);
+            }
+        } else if ("chooseClientKeyIdentity".equals(methodName)) {
+            if (sslEngineVariant) {
+                return chooseClientKeyIdentity((String) args[0], (SSLEngine) args[1]);
+            } else {
+                return chooseClientKeyIdentity((String) args[0], (Socket) args[1]);
+            }
+        } else {
+            throw new IllegalArgumentException("Unexpected method: " + method);
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
new file mode 100644
index 0000000..efe5d6c
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/RandomPrivateKeyX509ExtendedKeyManager.java
@@ -0,0 +1,87 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.fail;
+
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+import javax.net.ssl.X509ExtendedKeyManager;
+
+/**
+ * {@link X509ExtendedKeyManager} which forwards all calls to a delegate while substituting
+ * the returned private key with its own randomly generated keys of the same type (and parameters).
+ * @hide This class is not part of the Android public SDK API
+ */
+public class RandomPrivateKeyX509ExtendedKeyManager extends ForwardingX509ExtendedKeyManager {
+    private final Map<String, PrivateKey> cachedKeys = new HashMap<String, PrivateKey>();
+    public RandomPrivateKeyX509ExtendedKeyManager(X509ExtendedKeyManager delegate) {
+        super(delegate);
+    }
+    @Override
+    public PrivateKey getPrivateKey(String alias) {
+        PrivateKey originalPrivateKey = super.getPrivateKey(alias);
+        if (originalPrivateKey == null) {
+            return null;
+        }
+        PrivateKey result;
+        String keyAlgorithm = originalPrivateKey.getAlgorithm();
+        try {
+            KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
+            if ("RSA".equals(keyAlgorithm)) {
+                RSAPrivateKeySpec originalKeySpec =
+                        keyFactory.getKeySpec(originalPrivateKey, RSAPrivateKeySpec.class);
+                int keyLengthBits = originalKeySpec.getModulus().bitLength();
+                // Use a cache because RSA key generation is slow.
+                String cacheKey = keyAlgorithm + "-" + keyLengthBits;
+                result = cachedKeys.get(cacheKey);
+                if (result == null) {
+                    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlgorithm);
+                    keyPairGenerator.initialize(keyLengthBits);
+                    result = keyPairGenerator.generateKeyPair().getPrivate();
+                    cachedKeys.put(cacheKey, result);
+                }
+            } else if ("DSA".equals(keyAlgorithm)) {
+                DSAPrivateKeySpec originalKeySpec =
+                        keyFactory.getKeySpec(originalPrivateKey, DSAPrivateKeySpec.class);
+                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlgorithm);
+                keyPairGenerator.initialize(new DSAParameterSpec(
+                        originalKeySpec.getP(), originalKeySpec.getQ(), originalKeySpec.getG()));
+                result = keyPairGenerator.generateKeyPair().getPrivate();
+            } else if ("EC".equals(keyAlgorithm)) {
+                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyAlgorithm);
+                keyPairGenerator.initialize(((ECPrivateKey) originalPrivateKey).getParams());
+                result = keyPairGenerator.generateKeyPair().getPrivate();
+            } else {
+                fail("Unsupported key algorithm: " + originalPrivateKey.getAlgorithm());
+                result = null;
+            }
+        } catch (GeneralSecurityException e) {
+            fail("Failed to generate private key: " + e);
+            result = null;
+        }
+        return result;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/SSLConfigurationAsserts.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/SSLConfigurationAsserts.java
new file mode 100644
index 0000000..a415292
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/SSLConfigurationAsserts.java
@@ -0,0 +1,236 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import com.android.org.conscrypt.java.security.StandardNames;
+
+/**
+ * Assertions about the configuration of TLS/SSL primitives.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class SSLConfigurationAsserts {
+    /** Hidden constructor to prevent instantiation. */
+    private SSLConfigurationAsserts() {}
+    /**
+     * Asserts that the provided {@link SSLContext} has the expected default configuration, and that
+     * {@link SSLSocketFactory}, {@link SSLServerSocketFactory}, {@link SSLSocket},
+     * {@link SSLServerSocket} and {@link SSLEngine} instances created from the context match the
+     * configuration.
+     */
+    public static void assertSSLContextDefaultConfiguration(SSLContext sslContext)
+            throws IOException {
+        SSLParameters defaultParameters = sslContext.getDefaultSSLParameters();
+        StandardNames.assertSSLContextEnabledProtocols(
+                sslContext.getProtocol(), defaultParameters.getProtocols());
+        StandardNames.assertDefaultCipherSuites(defaultParameters.getCipherSuites());
+        assertFalse(defaultParameters.getWantClientAuth());
+        assertFalse(defaultParameters.getNeedClientAuth());
+        SSLParameters supportedParameters = sslContext.getSupportedSSLParameters();
+        StandardNames.assertSupportedCipherSuites(supportedParameters.getCipherSuites());
+        StandardNames.assertSupportedProtocols(supportedParameters.getProtocols());
+        assertFalse(supportedParameters.getWantClientAuth());
+        assertFalse(supportedParameters.getNeedClientAuth());
+        assertContainsAll("Unsupported enabled cipher suites",
+                supportedParameters.getCipherSuites(), defaultParameters.getCipherSuites());
+        assertContainsAll("Unsupported enabled protocols", supportedParameters.getProtocols(),
+                defaultParameters.getProtocols());
+        assertSSLSocketFactoryConfigSameAsSSLContext(sslContext.getSocketFactory(), sslContext);
+        assertSSLServerSocketFactoryConfigSameAsSSLContext(
+                sslContext.getServerSocketFactory(), sslContext);
+        SSLEngine sslEngine = sslContext.createSSLEngine();
+        assertFalse(sslEngine.getUseClientMode());
+        assertSSLEngineConfigSameAsSSLContext(sslEngine, sslContext);
+    }
+    /**
+     * Asserts that the provided {@link SSLSocketFactory} has the expected default configuration and
+     * that {@link SSLSocket} instances created by the factory match the configuration.
+     */
+    public static void assertSSLSocketFactoryDefaultConfiguration(SSLSocketFactory sslSocketFactory)
+            throws Exception {
+        assertSSLSocketFactoryConfigSameAsSSLContext(sslSocketFactory, SSLContext.getDefault());
+    }
+    /**
+     * Asserts that {@link SSLSocketFactory}'s configuration matches {@code SSLContext}'s
+     * configuration, and that {@link SSLSocket} instances obtained from the factory match this
+     * configuration as well.
+     */
+    private static void assertSSLSocketFactoryConfigSameAsSSLContext(
+            SSLSocketFactory sslSocketFactory, SSLContext sslContext) throws IOException {
+        assertCipherSuitesEqual(sslContext.getDefaultSSLParameters().getCipherSuites(),
+                sslSocketFactory.getDefaultCipherSuites());
+        assertCipherSuitesEqual(sslContext.getSupportedSSLParameters().getCipherSuites(),
+                sslSocketFactory.getSupportedCipherSuites());
+        SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket();
+        try {
+            assertTrue(sslSocket.getUseClientMode());
+            assertTrue(sslSocket.getEnableSessionCreation());
+            assertSSLSocketConfigSameAsSSLContext(sslSocket, sslContext);
+        } finally {
+            sslSocket.close();
+        }
+    }
+    /**
+     * Asserts that the provided {@link SSLSocket} has the expected default configuration.
+     */
+    public static void assertSSLSocketDefaultConfiguration(SSLSocket sslSocket) throws Exception {
+        assertTrue(sslSocket.getUseClientMode());
+        assertTrue(sslSocket.getEnableSessionCreation());
+        assertSSLSocketConfigSameAsSSLContext(sslSocket, SSLContext.getDefault());
+    }
+    /**
+     * Asserts that {@link SSLSocket}'s configuration matches {@code SSLContext's} configuration.
+     */
+    private static void assertSSLSocketConfigSameAsSSLContext(
+            SSLSocket sslSocket, SSLContext sslContext) {
+        assertSSLParametersEqual(
+                sslSocket.getSSLParameters(), sslContext.getDefaultSSLParameters());
+        assertCipherSuitesEqual(sslSocket.getEnabledCipherSuites(),
+                sslContext.getDefaultSSLParameters().getCipherSuites());
+        assertProtocolsEqual(sslSocket.getEnabledProtocols(),
+                sslContext.getDefaultSSLParameters().getProtocols());
+        assertCipherSuitesEqual(sslSocket.getSupportedCipherSuites(),
+                sslContext.getSupportedSSLParameters().getCipherSuites());
+        assertProtocolsEqual(sslSocket.getSupportedProtocols(),
+                sslContext.getSupportedSSLParameters().getProtocols());
+    }
+    /**
+     * Asserts that the provided {@link SSLServerSocketFactory} has the expected default
+     * configuration, and that {@link SSLServerSocket} instances created by the factory match the
+     * configuration.
+     */
+    public static void assertSSLServerSocketFactoryDefaultConfiguration(
+            SSLServerSocketFactory sslServerSocketFactory) throws Exception {
+        assertSSLServerSocketFactoryConfigSameAsSSLContext(
+                sslServerSocketFactory, SSLContext.getDefault());
+    }
+    /**
+     * Asserts that {@link SSLServerSocketFactory}'s configuration matches {@code SSLContext}'s
+     * configuration, and that {@link SSLServerSocket} instances obtained from the factory match
+     * this
+     * configuration as well.
+     */
+    private static void assertSSLServerSocketFactoryConfigSameAsSSLContext(
+            SSLServerSocketFactory sslServerSocketFactory, SSLContext sslContext)
+            throws IOException {
+        assertCipherSuitesEqual(sslContext.getDefaultSSLParameters().getCipherSuites(),
+                sslServerSocketFactory.getDefaultCipherSuites());
+        assertCipherSuitesEqual(sslContext.getSupportedSSLParameters().getCipherSuites(),
+                sslServerSocketFactory.getSupportedCipherSuites());
+        SSLServerSocket sslServerSocket =
+            (SSLServerSocket) sslServerSocketFactory.createServerSocket();
+        try {
+            assertFalse(sslServerSocket.getUseClientMode());
+            assertTrue(sslServerSocket.getEnableSessionCreation());
+            assertSSLServerSocketConfigSameAsSSLContext(sslServerSocket, sslContext);
+        } finally {
+            sslServerSocket.close();
+        }
+    }
+    /**
+     * Asserts that the provided {@link SSLServerSocket} has the expected default configuration.
+     */
+    public static void assertSSLServerSocketDefaultConfiguration(SSLServerSocket sslServerSocket)
+            throws Exception {
+        assertFalse(sslServerSocket.getUseClientMode());
+        assertTrue(sslServerSocket.getEnableSessionCreation());
+        assertSSLServerSocketConfigSameAsSSLContext(sslServerSocket, SSLContext.getDefault());
+        // TODO: Check SSLParameters when supported by SSLServerSocket API
+    }
+    /**
+     * Asserts that {@link SSLServerSocket}'s configuration matches {@code SSLContext's}
+     * configuration.
+     */
+    private static void assertSSLServerSocketConfigSameAsSSLContext(
+            SSLServerSocket sslServerSocket, SSLContext sslContext) {
+        assertCipherSuitesEqual(sslServerSocket.getEnabledCipherSuites(),
+                sslContext.getDefaultSSLParameters().getCipherSuites());
+        assertProtocolsEqual(sslServerSocket.getEnabledProtocols(),
+                sslContext.getDefaultSSLParameters().getProtocols());
+        assertCipherSuitesEqual(sslServerSocket.getSupportedCipherSuites(),
+                sslContext.getSupportedSSLParameters().getCipherSuites());
+        assertProtocolsEqual(sslServerSocket.getSupportedProtocols(),
+                sslContext.getSupportedSSLParameters().getProtocols());
+        assertEquals(sslServerSocket.getNeedClientAuth(),
+                sslContext.getDefaultSSLParameters().getNeedClientAuth());
+        assertEquals(sslServerSocket.getWantClientAuth(),
+                sslContext.getDefaultSSLParameters().getWantClientAuth());
+    }
+    /**
+     * Asserts that the provided {@link SSLEngine} has the expected default configuration.
+     */
+    public static void assertSSLEngineDefaultConfiguration(SSLEngine sslEngine) throws Exception {
+        assertFalse(sslEngine.getUseClientMode());
+        assertTrue(sslEngine.getEnableSessionCreation());
+        assertSSLEngineConfigSameAsSSLContext(sslEngine, SSLContext.getDefault());
+    }
+    /**
+     * Asserts that {@link SSLEngine}'s configuration matches {@code SSLContext's} configuration.
+     */
+    private static void assertSSLEngineConfigSameAsSSLContext(
+            SSLEngine sslEngine, SSLContext sslContext) {
+        assertSSLParametersEqual(
+                sslEngine.getSSLParameters(), sslContext.getDefaultSSLParameters());
+        assertCipherSuitesEqual(sslEngine.getEnabledCipherSuites(),
+                sslContext.getDefaultSSLParameters().getCipherSuites());
+        assertProtocolsEqual(sslEngine.getEnabledProtocols(),
+                sslContext.getDefaultSSLParameters().getProtocols());
+        assertCipherSuitesEqual(sslEngine.getSupportedCipherSuites(),
+                sslContext.getSupportedSSLParameters().getCipherSuites());
+        assertProtocolsEqual(sslEngine.getSupportedProtocols(),
+                sslContext.getSupportedSSLParameters().getProtocols());
+    }
+    private static void assertSSLParametersEqual(SSLParameters expected, SSLParameters actual) {
+        assertCipherSuitesEqual(expected.getCipherSuites(), actual.getCipherSuites());
+        assertProtocolsEqual(expected.getProtocols(), actual.getProtocols());
+        assertEquals(expected.getNeedClientAuth(), actual.getNeedClientAuth());
+        assertEquals(expected.getWantClientAuth(), actual.getWantClientAuth());
+    }
+    private static void assertCipherSuitesEqual(String[] expected, String[] actual) {
+        assertEquals(Arrays.asList(expected), Arrays.asList(actual));
+    }
+    private static void assertProtocolsEqual(String[] expected, String[] actual) {
+        // IMPLEMENTATION NOTE: The order of protocols versions does not matter. Similarly, it only
+        // matters whether a protocol version is present or absent in the array. These arrays are
+        // supposed to represent sets of protocol versions. Thus, we treat them as such.
+        assertEquals(new HashSet<String>(Arrays.asList(expected)),
+                new HashSet<String>(Arrays.asList(actual)));
+    }
+    /**
+     * Asserts that the {@code container} contains all the {@code elements}.
+     */
+    private static void assertContainsAll(String message, String[] container, String[] elements) {
+        Set<String> elementsNotInContainer = new HashSet<String>(Arrays.asList(elements));
+        elementsNotInContainer.removeAll(Arrays.asList(container));
+        assertEquals(message, Collections.EMPTY_SET, elementsNotInContainer);
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestHostnameVerifier.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestHostnameVerifier.java
new file mode 100644
index 0000000..ca6e225
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestHostnameVerifier.java
@@ -0,0 +1,57 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt.javax.net.ssl;
+
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * This class implements the simplest possible HostnameVerifier.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TestHostnameVerifier implements HostnameVerifier {
+    @Override
+    public boolean verify(String hostname, SSLSession sslSession) {
+        try {
+            return verify(hostname, (X509Certificate) sslSession.getPeerCertificates()[0]);
+        } catch (SSLException e) {
+            return false;
+        }
+    }
+
+    private boolean verify(String hostname, X509Certificate cert) {
+        for (String certHost : getHostnames(cert)) {
+            if (certHost.equals(hostname)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static final int DNS_NAME_TYPE = 2;
+
+    private List<String> getHostnames(X509Certificate cert) {
+        List<String> result = new ArrayList<String>();
+        try {
+            Collection<List<?>> altNamePairs = cert.getSubjectAlternativeNames();
+            if (altNamePairs != null) {
+                for (List<?> altNamePair : altNamePairs) {
+                    // altNames are returned as effectively Pair<Integer, String> instances,
+                    // where the first member is the type of altName and the second is the name.
+                    if (altNamePair.get(0).equals(DNS_NAME_TYPE)) {
+                        result.add((String) altNamePair.get(1));
+                    }
+                }
+            }
+            return result;
+        } catch (CertificateParsingException e) {
+            return Collections.emptyList();
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestKeyManager.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestKeyManager.java
new file mode 100644
index 0000000..10e2266
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestKeyManager.java
@@ -0,0 +1,213 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import java.io.PrintStream;
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.testing.NullPrintStream;
+
+/**
+ * TestKeyManager is a simple proxy class that wraps an existing
+ * X509ExtendedKeyManager to provide debug logging and recording of
+ * values.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestKeyManager extends X509ExtendedKeyManager {
+    private static final boolean LOG = false;
+    private static final PrintStream out = LOG ? System.out : new NullPrintStream();
+
+    private final X509ExtendedKeyManager keyManager;
+
+    public static KeyManager[] wrap(KeyManager[] keyManagers) {
+        KeyManager[] result = keyManagers.clone();
+        for (int i = 0; i < result.length; i++) {
+            result[i] = wrap(result[i]);
+        }
+        return result;
+    }
+
+    public static KeyManager wrap(KeyManager keyManager) {
+        if (!(keyManager instanceof X509ExtendedKeyManager)) {
+            return keyManager;
+        }
+        return new TestKeyManager((X509ExtendedKeyManager) keyManager);
+    }
+
+    public TestKeyManager(X509ExtendedKeyManager keyManager) {
+        out.println("TestKeyManager.<init> keyManager=" + keyManager);
+        this.keyManager = keyManager;
+    }
+
+    @Override
+    public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) {
+        out.print("TestKeyManager.chooseClientAlias");
+        out.print(" | keyTypes: ");
+        for (String keyType : keyTypes) {
+            out.print(keyType);
+            out.print(' ');
+        }
+        dumpIssuers(issuers);
+        dumpSocket(socket);
+        assertKeyTypes(keyTypes);
+        return dumpAlias(keyManager.chooseClientAlias(keyTypes, issuers, socket));
+    }
+
+    private void assertKeyTypes(String[] keyTypes) {
+        for (String keyType : keyTypes) {
+            assertKeyType(keyType);
+        }
+    }
+
+    private void assertKeyType(String keyType) {
+        if (!StandardNames.KEY_TYPES.contains(keyType)) {
+            throw new AssertionError("Unexpected key type " + keyType);
+        }
+    }
+
+    @Override
+    public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+        out.print("TestKeyManager.chooseServerAlias");
+        out.print(" | keyType: ");
+        out.print(keyType);
+        out.print(' ');
+        dumpIssuers(issuers);
+        dumpSocket(socket);
+        assertKeyType(keyType);
+        return dumpAlias(keyManager.chooseServerAlias(keyType, issuers, socket));
+    }
+
+    private void dumpSocket(Socket socket) {
+        out.print(" | socket: ");
+        out.print(String.valueOf(socket));
+    }
+
+    private void dumpIssuers(Principal[] issuers) {
+        out.print(" | issuers: ");
+        if (issuers == null) {
+            out.print("null");
+            return;
+        }
+        for (Principal issuer : issuers) {
+            out.print(issuer);
+            out.print(' ');
+        }
+    }
+
+    private String dumpAlias(String alias) {
+        out.print(" => ");
+        out.println(alias);
+        return alias;
+    }
+
+    @Override
+    public X509Certificate[] getCertificateChain(String alias) {
+        out.print("TestKeyManager.getCertificateChain");
+        out.print(" | alias: ");
+        out.print(alias);
+        return dumpCerts(keyManager.getCertificateChain(alias));
+    }
+
+    private X509Certificate[] dumpCerts(X509Certificate[] certs) {
+        out.print(" => ");
+        for (X509Certificate cert : certs) {
+            out.print(cert.getSubjectDN());
+            out.print(' ');
+        }
+        out.println();
+        return certs;
+    }
+
+    @Override
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        out.print("TestKeyManager.getClientAliases");
+        out.print(" | keyType: ");
+        out.print(keyType);
+        dumpIssuers(issuers);
+        assertKeyType(keyType);
+        return dumpAliases(keyManager.getClientAliases(keyType, issuers));
+    }
+
+    @Override
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        out.print("TestKeyManager.getServerAliases");
+        out.print(" | keyType: ");
+        out.print(keyType);
+        dumpIssuers(issuers);
+        assertKeyType(keyType);
+        return dumpAliases(keyManager.getServerAliases(keyType, issuers));
+    }
+
+    private String[] dumpAliases(String[] aliases) {
+        out.print(" => ");
+        for (String alias : aliases) {
+            out.print(alias);
+            out.print(' ');
+        }
+        out.println();
+        return aliases;
+    }
+
+    @Override
+    public PrivateKey getPrivateKey(String alias) {
+        out.print("TestKeyManager.getPrivateKey");
+        out.print(" | alias: ");
+        out.print(alias);
+        PrivateKey pk = keyManager.getPrivateKey(alias);
+        out.print(" => ");
+        out.println(String.valueOf(pk));
+        return pk;
+    }
+
+    @Override
+    public String chooseEngineClientAlias(String[] keyTypes, Principal[] issuers, SSLEngine e) {
+        out.print("TestKeyManager.chooseEngineClientAlias");
+        out.print(" | keyTypes: ");
+        for (String keyType : keyTypes) {
+            out.print(keyType);
+            out.print(' ');
+        }
+        dumpIssuers(issuers);
+        dumpEngine(e);
+        assertKeyTypes(keyTypes);
+        return dumpAlias(keyManager.chooseEngineClientAlias(keyTypes, issuers, e));
+    }
+
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine e) {
+        out.print("TestKeyManager.chooseEngineServerAlias");
+        out.print(" | keyType: ");
+        out.print(keyType);
+        out.print(' ');
+        dumpIssuers(issuers);
+        dumpEngine(e);
+        assertKeyType(keyType);
+        return dumpAlias(keyManager.chooseEngineServerAlias(keyType, issuers, e));
+    }
+
+    private void dumpEngine(SSLEngine engine) {
+        out.print(" | engine: ");
+        out.print(String.valueOf(engine));
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLContext.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLContext.java
new file mode 100644
index 0000000..84f377b
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLContext.java
@@ -0,0 +1,490 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import com.android.org.conscrypt.TestUtils;
+import com.android.org.conscrypt.java.security.TestKeyStore;
+
+/**
+ * TestSSLContext is a convenience class for other tests that
+ * want a canned SSLContext and related state for testing so they
+ * don't have to duplicate the logic.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestSSLContext {
+    /**
+     * The Android SSLSocket and SSLServerSocket implementations are
+     * based on a version of OpenSSL which includes support for RFC
+     * 4507 session tickets. When using session tickets, the server
+     * does not need to keep a cache mapping session IDs to SSL
+     * sessions for reuse. Instead, the client presents the server
+     * with a session ticket it received from the server earlier,
+     * which is an SSL session encrypted by the server's secret
+     * key. Since in this case the server does not need to keep a
+     * cache, some tests may find different results depending on
+     * whether or not the session tickets are in use. These tests can
+     * use this function to determine if loopback SSL connections are
+     * expected to use session tickets and conditionalize their
+     * results appropriately.
+     */
+    public static boolean sslServerSocketSupportsSessionTickets() {
+        // Disabled session tickets for better compatability b/2682876
+        // return !IS_RI;
+        return true;
+    }
+    public final KeyStore clientKeyStore;
+    public final char[] clientStorePassword;
+    public final KeyStore serverKeyStore;
+    public final char[] serverStorePassword;
+    public final KeyManager[] clientKeyManagers;
+    public final KeyManager[] serverKeyManagers;
+    public final X509TrustManager clientTrustManager;
+    public final X509TrustManager serverTrustManager;
+    public final SSLContext clientContext;
+    public final SSLContext serverContext;
+    public final SSLServerSocket serverSocket;
+    public final InetAddress host;
+    public final int port;
+    /**
+     * Used for replacing the hostname in an InetSocketAddress object during
+     * serialization.
+     */
+    private static class HostnameRewritingObjectOutputStream extends ObjectOutputStream {
+        private final String hostname;
+        public HostnameRewritingObjectOutputStream(OutputStream out, String hostname)
+                throws IOException {
+            super(out);
+            this.hostname = hostname;
+        }
+        @Override
+        public PutField putFields() throws IOException {
+            return new PutFieldProxy(super.putFields(), hostname);
+        }
+        private static class PutFieldProxy extends ObjectOutputStream.PutField {
+            private final PutField delegate;
+            private final String hostname;
+            public PutFieldProxy(ObjectOutputStream.PutField delegate, String hostname) {
+                this.delegate = delegate;
+                this.hostname = hostname;
+            }
+            @Override
+            public void put(String name, boolean val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, byte val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, char val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, short val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, int val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, long val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, float val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, double val) {
+                delegate.put(name, val);
+            }
+            @Override
+            public void put(String name, Object val) {
+                if ("hostname".equals(name)) {
+                    delegate.put(name, hostname);
+                } else {
+                    delegate.put(name, val);
+                }
+            }
+            @SuppressWarnings("deprecation")
+            @Override
+            public void write(ObjectOutput out) throws IOException {
+                delegate.write(out);
+            }
+        }
+    }
+    /**
+     * Creates an InetSocketAddress where the hostname points to an arbitrary
+     * hostname, but the address points to the loopback address. Useful for
+     * testing SNI where both "localhost" and IP addresses are not allowed.
+     */
+    public InetSocketAddress getLoopbackAsHostname(String hostname, int port)
+            throws IOException, ClassNotFoundException {
+        InetSocketAddress addr = new InetSocketAddress(TestUtils.getLoopbackAddress(), port);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        HostnameRewritingObjectOutputStream oos =
+                new HostnameRewritingObjectOutputStream(baos, hostname);
+        oos.writeObject(addr);
+        oos.close();
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
+        return (InetSocketAddress) ois.readObject();
+    }
+    private TestSSLContext(KeyStore clientKeyStore, char[] clientStorePassword,
+            KeyStore serverKeyStore, char[] serverStorePassword, KeyManager[] clientKeyManagers,
+            KeyManager[] serverKeyManagers, X509TrustManager clientTrustManager,
+            X509TrustManager serverTrustManager, SSLContext clientContext,
+            SSLContext serverContext, SSLServerSocket serverSocket, InetAddress host, int port) {
+        this.clientKeyStore = clientKeyStore;
+        this.clientStorePassword = clientStorePassword;
+        this.serverKeyStore = serverKeyStore;
+        this.serverStorePassword = serverStorePassword;
+        this.clientKeyManagers = clientKeyManagers;
+        this.serverKeyManagers = serverKeyManagers;
+        this.clientTrustManager = clientTrustManager;
+        this.serverTrustManager = serverTrustManager;
+        this.clientContext = clientContext;
+        this.serverContext = serverContext;
+        this.serverSocket = serverSocket;
+        this.host = host;
+        this.port = port;
+    }
+    public void close() {
+        try {
+            serverSocket.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static final class Builder {
+        private TestKeyStore client;
+        private char[] clientStorePassword;
+        private TestKeyStore server;
+        private char[] serverStorePassword;
+        private KeyManager[] additionalClientKeyManagers;
+        private KeyManager[] additionalServerKeyManagers;
+        private TrustManager clientTrustManager;
+        private TrustManager serverTrustManager;
+        private SSLContext clientContext;
+        private SSLContext serverContext;
+        private String clientProtocol = "TLS";
+        private String serverProtocol = "TLS";
+        private int serverReceiveBufferSize;
+        private boolean useDefaults = true;
+
+        public Builder useDefaults(boolean useDefaults) {
+            this.useDefaults = useDefaults;
+            return this;
+        }
+
+        public Builder client(TestKeyStore client) {
+            this.client = client;
+            return this;
+        }
+
+        public Builder clientStorePassword(char[] clientStorePassword) {
+            this.clientStorePassword = clientStorePassword;
+            return this;
+        }
+
+        public Builder server(TestKeyStore server) {
+            this.server = server;
+            return this;
+        }
+
+        public Builder serverStorePassword(char[] serverStorePassword) {
+            this.serverStorePassword = serverStorePassword;
+            return this;
+        }
+
+        public Builder additionalClientKeyManagers(KeyManager[] additionalClientKeyManagers) {
+            this.additionalClientKeyManagers = additionalClientKeyManagers;
+            return this;
+        }
+
+        public Builder additionalServerKeyManagers(KeyManager[] additionalServerKeyManagers) {
+            this.additionalServerKeyManagers = additionalServerKeyManagers;
+            return this;
+        }
+
+        public Builder clientTrustManager(TrustManager clientTrustManager) {
+            this.clientTrustManager = clientTrustManager;
+            return this;
+        }
+
+        public Builder serverTrustManager(TrustManager serverTrustManager) {
+            this.serverTrustManager = serverTrustManager;
+            return this;
+        }
+
+        public Builder clientContext(SSLContext clientContext) {
+            this.clientContext = clientContext;
+            return this;
+        }
+
+        public Builder serverContext(SSLContext serverContext) {
+            this.serverContext = serverContext;
+            return this;
+        }
+
+        public Builder clientProtocol(String clientProtocol) {
+            this.clientProtocol = clientProtocol;
+            return this;
+        }
+
+        public Builder serverProtocol(String serverProtocol) {
+            this.serverProtocol = serverProtocol;
+            return this;
+        }
+
+        public Builder serverReceiveBufferSize(int serverReceiveBufferSize) {
+            this.serverReceiveBufferSize = serverReceiveBufferSize;
+            return this;
+        }
+
+        TestSSLContext build() {
+            // Get the current values for all the things.
+            TestKeyStore client = this.client;
+            TestKeyStore server = this.server;
+            char[] clientStorePassword = this.clientStorePassword;
+            char[] serverStorePassword = this.serverStorePassword;
+            KeyManager[] clientKeyManagers = client != null ? client.keyManagers : null;
+            KeyManager[] serverKeyManagers = server != null ? server.keyManagers : null;
+            TrustManager clientTrustManager = this.clientTrustManager;
+            TrustManager serverTrustManager = this.serverTrustManager;
+            SSLContext clientContext = this.clientContext;
+            SSLContext serverContext = this.serverContext;
+
+            // Apply default values if configured to do so.
+            if (useDefaults) {
+                client = client != null ? client : TestKeyStore.getClient();
+                server = server != null ? server : TestKeyStore.getServer();
+                clientStorePassword =
+                        clientStorePassword != null ? clientStorePassword : client.storePassword;
+                serverStorePassword =
+                        serverStorePassword != null ? serverStorePassword : server.storePassword;
+                clientKeyManagers =
+                        clientKeyManagers != null ? clientKeyManagers : client.keyManagers;
+                serverKeyManagers =
+                        serverKeyManagers != null ? serverKeyManagers : server.keyManagers;
+                clientKeyManagers = concat(clientKeyManagers, additionalClientKeyManagers);
+                serverKeyManagers = concat(serverKeyManagers, additionalServerKeyManagers);
+                clientTrustManager =
+                        clientTrustManager != null ? clientTrustManager : client.trustManagers[0];
+                serverTrustManager =
+                        serverTrustManager != null ? serverTrustManager : server.trustManagers[0];
+
+                clientContext = clientContext != null
+                        ? clientContext
+                        : createSSLContext(clientProtocol, clientKeyManagers,
+                                  new TrustManager[] {clientTrustManager});
+                serverContext = serverContext != null
+                        ? serverContext
+                        : createSSLContext(serverProtocol, serverKeyManagers,
+                                  new TrustManager[] {serverTrustManager});
+            }
+
+            // Create the context.
+            try {
+                SSLServerSocket serverSocket =
+                        (SSLServerSocket) serverContext.getServerSocketFactory()
+                                .createServerSocket();
+                if (serverReceiveBufferSize > 0) {
+                    // The TCP spec says that this should occur before listen.
+                    serverSocket.setReceiveBufferSize(serverReceiveBufferSize);
+                }
+                InetAddress host = TestUtils.getLoopbackAddress();
+                serverSocket.bind(new InetSocketAddress(host, 0));
+                int port = serverSocket.getLocalPort();
+                return new TestSSLContext(client != null ? client.keyStore : null,
+                        clientStorePassword, server != null ? server.keyStore : null,
+                        serverStorePassword, clientKeyManagers, serverKeyManagers,
+                        (X509TrustManager) clientTrustManager,
+                        (X509TrustManager) serverTrustManager, clientContext, serverContext,
+                        serverSocket, host, port);
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Usual TestSSLContext creation method, creates underlying
+     * SSLContext with certificate and key as well as SSLServerSocket
+     * listening provided host and port.
+     */
+    public static TestSSLContext create() {
+        return new Builder().build();
+    }
+
+    /**
+     * TestSSLContext creation method that allows separate creation of server key store
+     */
+    public static TestSSLContext create(TestKeyStore client, TestKeyStore server) {
+        return new Builder().client(client).server(server).build();
+    }
+    /**
+     * Create a SSLContext with a KeyManager using the private key and
+     * certificate chain from the given KeyStore and a TrustManager
+     * using the certificates authorities from the same KeyStore.
+     */
+    public static SSLContext createSSLContext(final String protocol, final KeyManager[] keyManagers,
+            final TrustManager[] trustManagers) {
+        try {
+            SSLContext context = SSLContext.getInstance(protocol);
+            context.init(keyManagers, trustManagers, new SecureRandom());
+            return context;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+    public static void assertCertificateInKeyStore(Principal principal, KeyStore keyStore)
+            throws Exception {
+        String subjectName = principal.getName();
+        boolean found = false;
+        for (String alias : Collections.list(keyStore.aliases())) {
+            if (!keyStore.isCertificateEntry(alias)) {
+                continue;
+            }
+            X509Certificate keyStoreCertificate = (X509Certificate) keyStore.getCertificate(alias);
+            if (subjectName.equals(keyStoreCertificate.getSubjectDN().getName())) {
+                found = true;
+                break;
+            }
+        }
+        assertTrue(found);
+    }
+    public static void assertCertificateInKeyStore(Certificate certificate, KeyStore keyStore)
+            throws Exception {
+        boolean found = false;
+        for (String alias : Collections.list(keyStore.aliases())) {
+            if (!keyStore.isCertificateEntry(alias)) {
+                continue;
+            }
+            Certificate keyStoreCertificate = keyStore.getCertificate(alias);
+            if (certificate.equals(keyStoreCertificate)) {
+                found = true;
+                break;
+            }
+        }
+        assertTrue(found);
+    }
+    public static void assertServerCertificateChain(
+            X509TrustManager trustManager, Certificate[] serverChain) throws CertificateException {
+        X509Certificate[] chain = (X509Certificate[]) serverChain;
+        trustManager.checkServerTrusted(chain, chain[0].getPublicKey().getAlgorithm());
+    }
+    public static void assertClientCertificateChain(
+            X509TrustManager trustManager, Certificate[] clientChain) throws CertificateException {
+        X509Certificate[] chain = (X509Certificate[]) clientChain;
+        trustManager.checkClientTrusted(chain, chain[0].getPublicKey().getAlgorithm());
+    }
+    /**
+     * Returns an SSLSocketFactory that calls setWantClientAuth and
+     * setNeedClientAuth as specified on all returned sockets.
+     */
+    public static SSLSocketFactory clientAuth(
+            final SSLSocketFactory sf, final boolean want, final boolean need) {
+        return new SSLSocketFactory() {
+            private SSLSocket set(Socket socket) {
+                SSLSocket s = (SSLSocket) socket;
+                s.setWantClientAuth(want);
+                s.setNeedClientAuth(need);
+                return s;
+            }
+            @Override
+            public Socket createSocket(String host, int port) throws IOException {
+                return set(sf.createSocket(host, port));
+            }
+            @Override
+            public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+                    throws IOException {
+                return set(sf.createSocket(host, port, localHost, localPort));
+            }
+            @Override
+            public Socket createSocket(InetAddress host, int port) throws IOException {
+                return set(sf.createSocket(host, port));
+            }
+            @Override
+            public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+                    int localPort) throws IOException {
+                return set(sf.createSocket(address, port));
+            }
+            @Override
+            public String[] getDefaultCipherSuites() {
+                return sf.getDefaultCipherSuites();
+            }
+            @Override
+            public String[] getSupportedCipherSuites() {
+                return sf.getSupportedCipherSuites();
+            }
+            @Override
+            public Socket createSocket(Socket s, String host, int port, boolean autoClose)
+                    throws IOException {
+                return set(sf.createSocket(s, host, port, autoClose));
+            }
+        };
+    }
+    private static KeyManager[] concat(KeyManager[] a, KeyManager[] b) {
+        if ((a == null) || (a.length == 0)) {
+            return b;
+        }
+        if ((b == null) || (b.length == 0)) {
+            return a;
+        }
+        KeyManager[] result = new KeyManager[a.length + b.length];
+        System.arraycopy(a, 0, result, 0, a.length);
+        System.arraycopy(b, 0, result, a.length, b.length);
+        return result;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLEnginePair.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLEnginePair.java
new file mode 100644
index 0000000..a2906d3
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLEnginePair.java
@@ -0,0 +1,232 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * TestSSLEnginePair is a convenience class for other tests that want
+ * a pair of connected and handshaked client and server SSLEngines for
+ * testing.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestSSLEnginePair implements Closeable {
+    public final TestSSLContext c;
+    public final SSLEngine server;
+    public final SSLEngine client;
+
+    private TestSSLEnginePair(TestSSLContext c,
+            SSLEngine server,
+            SSLEngine client) {
+        this.c = c;
+        this.server = server;
+        this.client = client;
+    }
+
+    public static TestSSLEnginePair create() throws IOException {
+        return create((Hooks) null);
+    }
+
+    public static TestSSLEnginePair create(TestSSLContext c) throws IOException {
+        return create(c, null);
+    }
+
+    public static TestSSLEnginePair create(Hooks hooks) throws IOException {
+        return create(TestSSLContext.create(), hooks);
+    }
+
+    public static TestSSLEnginePair create(TestSSLContext c, Hooks hooks) throws IOException {
+        return create(c, hooks, null);
+    }
+
+    public static TestSSLEnginePair create(TestSSLContext c, Hooks hooks, boolean[] finished)
+            throws IOException {
+        SSLEngine[] engines = connect(c, hooks, finished);
+        return new TestSSLEnginePair(c, engines[0], engines[1]);
+    }
+
+    public static SSLEngine[] connect(TestSSLContext c, Hooks hooks) throws IOException {
+        return connect(c, hooks, null);
+    }
+
+    /**
+     * Create a new connected server/client engine pair within a
+     * existing SSLContext.
+     */
+    public static SSLEngine[] connect(final TestSSLContext c,
+            Hooks hooks,
+            boolean finished[]) throws IOException {
+        if (hooks == null) {
+            hooks = new Hooks();
+        }
+
+        // FINISHED state should be returned only once.
+        boolean[] clientFinished = new boolean[1];
+        boolean[] serverFinished = new boolean[1];
+
+        SSLSession session = c.clientContext.createSSLEngine().getSession();
+
+        int packetBufferSize = session.getPacketBufferSize();
+        ByteBuffer clientToServer = ByteBuffer.allocate(packetBufferSize);
+        ByteBuffer serverToClient = ByteBuffer.allocate(packetBufferSize);
+
+        int applicationBufferSize = session.getApplicationBufferSize();
+        ByteBuffer scratch = ByteBuffer.allocate(applicationBufferSize);
+
+        SSLEngine client = c.clientContext.createSSLEngine(c.host.getHostName(), c.port);
+        SSLEngine server = c.serverContext.createSSLEngine();
+        client.setUseClientMode(true);
+        server.setUseClientMode(false);
+        hooks.beforeBeginHandshake(client, server);
+        client.beginHandshake();
+        server.beginHandshake();
+
+        while (true) {
+            boolean clientDone = client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+            boolean serverDone = server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+            if (clientDone && serverDone) {
+                break;
+            }
+
+            boolean progress =
+                    handshakeStep(client, clientToServer, serverToClient, scratch, clientFinished);
+            progress |=
+                    handshakeStep(server, serverToClient, clientToServer, scratch, serverFinished);
+            if (!progress) {
+                break;
+            }
+        }
+
+        if (finished != null) {
+            assertEquals(2, finished.length);
+            finished[0] = clientFinished[0];
+            finished[1] = serverFinished[0];
+        }
+        return new SSLEngine[] { server, client };
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public static class Hooks {
+        void beforeBeginHandshake(SSLEngine client, SSLEngine server) {}
+    }
+
+    @Override
+    public void close() throws SSLException {
+        close(new SSLEngine[] { client, server });
+    }
+
+    public static void close(SSLEngine[] engines) {
+        try {
+            for (SSLEngine engine : engines) {
+                if (engine != null) {
+                    engine.closeInbound();
+                    engine.closeOutbound();
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static boolean handshakeStep(SSLEngine engine, ByteBuffer output, ByteBuffer input,
+            ByteBuffer scratch, boolean[] finished) throws IOException {
+        try {
+            // make the other side's output into our input
+            input.flip();
+
+            HandshakeStatus status = engine.getHandshakeStatus();
+            switch (status) {
+
+                case NEED_TASK: {
+                    boolean progress = false;
+                    while (true) {
+                        Runnable runnable = engine.getDelegatedTask();
+                        if (runnable == null) {
+                            return progress;
+                        }
+                        runnable.run();
+                        progress = true;
+                    }
+                }
+
+                case NOT_HANDSHAKING:
+                    // If we're not handshaking, our peer might still be.  Check if there's
+                    // any input for us to consume.
+                case NEED_UNWRAP: {
+                    // avoid underflow
+                    if (input.remaining() == 0) {
+                        return false;
+                    }
+                    int inputPositionBefore = input.position();
+                    SSLEngineResult unwrapResult = engine.unwrap(input, scratch);
+                    assertEquals(SSLEngineResult.Status.OK, unwrapResult.getStatus());
+                    assertEquals(0, scratch.position());
+                    assertEquals(0, unwrapResult.bytesProduced());
+                    assertEquals(input.position() - inputPositionBefore, unwrapResult.bytesConsumed());
+                    assertFinishedOnce(finished, unwrapResult);
+                    return true;
+                }
+
+                case NEED_WRAP: {
+                    // avoid possible overflow
+                    if (output.remaining() != output.capacity()) {
+                        return false;
+                    }
+                    ByteBuffer emptyByteBuffer = ByteBuffer.allocate(0);
+                    int inputPositionBefore = emptyByteBuffer.position();
+                    int outputPositionBefore = output.position();
+                    SSLEngineResult wrapResult = engine.wrap(emptyByteBuffer, output);
+                    assertEquals(SSLEngineResult.Status.OK, wrapResult.getStatus());
+                    assertEquals(0, wrapResult.bytesConsumed());
+                    assertEquals(inputPositionBefore, emptyByteBuffer.position());
+                    assertEquals(output.position() - outputPositionBefore,
+                            wrapResult.bytesProduced());
+                    assertFinishedOnce(finished, wrapResult);
+                    return true;
+                }
+
+                case FINISHED:
+                    // only returned by wrap/unrap status, not getHandshakeStatus
+                    throw new IllegalStateException("Unexpected HandshakeStatus = " + status);
+                default:
+                    throw new IllegalStateException("Unknown HandshakeStatus = " + status);
+            }
+        } finally {
+            // shift consumed input, restore to output mode
+            input.compact();
+        }
+    }
+
+    private static void assertFinishedOnce(boolean[] finishedOut, SSLEngineResult result) {
+        if (result.getHandshakeStatus() == HandshakeStatus.FINISHED) {
+            assertFalse("should only return FINISHED once", finishedOut[0]);
+            finishedOut[0] = true;
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLSessions.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLSessions.java
new file mode 100644
index 0000000..518d7d3
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLSessions.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+/**
+ * TestSSLSessions is a convenience class for other tests that want
+ * precreated SSLSessions for testing. It contains a connected
+ * client/server pair of SSLSession as well as an invalid SSLSession.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestSSLSessions {
+    /**
+     * An invalid session that is not connected
+     */
+    public final SSLSession invalid;
+
+    /**
+     * The server side of a connected session
+     */
+    public final SSLSession server;
+
+    /**
+     * The client side of a connected session
+     */
+    public final SSLSession client;
+
+    /**
+     * The associated SSLSocketTest.Helper that is the source of
+     * the client and server SSLSessions.
+     */
+    public final TestSSLSocketPair s;
+
+    private TestSSLSessions(SSLSession invalid,
+            SSLSession server,
+            SSLSession client,
+            TestSSLSocketPair s) {
+        this.invalid = invalid;
+        this.server = server;
+        this.client = client;
+        this.s = s;
+    }
+
+    public void close() {
+        s.close();
+    }
+
+    public static TestSSLSessions create() {
+        return create(TestSSLContext.create());
+    }
+
+    public static TestSSLSessions create(TestSSLContext context) {
+        try {
+            SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            SSLSocket ssl = (SSLSocket) sf.createSocket();
+            SSLSession invalid = ssl.getSession();
+            TestSSLSocketPair s = TestSSLSocketPair.create(context).connect();
+            return new TestSSLSessions(invalid, s.server.getSession(), s.client.getSession(), s);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLSocketPair.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLSocketPair.java
new file mode 100644
index 0000000..f6a3039
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestSSLSocketPair.java
@@ -0,0 +1,161 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLSocket;
+import com.android.org.conscrypt.TestUtils;
+
+/**
+ * TestSSLSocketPair is a convenience class for other tests that want
+ * a pair of connected and handshaked client and server SSLSockets for
+ * testing.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class TestSSLSocketPair {
+    public final TestSSLContext c;
+    public final SSLSocket server;
+    public final SSLSocket client;
+    private TestSSLSocketPair(TestSSLContext c, SSLSocket server, SSLSocket client) {
+        this.c = c;
+        this.server = server;
+        this.client = client;
+    }
+    public void close() {
+        c.close();
+        try {
+            server.close();
+            client.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public SSLSocket[] sockets() {
+        return new SSLSocket[] {server, client};
+    }
+
+    public TestSSLSocketPair connect() {
+        return connect(null, null);
+    }
+
+    /**
+     * Create a new connected server/client socket pair within a
+     * existing SSLContext. Optionally specify clientCipherSuites to
+     * allow forcing new SSLSession to test SSLSessionContext
+     * caching. Optionally specify serverCipherSuites for testing
+     * cipher suite negotiation.
+     */
+    public TestSSLSocketPair connect(
+            final String[] clientCipherSuites, final String[] serverCipherSuites) {
+        try {
+            ExecutorService executor = Executors.newFixedThreadPool(2);
+            Future<Void> s = executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    if (serverCipherSuites != null) {
+                        server.setEnabledCipherSuites(serverCipherSuites);
+                    }
+                    TestUtils.setUseSessionTickets(server, true);
+                    server.startHandshake();
+                    return null;
+                }
+            });
+            Future<Void> c = executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    if (clientCipherSuites != null) {
+                        client.setEnabledCipherSuites(clientCipherSuites);
+                    }
+                    TestUtils.setUseSessionTickets(client, true);
+                    client.startHandshake();
+                    return null;
+                }
+            });
+            executor.shutdown();
+            // catch client and server exceptions separately so we can
+            // potentially log both.
+            Exception serverException;
+            try {
+                s.get(30, TimeUnit.SECONDS);
+                serverException = null;
+            } catch (Exception e) {
+                serverException = e;
+                e.printStackTrace();
+            }
+            Exception clientException;
+            try {
+                c.get(30, TimeUnit.SECONDS);
+                clientException = null;
+            } catch (Exception e) {
+                clientException = e;
+                e.printStackTrace();
+            }
+            if (serverException != null) {
+                throw serverException;
+            }
+            if (clientException != null) {
+                throw clientException;
+            }
+            // Ensure that messages can actually be passed and that any NewSessionTicket messages
+            // that come after the handshake have been processed.
+            exchangeMessages();
+            return this;
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private TestSSLSocketPair exchangeMessages() {
+        try {
+            client.getOutputStream().write('A');
+            assertEquals((int) 'A', server.getInputStream().read());
+            server.getOutputStream().write('B');
+            assertEquals((int) 'B', client.getInputStream().read());
+            return this;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static TestSSLSocketPair create() {
+        return create(TestSSLContext.create());
+    }
+
+    /**
+     * based on test_SSLSocket_startHandshake
+     */
+    public static TestSSLSocketPair create(TestSSLContext context) {
+        try {
+            SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
+                    context.host, context.port);
+            SSLSocket server = (SSLSocket) context.serverSocket.accept();
+            return new TestSSLSocketPair(context, server, client);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestTrustManager.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestTrustManager.java
new file mode 100644
index 0000000..aa3a79b
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/javax/net/ssl/TestTrustManager.java
@@ -0,0 +1,282 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.javax.net.ssl;
+
+import java.io.PrintStream;
+import java.net.Socket;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509ExtendedTrustManager;
+import javax.net.ssl.X509TrustManager;
+import com.android.org.conscrypt.java.security.StandardNames;
+import com.android.org.conscrypt.testing.NullPrintStream;
+
+/**
+ * TestTrustManager is a simple proxy class that wraps an existing
+ * X509ExtendedTrustManager to provide debug logging and recording of
+ * values.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class TestTrustManager {
+    private static final boolean LOG = false;
+    private static final PrintStream out = LOG ? System.out : new NullPrintStream();
+    private static final Class<?> EXTENDED_TRUST_MANAGER_CLASS = getExtendedTrustManagerClass();
+
+    public static TrustManager[] wrap(TrustManager[] trustManagers) {
+        TrustManager[] result = trustManagers.clone();
+        for (int i = 0; i < result.length; i++) {
+            result[i] = wrap(result[i]);
+        }
+        return result;
+    }
+
+    public static TrustManager wrap(TrustManager trustManager) {
+        if (EXTENDED_TRUST_MANAGER_CLASS != null && EXTENDED_TRUST_MANAGER_CLASS.isInstance(trustManager)) {
+            return new ExtendedWrapper((X509ExtendedTrustManager) trustManager);
+        } else if (trustManager instanceof X509TrustManager) {
+            return new Wrapper((X509TrustManager) trustManager);
+        }
+        return trustManager;
+    }
+
+    private static Class<?> getExtendedTrustManagerClass() {
+        try {
+            return Class.forName("javax.net.ssl.X509ExtendedTrustManager");
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    private static void assertClientAuthType(String authType) {
+        if (!StandardNames.CLIENT_AUTH_TYPES.contains(authType)) {
+            throw new AssertionError("Unexpected client auth type " + authType);
+        }
+    }
+
+    private static void assertServerAuthType(String authType) {
+        if (!StandardNames.SERVER_AUTH_TYPES.contains(authType)) {
+            throw new AssertionError("Unexpected server auth type " + authType);
+        }
+    }
+
+    private static final class Wrapper implements X509TrustManager {
+        private final X509TrustManager trustManager;
+
+        private Wrapper(X509TrustManager trustManager) {
+            out.println("TestTrustManager.<init> trustManager=" + trustManager);
+            this.trustManager = trustManager;
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+            out.print("TestTrustManager.checkClientTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " ");
+            try {
+                assertClientAuthType(authType);
+                trustManager.checkClientTrusted(chain, authType);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+            out.print("TestTrustManager.checkServerTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " ");
+            try {
+                assertServerAuthType(authType);
+                trustManager.checkServerTrusted(chain, authType);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+        /**
+         * Returns the list of certificate issuer authorities which are trusted for
+         * authentication of peers.
+         *
+         * @return the list of certificate issuer authorities which are trusted for
+         *         authentication of peers.
+         */
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            X509Certificate[] result = trustManager.getAcceptedIssuers();
+            out.print("TestTrustManager.getAcceptedIssuers result=" + result.length);
+            return result;
+        }
+    }
+
+    private static final class ExtendedWrapper extends X509ExtendedTrustManager {
+        private final X509ExtendedTrustManager extendedTrustManager;
+        private final X509TrustManager trustManager;
+
+        ExtendedWrapper(X509ExtendedTrustManager trustManager) {
+            out.println("TestTrustManager.<init> extendedTrustManager=" + trustManager);
+            this.extendedTrustManager = trustManager;
+            this.trustManager = trustManager;
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+            out.print("TestTrustManager.checkClientTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " ");
+            try {
+                assertClientAuthType(authType);
+                trustManager.checkClientTrusted(chain, authType);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+            out.print("TestTrustManager.checkServerTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " ");
+            try {
+                assertServerAuthType(authType);
+                trustManager.checkServerTrusted(chain, authType);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
+            throws CertificateException {
+            if (extendedTrustManager == null) {
+                out.print("(fallback to X509TrustManager) ");
+                checkClientTrusted(chain, authType);
+                return;
+            }
+            out.print("TestTrustManager.checkClientTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " "
+                + "socket=" + socket + " ");
+            try {
+                assertClientAuthType(authType);
+                extendedTrustManager.checkClientTrusted(chain, authType, socket);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
+            throws CertificateException {
+            if (extendedTrustManager == null) {
+                out.print("(fallback to X509TrustManager) ");
+                checkClientTrusted(chain, authType);
+                return;
+            }
+            out.print("TestTrustManager.checkClientTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " "
+                + "engine=" + engine + " ");
+            try {
+                assertClientAuthType(authType);
+                extendedTrustManager.checkClientTrusted(chain, authType, engine);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
+            throws CertificateException {
+            if (extendedTrustManager == null) {
+                out.print("(fallback to X509TrustManager) ");
+                checkServerTrusted(chain, authType);
+                return;
+            }
+            out.print("TestTrustManager.checkServerTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " "
+                + "socket=" + socket.toString() + " ");
+            try {
+                assertServerAuthType(authType);
+                extendedTrustManager.checkServerTrusted(chain, authType, socket);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
+            throws CertificateException {
+            if (extendedTrustManager == null) {
+                out.print("(fallback to X509TrustManager) ");
+                checkServerTrusted(chain, authType);
+                return;
+            }
+            out.print("TestTrustManager.checkServerTrusted "
+                + "chain=" + chain.length + " "
+                + "authType=" + authType + " "
+                + "engine=" + engine.toString() + " ");
+            try {
+                assertServerAuthType(authType);
+                extendedTrustManager.checkServerTrusted(chain, authType, engine);
+                out.println("OK");
+            } catch (CertificateException e) {
+                e.printStackTrace(out);
+                throw e;
+            }
+        }
+
+        /**
+         * Returns the list of certificate issuer authorities which are trusted for
+         * authentication of peers.
+         *
+         * @return the list of certificate issuer authorities which are trusted for
+         *         authentication of peers.
+         */
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            X509Certificate[] result = trustManager.getAcceptedIssuers();
+            out.print("TestTrustManager.getAcceptedIssuers result=" + result.length);
+            return result;
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/BrokenProvider.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/BrokenProvider.java
new file mode 100644
index 0000000..e7b11ff
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/BrokenProvider.java
@@ -0,0 +1,81 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt.testing;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+
+/**
+ * A provider that throws UnsupportedOperationException whenever its features are used.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class BrokenProvider extends Provider {
+
+  public static final String NAME = "BrokenProvider";
+
+  public BrokenProvider() {
+    super(NAME, 1.0, "A broken provider");
+    put("Signature.NONEwithECDSA", BrokenSignatureSpi.ECDSA.class.getName());
+  }
+
+  private static class BrokenSignatureSpi extends SignatureSpi {
+
+    BrokenSignatureSpi() { }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public final static class ECDSA extends BrokenSignatureSpi {
+      public ECDSA() {
+        super();
+      }
+    }
+
+    @Override
+    protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @Override
+    protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @Override
+    protected void engineUpdate(byte b) throws SignatureException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @Override
+    protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @Override
+    protected byte[] engineSign() throws SignatureException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @Override
+    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected void engineSetParameter(String param, Object value)
+        throws InvalidParameterException {
+      throw new UnsupportedOperationException("Nope");
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected Object engineGetParameter(String param) throws InvalidParameterException {
+      throw new UnsupportedOperationException("Nope");
+    }
+  }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/NullPrintStream.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/NullPrintStream.java
new file mode 100644
index 0000000..ca1e70b
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/NullPrintStream.java
@@ -0,0 +1,149 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.testing;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Locale;
+
+/**
+ * A PrintStream that throws away its output.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class NullPrintStream extends PrintStream {
+    public NullPrintStream() {
+        // super class complains if argument is null
+        super((OutputStream) new ByteArrayOutputStream());
+    }
+
+    @Override
+    public boolean checkError() {
+        return false;
+    }
+
+    @Override
+    protected void clearError() {}
+
+    @Override
+    public void close() {}
+
+    @Override
+    public void flush() {}
+
+    @Override
+    public PrintStream format(String format, Object... args) {
+        return this;
+    }
+
+    @Override
+    public PrintStream format(Locale l, String format, Object... args) {
+        return this;
+    }
+
+    @Override
+    public PrintStream printf(String format, Object... args) {
+        return this;
+    }
+
+    @Override
+    public PrintStream printf(Locale l, String format, Object... args) {
+        return this;
+    }
+
+    @Override
+    public void print(char[] charArray) {}
+
+    @Override
+    public void print(char ch) {}
+
+    @Override
+    public void print(double dnum) {}
+
+    @Override
+    public void print(float fnum) {}
+
+    @Override
+    public void print(int inum) {}
+
+    @Override
+    public void print(long lnum) {}
+
+    @Override
+    public void print(Object obj) {}
+
+    @Override
+    public void print(String str) {}
+
+    @Override
+    public void print(boolean bool) {}
+
+    @Override
+    public void println() {}
+
+    @Override
+    public void println(char[] charArray) {}
+
+    @Override
+    public void println(char ch) {}
+
+    @Override
+    public void println(double dnum) {}
+
+    @Override
+    public void println(float fnum) {}
+
+    @Override
+    public void println(int inum) {}
+
+    @Override
+    public void println(long lnum) {}
+
+    @Override
+    public void println(Object obj) {}
+
+    @Override
+    public void println(String str) {}
+
+    @Override
+    public void println(boolean bool) {}
+
+    @Override
+    protected void setError() {}
+
+    @Override
+    public void write(byte[] buffer, int offset, int length) {}
+
+    @Override
+    public void write(int oneByte) {}
+
+    @Override
+    public PrintStream append(char c) {
+        return this;
+    }
+
+    @Override
+    public PrintStream append(CharSequence csq) {
+        return this;
+    }
+
+    @Override
+    public PrintStream append(CharSequence csq, int start, int end) {
+        return this;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/OpaqueProvider.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/OpaqueProvider.java
new file mode 100644
index 0000000..7ad4b83
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/OpaqueProvider.java
@@ -0,0 +1,353 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt.testing;
+
+import static org.junit.Assert.fail;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECParameterSpec;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import com.android.org.conscrypt.java.security.StandardNames;
+
+/**
+ * A provider that supplies and can use keys whose keying material is hidden from callers.
+ * @hide This class is not part of the Android public SDK API
+ */
+@SuppressWarnings("serial")
+public class OpaqueProvider extends Provider {
+
+  public static final String NAME = "OpaqueProvider";
+
+  public OpaqueProvider() {
+    super(NAME, 1.0, "test provider");
+    put("Signature.NONEwithECDSA", OpaqueSignatureSpi.ECDSA.class.getName());
+    put("Cipher.RSA/ECB/NoPadding", OpaqueCipherSpi.NoPadding.class.getName());
+    put("Cipher.RSA/ECB/PKCS1Padding", OpaqueCipherSpi.PKCS1Padding.class.getName());
+  }
+
+  /**
+   * Returns an opaque key that wraps the given key.
+   */
+  public static PrivateKey wrapKey(PrivateKey key) {
+    if (key instanceof RSAPrivateKey) {
+      return new OpaqueDelegatingRSAPrivateKey((RSAPrivateKey) key);
+    } else if (key instanceof ECPrivateKey) {
+      return new OpaqueDelegatingECPrivateKey((ECPrivateKey) key);
+    } else {
+      fail("Unknown key type: " + key.getClass().getName());
+      return null;
+    }
+  }
+
+  /**
+   * Returns an opaque key that wraps the given key and is additionally marked with the
+   * appropriate FooPrivateKey interface for that key type.
+   */
+  public static PrivateKey wrapKeyMarked(PrivateKey key) {
+    if (key instanceof RSAPrivateKey) {
+      return new OpaqueDelegatingMarkedRSAPrivateKey((RSAPrivateKey) key);
+    } else if (key instanceof ECPrivateKey) {
+      return new OpaqueDelegatingMarkedECPrivateKey((ECPrivateKey) key);
+    } else {
+      fail("Unknown key type: " + key.getClass().getName());
+      return null;
+    }
+  }
+
+  private static class OpaqueSignatureSpi extends SignatureSpi {
+    private final String algorithm;
+    private Signature delegate;
+
+    OpaqueSignatureSpi(String algorithm) {
+      this.algorithm = algorithm;
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public final static class ECDSA extends OpaqueSignatureSpi {
+      public ECDSA() {
+        super("NONEwithECDSA");
+      }
+    }
+
+    @Override
+    protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+      fail("Cannot verify");
+    }
+
+    @Override
+    protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+      DelegatingPrivateKey opaqueKey = (DelegatingPrivateKey) privateKey;
+      try {
+        delegate = Signature.getInstance(algorithm);
+      } catch (NoSuchAlgorithmException e) {
+        throw new InvalidKeyException(e);
+      }
+      delegate.initSign(opaqueKey.getDelegate());
+    }
+
+    @Override
+    protected void engineUpdate(byte b) throws SignatureException {
+      delegate.update(b);
+    }
+
+    @Override
+    protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+      delegate.update(b, off, len);
+    }
+
+    @Override
+    protected byte[] engineSign() throws SignatureException {
+      return delegate.sign();
+    }
+
+    @Override
+    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+      return delegate.verify(sigBytes);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected void engineSetParameter(String param, Object value)
+        throws InvalidParameterException {
+      delegate.setParameter(param, value);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    protected Object engineGetParameter(String param) throws InvalidParameterException {
+      return delegate.getParameter(param);
+    }
+  }
+
+  private static class OpaqueCipherSpi extends CipherSpi {
+    private Cipher delegate;
+    private final String algorithm;
+
+    public OpaqueCipherSpi(String algorithm) {
+      this.algorithm = algorithm;
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public final static class NoPadding extends OpaqueCipherSpi {
+      public NoPadding() {
+        super("RSA/ECB/NoPadding");
+      }
+    }
+
+    /**
+     * @hide This class is not part of the Android public SDK API
+     */
+    public final static class PKCS1Padding extends OpaqueCipherSpi {
+      public PKCS1Padding() {
+        super("RSA/ECB/PKCS1Padding");
+      }
+    }
+
+    @Override
+    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+      fail();
+    }
+
+    @Override
+    protected void engineSetPadding(String padding) throws NoSuchPaddingException {
+      fail();
+    }
+
+    @Override
+    protected int engineGetBlockSize() {
+      return delegate.getBlockSize();
+    }
+
+    @Override
+    protected int engineGetOutputSize(int inputLen) {
+      return delegate.getOutputSize(inputLen);
+    }
+
+    @Override
+    protected byte[] engineGetIV() {
+      return delegate.getIV();
+    }
+
+    @Override
+    protected AlgorithmParameters engineGetParameters() {
+      return delegate.getParameters();
+    }
+
+    @Override
+    protected void engineInit(int opmode, Key key, SecureRandom random)
+        throws InvalidKeyException {
+      getCipher();
+      delegate.init(opmode, ((DelegatingPrivateKey) key).getDelegate(), random);
+    }
+
+    void getCipher() throws InvalidKeyException {
+      try {
+        delegate = Cipher.getInstance(algorithm, StandardNames.JSSE_PROVIDER_NAME);
+      } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
+        throw new InvalidKeyException(e);
+      }
+    }
+
+    @Override
+    protected void engineInit(
+        int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)
+        throws InvalidKeyException, InvalidAlgorithmParameterException {
+      getCipher();
+      delegate.init(opmode, ((DelegatingPrivateKey) key).getDelegate(), params, random);
+    }
+
+    @Override
+    protected void engineInit(
+        int opmode, Key key, AlgorithmParameters params, SecureRandom random)
+        throws InvalidKeyException, InvalidAlgorithmParameterException {
+      getCipher();
+      delegate.init(opmode, ((DelegatingPrivateKey) key).getDelegate(), params, random);
+    }
+
+    @Override
+    protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+      return delegate.update(input, inputOffset, inputLen);
+    }
+
+    @Override
+    protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+        int outputOffset) throws ShortBufferException {
+      return delegate.update(input, inputOffset, inputLen, output, outputOffset);
+    }
+
+    @Override
+    protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+        throws IllegalBlockSizeException, BadPaddingException {
+      return delegate.doFinal(input, inputOffset, inputLen);
+    }
+
+    @Override
+    protected int engineDoFinal(
+        byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
+        throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+      return delegate.doFinal(input, inputOffset, inputLen, output, outputOffset);
+    }
+  }
+
+  private interface DelegatingPrivateKey { PrivateKey getDelegate(); }
+
+  private static class OpaqueDelegatingECPrivateKey
+      implements ECKey, PrivateKey, DelegatingPrivateKey {
+    private final ECPrivateKey delegate;
+
+    private OpaqueDelegatingECPrivateKey(ECPrivateKey delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public PrivateKey getDelegate() {
+      return delegate;
+    }
+
+    @Override
+    public String getAlgorithm() {
+      return delegate.getAlgorithm();
+    }
+
+    @Override
+    public String getFormat() {
+      return null;
+    }
+
+    @Override
+    public byte[] getEncoded() {
+      return null;
+    }
+
+    @Override
+    public ECParameterSpec getParams() {
+      return delegate.getParams();
+    }
+  }
+
+  private static class OpaqueDelegatingMarkedECPrivateKey extends OpaqueDelegatingECPrivateKey
+      implements ECPrivateKey {
+    private OpaqueDelegatingMarkedECPrivateKey(ECPrivateKey delegate) {
+      super(delegate);
+    }
+
+    @Override
+    public BigInteger getS() {
+      throw new UnsupportedOperationException("Nope");
+    }
+  }
+
+  private static class OpaqueDelegatingRSAPrivateKey
+      implements RSAKey, PrivateKey, DelegatingPrivateKey {
+
+    private final RSAPrivateKey delegate;
+
+    private OpaqueDelegatingRSAPrivateKey(RSAPrivateKey delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public String getAlgorithm() {
+      return delegate.getAlgorithm();
+    }
+
+    @Override
+    public String getFormat() {
+      return null;
+    }
+
+    @Override
+    public byte[] getEncoded() {
+      return null;
+    }
+
+    @Override
+    public BigInteger getModulus() {
+      return delegate.getModulus();
+    }
+
+    @Override
+    public PrivateKey getDelegate() {
+      return delegate;
+    }
+  }
+
+  private static class OpaqueDelegatingMarkedRSAPrivateKey extends OpaqueDelegatingRSAPrivateKey
+     implements RSAPrivateKey {
+    private OpaqueDelegatingMarkedRSAPrivateKey(RSAPrivateKey delegate) {
+      super(delegate);
+    }
+
+    @Override
+    public BigInteger getPrivateExponent() {
+      throw new UnsupportedOperationException("Nope");
+    }
+  }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/Streams.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/Streams.java
new file mode 100644
index 0000000..9225df1
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/testing/Streams.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 com.android.org.conscrypt.testing;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Streams {
+    private Streams() {}
+
+    /**
+     * Returns a byte[] containing the remainder of 'in', closing it when done.
+     */
+    public static byte[] readFully(InputStream in) throws IOException {
+        try {
+            return readFullyNoClose(in);
+        } finally {
+            in.close();
+        }
+    }
+
+    /**
+     * Returns a byte[] containing the remainder of 'in'.
+     */
+    private static byte[] readFullyNoClose(InputStream in) throws IOException {
+        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int count;
+        while ((count = in.read(buffer)) != -1) {
+            bytes.write(buffer, 0, count);
+        }
+        return bytes.toByteArray();
+    }
+
+    /**
+     * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
+     * Returns the total number of bytes transferred.
+     */
+    public static int copy(InputStream in, OutputStream out) throws IOException {
+        int total = 0;
+        byte[] buffer = new byte[8192];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            total += c;
+            out.write(buffer, 0, c);
+        }
+        return total;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/TlsTester.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/TlsTester.java
new file mode 100644
index 0000000..fc8d802
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/TlsTester.java
@@ -0,0 +1,161 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt.tlswire;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import com.android.org.conscrypt.tlswire.handshake.ClientHello;
+import com.android.org.conscrypt.tlswire.handshake.HandshakeMessage;
+import com.android.org.conscrypt.tlswire.record.TlsProtocols;
+import com.android.org.conscrypt.tlswire.record.TlsRecord;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TlsTester {
+
+    private TlsTester() {}
+
+    public static ClientHello captureTlsHandshakeClientHello(ExecutorService executor,
+            SSLSocketFactory sslSocketFactory) throws Exception {
+        TlsRecord record = captureTlsHandshakeFirstTlsRecord(executor, sslSocketFactory);
+        return parseClientHello(record);
+    }
+
+    public static ClientHello parseClientHello(byte[] data) throws Exception {
+        return parseClientHello(parseRecord(data));
+    }
+
+    private static ClientHello parseClientHello(TlsRecord record) throws Exception {
+        assertEquals("TLS record type", TlsProtocols.HANDSHAKE, record.type);
+        ByteArrayInputStream fragmentIn = new ByteArrayInputStream(record.fragment);
+        HandshakeMessage handshakeMessage = HandshakeMessage.read(new DataInputStream(fragmentIn));
+        assertEquals(
+                "HandshakeMessage type", HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type);
+        // Assert that the fragment does not contain any more messages
+        assertEquals(0, fragmentIn.available());
+        return (ClientHello) handshakeMessage;
+    }
+
+    public static TlsRecord captureTlsHandshakeFirstTlsRecord(ExecutorService executor,
+            SSLSocketFactory sslSocketFactory) throws Exception {
+        byte[] firstReceivedChunk = captureTlsHandshakeFirstTransmittedChunkBytes(executor, sslSocketFactory);
+        return parseRecord(firstReceivedChunk);
+    }
+
+    public static TlsRecord parseRecord(byte[] data) throws Exception {
+        ByteArrayInputStream firstReceivedChunkIn = new ByteArrayInputStream(data);
+        TlsRecord record = TlsRecord.read(new DataInputStream(firstReceivedChunkIn));
+        // Assert that the chunk does not contain any more data
+        assertEquals(0, firstReceivedChunkIn.available());
+        return record;
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private static byte[] captureTlsHandshakeFirstTransmittedChunkBytes(
+            ExecutorService executor, final SSLSocketFactory sslSocketFactory) throws Exception {
+        // Since there's no straightforward way to obtain a ClientHello from SSLSocket, this test
+        // does the following:
+        // 1. Creates a listening server socket (a plain one rather than a TLS/SSL one).
+        // 2. Creates a client SSLSocket, which connects to the server socket and initiates the
+        //    TLS/SSL handshake.
+        // 3. Makes the server socket accept an incoming connection on the server socket, and reads
+        //    the first chunk of data received. This chunk is assumed to be the ClientHello.
+        // NOTE: Steps 2 and 3 run concurrently.
+        ServerSocket listeningSocket = null;
+        // Some Socket operations are not interruptible via Thread.interrupt for some reason. To
+        // work around, we unblock these sockets using Socket.close.
+        final Socket[] sockets = new Socket[2];
+        try {
+            // 1. Create the listening server socket.
+            listeningSocket = ServerSocketFactory.getDefault().createServerSocket(0);
+            final ServerSocket finalListeningSocket = listeningSocket;
+            // 2. (in background) Wait for an incoming connection and read its first chunk.
+            final Future<byte[]>
+                    readFirstReceivedChunkFuture = executor.submit(new Callable<byte[]>() {
+                @Override
+                public byte[] call() throws Exception {
+                    Socket socket = finalListeningSocket.accept();
+                    sockets[1] = socket;
+                    try {
+                        byte[] buffer = new byte[64 * 1024];
+                        int bytesRead = socket.getInputStream().read(buffer);
+                        if (bytesRead == -1) {
+                            throw new EOFException("Failed to read anything");
+                        }
+                        return Arrays.copyOf(buffer, bytesRead);
+                    } finally {
+                        closeQuietly(socket);
+                    }
+                }
+            });
+            // 3. Create a client socket, connect it to the server socket, and start the TLS/SSL
+            //    handshake.
+            executor.submit(new Callable<Void>() {
+                @Override
+                public Void call() throws Exception {
+                    Socket client = new Socket();
+                    sockets[0] = client;
+                    try {
+                        client.connect(finalListeningSocket.getLocalSocketAddress());
+                        // Initiate the TLS/SSL handshake which is expected to fail as soon as the
+                        // server socket receives a ClientHello.
+                        try {
+                            SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(client,
+                                    "localhost.localdomain", finalListeningSocket.getLocalPort(),
+                                    true);
+                            sslSocket.startHandshake();
+                            fail();
+                            return null;
+                        } catch (IOException expected) {
+                            // Ignored.
+                        }
+                        return null;
+                    } finally {
+                        closeQuietly(client);
+                    }
+                }
+            });
+            // Wait for the ClientHello to arrive
+            return readFirstReceivedChunkFuture.get(10, TimeUnit.SECONDS);
+        } finally {
+            closeQuietly(listeningSocket);
+            closeQuietly(sockets[0]);
+            closeQuietly(sockets[1]);
+        }
+    }
+
+    private static void closeQuietly(Socket socket) {
+        if (socket != null) {
+            try {
+                socket.close();
+            } catch (IOException ignored) {
+                // Ignored.
+            }
+        }
+    }
+
+    private static void closeQuietly(ServerSocket serverSocket) {
+        if (serverSocket != null) {
+            try {
+                serverSocket.close();
+            } catch (IOException ignored) {
+                // Ignored.
+            }
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/AlpnHelloExtension.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/AlpnHelloExtension.java
new file mode 100644
index 0000000..f0709ec
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/AlpnHelloExtension.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2018 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 com.android.org.conscrypt.tlswire.handshake;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import com.android.org.conscrypt.tlswire.util.IoUtils;
+
+/**
+ * {@code application_layer_protocol_negotiation} {@link HelloExtension} from RFC 7301 section 3.1.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AlpnHelloExtension extends HelloExtension {
+
+    public List<String> protocols;
+
+    @Override
+    protected void parseData() throws IOException {
+        byte[] alpnListBytes = IoUtils.readTlsVariableLengthByteVector(
+                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
+        protocols = new ArrayList<String>();
+        DataInputStream alpnList = new DataInputStream(new ByteArrayInputStream(alpnListBytes));
+        while (alpnList.available() > 0) {
+            byte[] alpnValue = IoUtils.readTlsVariableLengthByteVector(alpnList, 0xff);
+            protocols.add(new String(alpnValue, "US-ASCII"));
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("HelloExtension{type: elliptic_curves, protocols: ");
+        sb.append(protocols);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/CipherSuite.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/CipherSuite.java
new file mode 100644
index 0000000..89857dd
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/CipherSuite.java
@@ -0,0 +1,464 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.handshake;
+import java.util.HashMap;
+import java.util.Map;
+/**
+ * {@code CipherSuite} enum from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CipherSuite {
+    // The list of cipher suites below is based on IANA registry
+    // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
+    private static final CipherSuite[] CIPHER_SUITES = new CipherSuite[] {
+            new CipherSuite(0x0000, "TLS_NULL_WITH_NULL_NULL"),
+            new CipherSuite(0x0001, "TLS_RSA_WITH_NULL_MD5", "SSL_RSA_WITH_NULL_MD5"),
+            new CipherSuite(0x0002, "TLS_RSA_WITH_NULL_SHA", "SSL_RSA_WITH_NULL_SHA"),
+            new CipherSuite(
+                    0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_EXPORT_WITH_RC4_40_MD5"),
+            new CipherSuite(0x0004, "TLS_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_MD5"),
+            new CipherSuite(0x0005, "TLS_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_SHA"),
+            new CipherSuite(0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"),
+            new CipherSuite(0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA"),
+            new CipherSuite(0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"),
+            new CipherSuite(0x0009, "TLS_RSA_WITH_DES_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA"),
+            new CipherSuite(
+                    0x000a, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x000b, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"),
+            new CipherSuite(0x000c, "TLS_DH_DSS_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x000d, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x000e, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"),
+            new CipherSuite(0x000f, "TLS_DH_RSA_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"),
+            new CipherSuite(0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+                    "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"),
+            new CipherSuite(0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", "SSL_DHE_RSA_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+                    "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5",
+                    "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"),
+            new CipherSuite(0x0018, "TLS_DH_anon_WITH_RC4_128_MD5", "SSL_DH_anon_WITH_RC4_128_MD5"),
+            new CipherSuite(0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+                    "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"),
+            new CipherSuite(0x001a, "TLS_DH_anon_WITH_DES_CBC_SHA", "SSL_DH_anon_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x001b, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA",
+                    "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x001e, "TLS_KRB5_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x001f, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x0020, "TLS_KRB5_WITH_RC4_128_SHA"),
+            new CipherSuite(0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"),
+            new CipherSuite(0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"),
+            new CipherSuite(0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"),
+            new CipherSuite(0x0024, "TLS_KRB5_WITH_RC4_128_MD5"),
+            new CipherSuite(0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"),
+            new CipherSuite(0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"),
+            new CipherSuite(0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"),
+            new CipherSuite(0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"),
+            new CipherSuite(0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"),
+            new CipherSuite(0x002a, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"),
+            new CipherSuite(0x002b, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"),
+            new CipherSuite(0x002c, "TLS_PSK_WITH_NULL_SHA"),
+            new CipherSuite(0x002d, "TLS_DHE_PSK_WITH_NULL_SHA"),
+            new CipherSuite(0x002e, "TLS_RSA_PSK_WITH_NULL_SHA"),
+            new CipherSuite(0x002f, "TLS_RSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x003a, "TLS_DH_anon_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x003b, "TLS_RSA_WITH_NULL_SHA256"),
+            new CipherSuite(0x003c, "TLS_RSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x003d, "TLS_RSA_WITH_AES_256_CBC_SHA256"),
+            new CipherSuite(0x003e, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x003f, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"),
+            new CipherSuite(0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"),
+            new CipherSuite(0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"),
+            new CipherSuite(0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"),
+            new CipherSuite(0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"),
+            new CipherSuite(0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"),
+            new CipherSuite(0x0060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5"),
+            new CipherSuite(0x0061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5"),
+            new CipherSuite(0x0062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x0063, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA"),
+            new CipherSuite(0x0064, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"),
+            new CipherSuite(0x0065, "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA"),
+            new CipherSuite(0x0066, "TLS_DHE_DSS_WITH_RC4_128_SHA"),
+            new CipherSuite(0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"),
+            new CipherSuite(0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"),
+            new CipherSuite(0x006a, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"),
+            new CipherSuite(0x006b, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"),
+            new CipherSuite(0x006c, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x006d, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"),
+            new CipherSuite(0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"),
+            new CipherSuite(0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"),
+            new CipherSuite(0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"),
+            new CipherSuite(0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"),
+            new CipherSuite(0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"),
+            new CipherSuite(0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"),
+            new CipherSuite(0x008a, "TLS_PSK_WITH_RC4_128_SHA"),
+            new CipherSuite(0x008b, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x008c, "TLS_PSK_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x008d, "TLS_PSK_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x008e, "TLS_DHE_PSK_WITH_RC4_128_SHA"),
+            new CipherSuite(0x008f, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"),
+            new CipherSuite(0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"),
+            new CipherSuite(0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"),
+            new CipherSuite(0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"),
+            new CipherSuite(0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"),
+            new CipherSuite(0x009a, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"),
+            new CipherSuite(0x009b, "TLS_DH_anon_WITH_SEED_CBC_SHA"),
+            new CipherSuite(0x009c, "TLS_RSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x009d, "TLS_RSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x009e, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x009f, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00a0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00a1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00a2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00a3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00a4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00a5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00a6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00a7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00a8, "TLS_PSK_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00a9, "TLS_PSK_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00aa, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00ab, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00ac, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0x00ad, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0x00ae, "TLS_PSK_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x00af, "TLS_PSK_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0x00b0, "TLS_PSK_WITH_NULL_SHA256"),
+            new CipherSuite(0x00b1, "TLS_PSK_WITH_NULL_SHA384"),
+            new CipherSuite(0x00b2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x00b3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0x00b4, "TLS_DHE_PSK_WITH_NULL_SHA256"),
+            new CipherSuite(0x00b5, "TLS_DHE_PSK_WITH_NULL_SHA384"),
+            new CipherSuite(0x00b6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0x00b7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0x00b8, "TLS_RSA_PSK_WITH_NULL_SHA256"),
+            new CipherSuite(0x00b9, "TLS_RSA_PSK_WITH_NULL_SHA384"),
+            new CipherSuite(0x00ba, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0x00bb, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0x00bc, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0x00bd, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0x00be, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0x00bf, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0x00c0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"),
+            new CipherSuite(0x00c1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"),
+            new CipherSuite(0x00c2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"),
+            new CipherSuite(0x00c3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"),
+            new CipherSuite(0x00c4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"),
+            new CipherSuite(0x00c5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"),
+            new CipherSuite(0x00ff, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"),
+            new CipherSuite(0x1301, "TLS_AES_128_GCM_SHA256"),
+            new CipherSuite(0x1302, "TLS_AES_256_GCM_SHA384"),
+            new CipherSuite(0x1303, "TLS_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0x1304, "TLS_AES_128_CCM_SHA256"),
+            new CipherSuite(0x1305, "TLS_AES_128_CCM_8_SHA256"),
+            new CipherSuite(0x5600, "TLS_FALLBACK_SCSV"),
+            new CipherSuite(0xc001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"),
+            new CipherSuite(0xc002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"),
+            new CipherSuite(0xc003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"),
+            new CipherSuite(0xc007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"),
+            new CipherSuite(0xc008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc00a, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc00b, "TLS_ECDH_RSA_WITH_NULL_SHA"),
+            new CipherSuite(0xc00c, "TLS_ECDH_RSA_WITH_RC4_128_SHA"),
+            new CipherSuite(0xc00d, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc00e, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc00f, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc010, "TLS_ECDHE_RSA_WITH_NULL_SHA"),
+            new CipherSuite(0xc011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"),
+            new CipherSuite(0xc012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc015, "TLS_ECDH_anon_WITH_NULL_SHA"),
+            new CipherSuite(0xc016, "TLS_ECDH_anon_WITH_RC4_128_SHA"),
+            new CipherSuite(0xc017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc01a, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc01b, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc01c, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc01d, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc01e, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc01f, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0xc024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0xc025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0xc026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0xc027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0xc028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0xc029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0xc02a, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0xc02b, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0xc02c, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0xc02d, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0xc02e, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0xc02f, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0xc030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0xc031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"),
+            new CipherSuite(0xc032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"),
+            new CipherSuite(0xc033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA"),
+            new CipherSuite(0xc034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA"),
+            new CipherSuite(0xc035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"),
+            new CipherSuite(0xc036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA"),
+            new CipherSuite(0xc037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256"),
+            new CipherSuite(0xc038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384"),
+            new CipherSuite(0xc039, "TLS_ECDHE_PSK_WITH_NULL_SHA"),
+            new CipherSuite(0xc03a, "TLS_ECDHE_PSK_WITH_NULL_SHA256"),
+            new CipherSuite(0xc03b, "TLS_ECDHE_PSK_WITH_NULL_SHA384"),
+            new CipherSuite(0xc03c, "TLS_RSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc03d, "TLS_RSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc03e, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc03f, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc04a, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc04b, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc04c, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc04d, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc04e, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc04f, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc05a, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc05b, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc05c, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc05d, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc05e, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc05f, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc06a, "TLS_PSK_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc06b, "TLS_PSK_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc06c, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc06d, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc06e, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256"),
+            new CipherSuite(0xc06f, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384"),
+            new CipherSuite(0xc070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256"),
+            new CipherSuite(0xc071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384"),
+            new CipherSuite(0xc072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc07a, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc07b, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc07c, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc07d, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc07e, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc07f, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc08a, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc08b, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc08c, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc08d, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc08e, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc08f, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256"),
+            new CipherSuite(0xc093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384"),
+            new CipherSuite(0xc094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc09a, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"),
+            new CipherSuite(0xc09b, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"),
+            new CipherSuite(0xc09c, "TLS_RSA_WITH_AES_128_CCM"),
+            new CipherSuite(0xc09d, "TLS_RSA_WITH_AES_256_CCM"),
+            new CipherSuite(0xc09e, "TLS_DHE_RSA_WITH_AES_128_CCM"),
+            new CipherSuite(0xc09f, "TLS_DHE_RSA_WITH_AES_256_CCM"),
+            new CipherSuite(0xc0a0, "TLS_RSA_WITH_AES_128_CCM_8"),
+            new CipherSuite(0xc0a1, "TLS_RSA_WITH_AES_256_CCM_8"),
+            new CipherSuite(0xc0a2, "TLS_DHE_RSA_WITH_AES_128_CCM_8"),
+            new CipherSuite(0xc0a3, "TLS_DHE_RSA_WITH_AES_256_CCM_8"),
+            new CipherSuite(0xc0a4, "TLS_PSK_WITH_AES_128_CCM"),
+            new CipherSuite(0xc0a5, "TLS_PSK_WITH_AES_256_CCM"),
+            new CipherSuite(0xc0a6, "TLS_DHE_PSK_WITH_AES_128_CCM"),
+            new CipherSuite(0xc0a7, "TLS_DHE_PSK_WITH_AES_256_CCM"),
+            new CipherSuite(0xc0a8, "TLS_PSK_WITH_AES_128_CCM_8"),
+            new CipherSuite(0xc0a9, "TLS_PSK_WITH_AES_256_CCM_8"),
+            new CipherSuite(0xc0aa, "TLS_PSK_DHE_WITH_AES_128_CCM_8"),
+            new CipherSuite(0xc0ab, "TLS_PSK_DHE_WITH_AES_256_CCM_8"),
+            new CipherSuite(0xc0ac, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"),
+            new CipherSuite(0xc0ad, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"),
+            new CipherSuite(0xc0ae, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"),
+            new CipherSuite(0xc0af, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"),
+            new CipherSuite(0xcc13, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD"),
+            new CipherSuite(0xcc14, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD"),
+            new CipherSuite(0xcc15, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_OLD"),
+            new CipherSuite(0xcca8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0xcca9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0xccaa, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0xccab, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0xccac, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0xccad, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256"),
+            new CipherSuite(0xccae, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256"),
+    };
+    private static final Map<Integer, CipherSuite> CODE_TO_CIPHER_SUITE;
+    private static final Map<String, CipherSuite> NAME_TO_CIPHER_SUITE;
+    static {
+        Map<Integer, CipherSuite> byCode = new HashMap<Integer, CipherSuite>();
+        Map<String, CipherSuite> byName = new HashMap<String, CipherSuite>();
+        for (CipherSuite cipherSuite : CIPHER_SUITES) {
+            if (byCode.put(cipherSuite.code, cipherSuite) != null) {
+                throw new RuntimeException(
+                        "Cipher suite multiply defined: " + Integer.toHexString(cipherSuite.code));
+            }
+            String name = cipherSuite.name;
+            if (byName.put(name, cipherSuite) != null) {
+                throw new RuntimeException(
+                        "Cipher suite multiply defined: " + cipherSuite.name);
+            }
+            String androidName = cipherSuite.getAndroidName();
+            if (!name.equals(androidName)) {
+                if (byName.put(androidName, cipherSuite) != null) {
+                    throw new RuntimeException(
+                            "Cipher suite multiply defined: " + cipherSuite.androidName);
+                }
+            }
+        }
+        CODE_TO_CIPHER_SUITE = byCode;
+        NAME_TO_CIPHER_SUITE = byName;
+    }
+    public final int code;
+    public final String name;
+    private final String androidName;
+    private CipherSuite(int code, String name) {
+        this.code = code;
+        this.name = name;
+        this.androidName = null;
+    }
+    private CipherSuite(int code, String name, String androidName) {
+        this.code = code;
+        this.name = name;
+        this.androidName = androidName;
+    }
+    public static CipherSuite valueOf(String name) {
+        CipherSuite result = NAME_TO_CIPHER_SUITE.get(name);
+        if (result != null) {
+            return result;
+        }
+        throw new IllegalArgumentException("Unknown cipher suite: " + name);
+    }
+    public static CipherSuite valueOf(int code) {
+        CipherSuite result = CODE_TO_CIPHER_SUITE.get(code);
+        if (result != null) {
+            return result;
+        }
+        return new CipherSuite(code, Integer.toHexString(code));
+    }
+    public String getAndroidName() {
+        return (androidName != null) ? androidName : name;
+    }
+    @Override
+    public String toString() {
+        return name;
+    }
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + code;
+        return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        CipherSuite other = (CipherSuite) obj;
+        if (code != other.code) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/ClientHello.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/ClientHello.java
new file mode 100644
index 0000000..55d2575
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/ClientHello.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.handshake;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import com.android.org.conscrypt.tlswire.util.IoUtils;
+import com.android.org.conscrypt.tlswire.util.TlsProtocolVersion;
+
+/**
+ * {@link ClientHello} {@link HandshakeMessage} from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ClientHello extends HandshakeMessage {
+    public TlsProtocolVersion clientVersion;
+    public byte[] random;
+    public byte[] sessionId;
+    public List<CipherSuite> cipherSuites;
+    public List<CompressionMethod> compressionMethods;
+    /** Extensions or {@code null} for no extensions. */
+    public List<HelloExtension> extensions;
+    @Override
+    protected void parseBody(DataInput in) throws IOException {
+        clientVersion = TlsProtocolVersion.read(in);
+        random = new byte[32];
+        in.readFully(random);
+        sessionId = IoUtils.readTlsVariableLengthByteVector(in, 32);
+        int[] cipherSuiteCodes = IoUtils.readTlsVariableLengthUnsignedShortVector(in, 0xfffe);
+        cipherSuites = new ArrayList<CipherSuite>(cipherSuiteCodes.length);
+        for (int i = 0; i < cipherSuiteCodes.length; i++) {
+            cipherSuites.add(CipherSuite.valueOf(cipherSuiteCodes[i]));
+        }
+        byte[] compressionMethodCodes = IoUtils.readTlsVariableLengthByteVector(in, 0xff);
+        compressionMethods = new ArrayList<CompressionMethod>(compressionMethodCodes.length);
+        for (int i = 0; i < compressionMethodCodes.length; i++) {
+            int code = compressionMethodCodes[i] & 0xff;
+            compressionMethods.add(CompressionMethod.valueOf(code));
+        }
+        int extensionsSectionSize;
+        try {
+            extensionsSectionSize = in.readUnsignedShort();
+        } catch (EOFException e) {
+            // No extensions present
+            extensionsSectionSize = 0;
+        }
+        if (extensionsSectionSize > 0) {
+            extensions = new ArrayList<HelloExtension>();
+            byte[] extensionsBytes = new byte[extensionsSectionSize];
+            in.readFully(extensionsBytes);
+            ByteArrayInputStream extensionsIn = new ByteArrayInputStream(extensionsBytes);
+            DataInput extensionsDataIn = new DataInputStream(extensionsIn);
+            while (extensionsIn.available() > 0) {
+                try {
+                    extensions.add(HelloExtension.read(extensionsDataIn));
+                } catch (IOException e) {
+                    throw new IOException(
+                            "Failed to read HelloExtension #" + (extensions.size() + 1));
+                }
+            }
+        }
+    }
+    public HelloExtension findExtensionByType(int extensionType) {
+        if (extensions == null) {
+            return null;
+        }
+        for (HelloExtension extension : extensions) {
+            if (extension.type == extensionType) {
+                return extension;
+            }
+        }
+        return null;
+    }
+    @Override
+    public String toString() {
+        return "ClientHello{client version: " + clientVersion + ", random: "
+                + new BigInteger(1, random).toString(16) + ", sessionId: "
+                + new BigInteger(1, sessionId).toString(16) + ", cipher suites: " + cipherSuites
+                + ", compression methods: " + compressionMethods
+                + ((extensions != null) ? (", extensions: " + String.valueOf(extensions)) : "")
+                + "}";
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/CompressionMethod.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/CompressionMethod.java
new file mode 100644
index 0000000..88069d2
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/CompressionMethod.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.handshake;
+/**
+ * {@code CompressionMethod} enum from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class CompressionMethod {
+    public static final CompressionMethod NULL = new CompressionMethod(0, "null");
+    public static final CompressionMethod DEFLATE = new CompressionMethod(1, "deflate");
+    public final int type;
+    public final String name;
+    private CompressionMethod(int type, String name) {
+        this.type = type;
+        this.name = name;
+    }
+    public static CompressionMethod valueOf(int type) {
+        switch (type) {
+            case 0:
+                return NULL;
+            case 1:
+                return DEFLATE;
+            default:
+                return new CompressionMethod(type, String.valueOf(type));
+        }
+    }
+    @Override
+    public String toString() {
+        return name;
+    }
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + type;
+        return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        CompressionMethod other = (CompressionMethod) obj;
+        if (type != other.type) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/EllipticCurve.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/EllipticCurve.java
new file mode 100644
index 0000000..01fc90e
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/EllipticCurve.java
@@ -0,0 +1,79 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.org.conscrypt.tlswire.handshake;
+/**
+ * {@code EllipticCurve} enum from RFC 4492 section 5.1.1. Curves are assigned
+ * via the
+ * <a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8">IANA registry</a>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum EllipticCurve {
+    SECT163K1(1, "sect163k1"),
+    SECT163R1(2, "sect163r1"),
+    SECT163R2(3, "sect163r2"),
+    SECT193R1(4, "sect193r1"),
+    SECT193R2(5, "sect193r2"),
+    SECT233K1(6, "sect233k1"),
+    SECT233R1(7, "sect233r1"),
+    SECT239K1(8, "sect239k1"),
+    SECT283K1(9, "sect283k1"),
+    SECT283R1(10, "sect283r1"),
+    SECT409K1(11, "sect409k1"),
+    SECT409R1(12, "sect409r1"),
+    SECT571K1(13, "sect571k1"),
+    SECT571R1(14, "sect571r1"),
+    SECP160K1(15, "secp160k1"),
+    SECP160R1(16, "secp160r1"),
+    SECP160R2(17, "secp160r2"),
+    SECP192K1(18, "secp192k1"),
+    SECP192R1(19, "secp192r1"),
+    SECP224K1(20, "secp224k1"),
+    SECP224R1(21, "secp224r1"),
+    SECP256K1(22, "secp256k1"),
+    SECP256R1(23, "secp256r1"),
+    SECP384R1(24, "secp384r1"),
+    SECP521R1(25, "secp521r1"),
+    BRAINPOOLP256R1(26, "brainpoolP256r1"),
+    BRAINPOOLP384R1(27, "brainpoolP384r1"),
+    BRAINPOOLP521R1(28, "brainpoolP521r1"),
+    X25519(29, "x25519"),
+    X448(30, "x448"),
+    ARBITRARY_PRIME(0xFF01, "arbitrary_explicit_prime_curves"),
+    ARBITRARY_CHAR2(0xFF02, "arbitrary_explicit_char2_curves");
+    public final int identifier;
+    public final String name;
+    private EllipticCurve(int identifier, String name) {
+        this.identifier = identifier;
+        this.name = name;
+    }
+    public static EllipticCurve fromIdentifier(int identifier) {
+        for (EllipticCurve curve : values()) {
+            if (curve.identifier == identifier) {
+                return curve;
+            }
+        }
+        throw new AssertionError("Unknown curve identifier " + identifier);
+    }
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(name);
+        sb.append(" (");
+        sb.append(identifier);
+        sb.append(')');
+        return sb.toString();
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/EllipticCurvesHelloExtension.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/EllipticCurvesHelloExtension.java
new file mode 100644
index 0000000..56dc55d
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/EllipticCurvesHelloExtension.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.org.conscrypt.tlswire.handshake;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import com.android.org.conscrypt.tlswire.util.IoUtils;
+
+/**
+ * {@code elliptic_curves} {@link HelloExtension} from RFC 4492 section 5.1.1.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class EllipticCurvesHelloExtension extends HelloExtension {
+    public List<EllipticCurve> supported;
+    public boolean wellFormed;
+    @Override
+    protected void parseData() throws IOException {
+        byte[] ellipticCurvesListBytes = IoUtils.readTlsVariableLengthByteVector(
+                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
+        ByteArrayInputStream ellipticCurvesListIn =
+                new ByteArrayInputStream(ellipticCurvesListBytes);
+        DataInputStream in = new DataInputStream(ellipticCurvesListIn);
+        wellFormed = (ellipticCurvesListIn.available() % 2) == 0;
+        supported = new ArrayList<EllipticCurve>(ellipticCurvesListIn.available() / 2);
+        while (ellipticCurvesListIn.available() >= 2) {
+            int curve_id = in.readUnsignedShort();
+            supported.add(EllipticCurve.fromIdentifier(curve_id));
+        }
+    }
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("HelloExtension{type: elliptic_curves, wellFormed: ");
+        sb.append(wellFormed);
+        sb.append(", supported: ");
+        sb.append(supported);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/HandshakeMessage.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/HandshakeMessage.java
new file mode 100644
index 0000000..4e04f2f
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/HandshakeMessage.java
@@ -0,0 +1,60 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.handshake;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+import com.android.org.conscrypt.tlswire.util.IoUtils;
+
+/**
+ * Handshake Protocol message from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HandshakeMessage {
+    public static final int TYPE_CLIENT_HELLO = 1;
+    public int type;
+    public byte[] body;
+    /**
+     * Parses the provided TLS record as a handshake message.
+     */
+    public static HandshakeMessage read(DataInput in) throws IOException {
+        int type = in.readUnsignedByte();
+        HandshakeMessage result;
+        switch (type) {
+            case TYPE_CLIENT_HELLO:
+                result = new ClientHello();
+                break;
+            default:
+                result = new HandshakeMessage();
+                break;
+        }
+        result.type = type;
+        int bodyLength = IoUtils.readUnsignedInt24(in);
+        result.body = new byte[bodyLength];
+        in.readFully(result.body);
+        result.parseBody(new DataInputStream(new ByteArrayInputStream(result.body)));
+        return result;
+    }
+    /**
+     * Parses the provided body. The default implementation does nothing.
+     *
+     * @throws IOException if an I/O error occurs.
+     */
+    protected void parseBody(@SuppressWarnings("unused") DataInput in) throws IOException {}
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/HelloExtension.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/HelloExtension.java
new file mode 100644
index 0000000..298bd52
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/HelloExtension.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.handshake;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+import com.android.org.conscrypt.tlswire.util.IoUtils;
+
+/**
+ * {@code HelloExtension} struct from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HelloExtension {
+    public static final int TYPE_SERVER_NAME = 0;
+    public static final int TYPE_ELLIPTIC_CURVES = 10;
+    public static final int TYPE_APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16;
+    public static final int TYPE_PADDING = 21;
+    public static final int TYPE_SESSION_TICKET = 35;
+    public static final int TYPE_RENEGOTIATION_INFO = 65281;
+    private static final Map<Integer, String> TYPE_TO_NAME = new HashMap<Integer, String>();
+    static {
+        TYPE_TO_NAME.put(TYPE_SERVER_NAME, "server_name");
+        TYPE_TO_NAME.put(1, "max_fragment_length");
+        TYPE_TO_NAME.put(2, "client_certificate_url");
+        TYPE_TO_NAME.put(3, "trusted_ca_keys");
+        TYPE_TO_NAME.put(4, "truncated_hmac");
+        TYPE_TO_NAME.put(5, "status_request");
+        TYPE_TO_NAME.put(6, "user_mapping");
+        TYPE_TO_NAME.put(7, "client_authz");
+        TYPE_TO_NAME.put(8, "server_authz");
+        TYPE_TO_NAME.put(9, "cert_type");
+        TYPE_TO_NAME.put(TYPE_ELLIPTIC_CURVES, "elliptic_curves");
+        TYPE_TO_NAME.put(11, "ec_point_formats");
+        TYPE_TO_NAME.put(12, "srp");
+        TYPE_TO_NAME.put(13, "signature_algorithms");
+        TYPE_TO_NAME.put(14, "use_srtp");
+        TYPE_TO_NAME.put(15, "heartbeat");
+        TYPE_TO_NAME.put(TYPE_APPLICATION_LAYER_PROTOCOL_NEGOTIATION, "application_layer_protocol_negotiation");
+        TYPE_TO_NAME.put(17, "status_request_v2");
+        TYPE_TO_NAME.put(18, "signed_certificate_timestamp");
+        TYPE_TO_NAME.put(19, "client_certificate_type");
+        TYPE_TO_NAME.put(20, "server_certificate_type");
+        TYPE_TO_NAME.put(TYPE_PADDING, "padding");
+        TYPE_TO_NAME.put(TYPE_SESSION_TICKET, "SessionTicket");
+        TYPE_TO_NAME.put(13172, "next_protocol_negotiation");
+        TYPE_TO_NAME.put(30031, "Channel ID (old)");
+        TYPE_TO_NAME.put(30032, "Channel ID (new)");
+        TYPE_TO_NAME.put(TYPE_RENEGOTIATION_INFO, "renegotiation_info");
+    }
+    public int type;
+    public String name;
+    public byte[] data;
+    public static HelloExtension read(DataInput in) throws IOException {
+        int type = in.readUnsignedShort();
+        HelloExtension result;
+        switch (type) {
+            case TYPE_SERVER_NAME:
+                result = new ServerNameHelloExtension();
+                break;
+            case TYPE_ELLIPTIC_CURVES:
+                result = new EllipticCurvesHelloExtension();
+                break;
+            case TYPE_APPLICATION_LAYER_PROTOCOL_NEGOTIATION:
+                result = new AlpnHelloExtension();
+                break;
+            default:
+                result = new HelloExtension();
+                break;
+        }
+        result.type = type;
+        result.name = TYPE_TO_NAME.get(result.type);
+        if (result.name == null) {
+            result.name = String.valueOf(result.type);
+        }
+        result.data = IoUtils.readTlsVariableLengthByteVector(in, 0xffff);
+        result.parseData();
+        return result;
+    }
+    /**
+     * @throws IOException
+     */
+    protected void parseData() throws IOException {}
+    @Override
+    public String toString() {
+        return "HelloExtension{type: " + name + ", data: " + new BigInteger(1, data).toString(16)
+                + "}";
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/ServerNameHelloExtension.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/ServerNameHelloExtension.java
new file mode 100644
index 0000000..27262db
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/handshake/ServerNameHelloExtension.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.handshake;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import com.android.org.conscrypt.tlswire.util.IoUtils;
+
+/**
+ * {@code server_name} (SNI) {@link HelloExtension} from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ServerNameHelloExtension extends HelloExtension {
+    private static final int TYPE_HOST_NAME = 0;
+    public List<String> hostnames;
+    @Override
+    protected void parseData() throws IOException {
+        byte[] serverNameListBytes = IoUtils.readTlsVariableLengthByteVector(
+                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
+        ByteArrayInputStream serverNameListIn = new ByteArrayInputStream(serverNameListBytes);
+        DataInputStream in = new DataInputStream(serverNameListIn);
+        hostnames = new ArrayList<String>();
+        while (serverNameListIn.available() > 0) {
+            int type = in.readUnsignedByte();
+            if (type != TYPE_HOST_NAME) {
+                throw new IOException("Unsupported ServerName type: " + type);
+            }
+            byte[] hostnameBytes = IoUtils.readTlsVariableLengthByteVector(in, 0xffff);
+            String hostname = new String(hostnameBytes, "US-ASCII");
+            hostnames.add(hostname);
+        }
+    }
+    @Override
+    public String toString() {
+        return "HelloExtension{type: server_name, hostnames: " + hostnames + "}";
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/record/TlsProtocols.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/record/TlsProtocols.java
new file mode 100644
index 0000000..a96afd1
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/record/TlsProtocols.java
@@ -0,0 +1,29 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.record;
+/**
+ * Protocols that can run over the TLS Record Protocol from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TlsProtocols {
+    public static final int CHANGE_CIPHER_SPEC = 20;
+    public static final int ALERT = 21;
+    public static final int HANDSHAKE = 22;
+    public static final int APPLICATION_DATA = 23;
+    public static final int HEARTBEAT = 24;
+    private TlsProtocols() {}
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/record/TlsRecord.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/record/TlsRecord.java
new file mode 100644
index 0000000..c22bb9b
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/record/TlsRecord.java
@@ -0,0 +1,40 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.record;
+
+import java.io.DataInput;
+import java.io.IOException;
+import com.android.org.conscrypt.tlswire.util.TlsProtocolVersion;
+
+/**
+ * TLS Record Protocol record from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TlsRecord {
+    public int type;
+    public TlsProtocolVersion version;
+    public byte[] fragment;
+    public static TlsRecord read(DataInput in) throws IOException {
+        TlsRecord result = new TlsRecord();
+        result.type = in.readUnsignedByte();
+        result.version = TlsProtocolVersion.read(in);
+        int fragmentLength = in.readUnsignedShort();
+        result.fragment = new byte[fragmentLength];
+        in.readFully(result.fragment);
+        return result;
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/util/IoUtils.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/util/IoUtils.java
new file mode 100644
index 0000000..ecbefab
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/util/IoUtils.java
@@ -0,0 +1,56 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.util;
+import java.io.DataInput;
+import java.io.IOException;
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class IoUtils {
+    public static int readUnsignedInt24(DataInput in) throws IOException {
+        return (in.readUnsignedByte() << 16) | in.readUnsignedShort();
+    }
+    public static byte[] readTlsVariableLengthByteVector(DataInput in, int maxSizeBytes)
+            throws IOException {
+        int sizeBytes = readTlsVariableLengthVectorSizeBytes(in, maxSizeBytes);
+        byte[] result = new byte[sizeBytes];
+        in.readFully(result);
+        return result;
+    }
+    public static int[] readTlsVariableLengthUnsignedShortVector(DataInput in, int maxSizeBytes)
+            throws IOException {
+        int sizeBytes = readTlsVariableLengthVectorSizeBytes(in, maxSizeBytes);
+        int elementCount = sizeBytes / 2;
+        int[] result = new int[elementCount];
+        for (int i = 0; i < elementCount; i++) {
+            result[i] = in.readUnsignedShort();
+        }
+        return result;
+    }
+    private static int readTlsVariableLengthVectorSizeBytes(DataInput in, int maxSizeBytes)
+            throws IOException {
+        if (maxSizeBytes < 0x100) {
+            return in.readUnsignedByte();
+        } else if (maxSizeBytes < 0x10000) {
+            return in.readUnsignedShort();
+        } else if (maxSizeBytes < 0x1000000) {
+            return readUnsignedInt24(in);
+        } else {
+            return in.readInt();
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/util/TlsProtocolVersion.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/util/TlsProtocolVersion.java
new file mode 100644
index 0000000..0aa4446
--- /dev/null
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/tlswire/util/TlsProtocolVersion.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.org.conscrypt.tlswire.util;
+import java.io.DataInput;
+import java.io.IOException;
+/**
+ * {@code ProtovolVersion} struct from TLS 1.2 RFC 5246.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class TlsProtocolVersion {
+    public static final TlsProtocolVersion SSLV3 = new TlsProtocolVersion(3, 0, "SSLv3");
+    public static final TlsProtocolVersion TLSv1_0 = new TlsProtocolVersion(3, 1, "TLSv1.0");
+    public static final TlsProtocolVersion TLSv1_1 = new TlsProtocolVersion(3, 2, "TLSv1.1");
+    public static final TlsProtocolVersion TLSv1_2 = new TlsProtocolVersion(3, 3, "TLSv1.2");
+    public static final TlsProtocolVersion TLSv1_3 = new TlsProtocolVersion(3, 4, "TLSv1.3");
+    public final int major;
+    public final int minor;
+    public final String name;
+    private TlsProtocolVersion(int major, int minor, String name) {
+        this.major = major;
+        this.minor = minor;
+        this.name = name;
+    }
+    public static TlsProtocolVersion valueOf(int major, int minor) {
+        if (major == 3) {
+            switch (minor) {
+                case 0:
+                    return SSLV3;
+                case 1:
+                    return TLSv1_0;
+                case 2:
+                    return TLSv1_1;
+                case 3:
+                    return TLSv1_2;
+                case 4:
+                    return TLSv1_3;
+            }
+        }
+        return new TlsProtocolVersion(major, minor, major + "." + minor);
+    }
+    public static TlsProtocolVersion read(DataInput in) throws IOException {
+        int major = in.readUnsignedByte();
+        int minor = in.readUnsignedByte();
+        return TlsProtocolVersion.valueOf(major, minor);
+    }
+    @Override
+    public String toString() {
+        return name;
+    }
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + major;
+        result = prime * result + minor;
+        return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        TlsProtocolVersion other = (TlsProtocolVersion) obj;
+        if (major != other.major) {
+            return false;
+        }
+        if (minor != other.minor) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/repackaged/testing/src/main/java/tests/net/DelegatingSSLSocketFactory.java b/repackaged/testing/src/main/java/tests/net/DelegatingSSLSocketFactory.java
new file mode 100644
index 0000000..f93df76
--- /dev/null
+++ b/repackaged/testing/src/main/java/tests/net/DelegatingSSLSocketFactory.java
@@ -0,0 +1,83 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 tests.net;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+/**
+ * {@link SSLSocketFactory} which delegates all invocations to the provided delegate
+ * {@code SSLSocketFactory}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DelegatingSSLSocketFactory extends SSLSocketFactory {
+    private final SSLSocketFactory mDelegate;
+    public DelegatingSSLSocketFactory(SSLSocketFactory delegate) {
+        this.mDelegate = delegate;
+    }
+    /**
+     * Invoked after obtaining a socket from the delegate and before returning it to the caller.
+     *
+     * <p>The default implementation does nothing.
+     */
+    protected SSLSocket configureSocket(SSLSocket socket) throws IOException {
+        return socket;
+    }
+    @Override
+    public String[] getDefaultCipherSuites() {
+        return mDelegate.getDefaultCipherSuites();
+    }
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return mDelegate.getSupportedCipherSuites();
+    }
+    @Override
+    public Socket createSocket() throws IOException {
+        SSLSocket socket = (SSLSocket) mDelegate.createSocket();
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(Socket s, String host, int port, boolean autoClose)
+            throws IOException {
+        SSLSocket socket = (SSLSocket) mDelegate.createSocket(s, host, port, autoClose);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+        SSLSocket socket = (SSLSocket) mDelegate.createSocket(host, port);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+            throws IOException, UnknownHostException {
+        SSLSocket socket = (SSLSocket) mDelegate.createSocket(host, port, localHost, localPort);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(InetAddress host, int port) throws IOException {
+        SSLSocket socket = (SSLSocket) mDelegate.createSocket(host, port);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+            int localPort) throws IOException {
+        SSLSocket socket = (SSLSocket) mDelegate.createSocket(address, port, localAddress, localPort);
+        return configureSocket(socket);
+    }
+}
diff --git a/repackaged/testing/src/main/java/tests/net/DelegatingSocketFactory.java b/repackaged/testing/src/main/java/tests/net/DelegatingSocketFactory.java
new file mode 100644
index 0000000..c412ed4
--- /dev/null
+++ b/repackaged/testing/src/main/java/tests/net/DelegatingSocketFactory.java
@@ -0,0 +1,68 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 tests.net;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import javax.net.SocketFactory;
+/**
+ * {@link SocketFactory} which delegates all invocations to the provided delegate
+ * {@code SocketFactory}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class DelegatingSocketFactory extends SocketFactory {
+    private final SocketFactory mDelegate;
+    public DelegatingSocketFactory(SocketFactory delegate) {
+        this.mDelegate = delegate;
+    }
+    /**
+     * Invoked after obtaining a socket from the delegate and before returning it to the caller.
+     *
+     * <p>The default implementation does nothing.
+     */
+    protected Socket configureSocket(Socket socket) throws IOException {
+        return socket;
+    }
+    @Override
+    public Socket createSocket() throws IOException {
+        Socket socket = mDelegate.createSocket();
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+        Socket socket = mDelegate.createSocket(host, port);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+            throws IOException, UnknownHostException {
+        Socket socket = mDelegate.createSocket(host, port, localHost, localPort);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(InetAddress host, int port) throws IOException {
+        Socket socket = mDelegate.createSocket(host, port);
+        return configureSocket(socket);
+    }
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
+            int localPort) throws IOException {
+        Socket socket = mDelegate.createSocket(address, port, localAddress, localPort);
+        return configureSocket(socket);
+    }
+}
diff --git a/repackaged/testing/src/main/java/tests/util/ForEachRunner.java b/repackaged/testing/src/main/java/tests/util/ForEachRunner.java
new file mode 100644
index 0000000..614716d
--- /dev/null
+++ b/repackaged/testing/src/main/java/tests/util/ForEachRunner.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 tests.util;
+/**
+ * Runner which executes the provided code under test (via a callback) for each provided input
+ * value.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ForEachRunner {
+    /**
+     * Callback parameterized with a value.
+     * @hide This class is not part of the Android public SDK API
+     */
+    public interface Callback<T> {
+        /**
+         * Invokes the callback for the provided value.
+         */
+        void run(T value) throws Exception;
+    }
+    private ForEachRunner() {}
+    /**
+     * Invokes the provided callback for each of the provided named values.
+     *
+     * @param namesAndValues named values represented as name-value pairs.
+     *
+     * @param <T> type of value.
+     */
+    public static <T> void runNamed(Callback<T> callback, Iterable<Pair<String, T>> namesAndValues)
+            throws Exception {
+        for (Pair<String, T> nameAndValue : namesAndValues) {
+            try {
+                callback.run(nameAndValue.getSecond());
+            } catch (Throwable e) {
+                throw new Exception("Failed for " + nameAndValue.getFirst() + ": " + e.getMessage(), e);
+            }
+        }
+    }
+}
diff --git a/repackaged/testing/src/main/java/tests/util/Pair.java b/repackaged/testing/src/main/java/tests/util/Pair.java
new file mode 100644
index 0000000..1bf662e
--- /dev/null
+++ b/repackaged/testing/src/main/java/tests/util/Pair.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2010 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 tests.util;
+/**
+ * Pair of typed values.
+ *
+ * <p>Pairs are obtained using {@link #of(Object, Object) of}.
+ *
+ * @param <F> type of the first value.
+ * @param <S> type of the second value.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Pair<F, S> {
+    private final F mFirst;
+    private final S mSecond;
+    private Pair(F first, S second) {
+        mFirst = first;
+        mSecond = second;
+    }
+    /**
+     * Gets the pair consisting of the two provided values.
+     *
+     * @param first first value or {@code null}.
+     * @param second second value or {@code null}.
+     */
+    public static <F, S> Pair<F, S> of(F first, S second) {
+        return new Pair<F, S>(first, second);
+    }
+    /**
+     * Gets the first value from this pair.
+     *
+     * @return value or {@code null}.
+     */
+    public F getFirst() {
+        return mFirst;
+    }
+    /**
+     * Gets the second value from this pair.
+     *
+     * @return value or {@code null}.
+     */
+    public S getSecond() {
+        return mSecond;
+    }
+    @Override
+    public String toString() {
+        return "Pair[" + mFirst + ", " + mSecond + "]";
+    }
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mFirst == null) ? 0 : mFirst.hashCode());
+        result = prime * result + ((mSecond == null) ? 0 : mSecond.hashCode());
+        return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        @SuppressWarnings("rawtypes")
+        Pair other = (Pair) obj;
+        if (mFirst == null) {
+            if (other.mFirst != null) {
+                return false;
+            }
+        } else if (!mFirst.equals(other.mFirst)) {
+            return false;
+        }
+        if (mSecond == null) {
+            if (other.mSecond != null) {
+                return false;
+            }
+        } else if (!mSecond.equals(other.mSecond)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/repackaged/testing/src/main/java/tests/util/ServiceTester.java b/repackaged/testing/src/main/java/tests/util/ServiceTester.java
new file mode 100644
index 0000000..e2e325c
--- /dev/null
+++ b/repackaged/testing/src/main/java/tests/util/ServiceTester.java
@@ -0,0 +1,179 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2019 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 tests.util;
+
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * A utility for testing all the implementations of a particular service (such as MessageDigest or
+ * KeyGenerator).
+ * <p>
+ * An instance of this class may only be used to run one test.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ServiceTester {
+
+  /**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Test {
+    /**
+     * Run the test for the given provider and algorithm.  This method should throw an exception
+     * if the test fails or do nothing if it passes.
+     */
+    void test(Provider p, String algorithm) throws Exception;
+  }
+
+  private final String service;
+  private Set<Provider> providers = new LinkedHashSet<>();
+  private Set<Provider> skipProviders = new HashSet<>();
+  private Set<String> algorithms = new LinkedHashSet<>();
+  private Set<String> skipAlgorithms = new HashSet<>();
+
+  private ServiceTester(String service) {
+    this.service = service;
+  }
+
+  /**
+   * Create a new ServiceTester for the given service.
+   */
+  public static ServiceTester test(String service) {
+    if (service.equalsIgnoreCase("Cipher")) {
+      // Cipher is complicated because the parameterized transformations mean that you have
+      // to check for a lot of combinations (eg, a test for AES/CBC/NoPadding might be satisfied by
+      // a provider providing AES, AES/CBC, AES//NoPadding, or AES/CBC/NoPadding).  We don't
+      // really need it, so we haven't implemented it.
+      throw new IllegalArgumentException("ServiceTester doesn't support Cipher");
+    }
+    return new ServiceTester(service);
+  }
+
+  /**
+   * Specifies the list of providers to test.  If this method is called multiple times, the
+   * collections are combined.  If this method is never called, this will test all installed
+   * providers.
+   *
+   * @throws IllegalArgumentException if a named provider is not installed
+   */
+  public ServiceTester withProviders(Collection<String> providers) {
+    for (String name : providers) {
+      Provider p = Security.getProvider(name);
+      if (p == null) {
+        throw new IllegalArgumentException("No such provider: " + name);
+      }
+      this.providers.add(p);
+    }
+    return this;
+  }
+
+  /**
+   * Causes the given provider to be omitted from this instance's testing.  If the given provider
+   * is not installed, does nothing.
+   */
+  public ServiceTester skipProvider(String provider) {
+    Provider p = Security.getProvider(provider);
+    if (p != null) {
+      skipProviders.add(p);
+    }
+    return this;
+  }
+
+  /**
+   * Specifies the algorithm to test.  If this method and/or {@link #withAlgorithms(Collection)}}
+   * are called multiple times, all values are combined.  If neither method is called, this will
+   * test all algorithms supported by any tested provider.
+   */
+  public ServiceTester withAlgorithm(String algorithm) {
+    this.algorithms.add(algorithm);
+    return this;
+  }
+
+  /**
+   * Specifies the algorithms to test.  If this method and/or {@link #withAlgorithm(String)}}
+   * are called multiple times, all values are combined.  If neither method is called, this will
+   * test all algorithms supported by any tested provider.
+   */
+  public ServiceTester withAlgorithms(Collection<String> algorithms) {
+    this.algorithms.addAll(algorithms);
+    return this;
+  }
+
+  /**
+   * Causes the given algorithm to be omitted from this instance's testing.  If no tested provider
+   * provides the given algorithm, does nothing.
+   */
+  public ServiceTester skipAlgorithm(String algorithm) {
+    skipAlgorithms.add(algorithm);
+    return this;
+  }
+
+  /**
+   * Runs the given test against the configured combination of providers and algorithms.  Continues
+   * running all combinations even if some fail.  If any of the test runs fail, this throws
+   * an exception with the details of the failure(s).
+   */
+  public void run(Test test) {
+    if (providers.isEmpty()) {
+      providers.addAll(Arrays.asList(Security.getProviders()));
+    }
+    providers.removeAll(skipProviders);
+    final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
+    PrintStream errors = new PrintStream(errBuffer);
+    for (Provider p : providers) {
+      if (algorithms.isEmpty()) {
+        for (Provider.Service s : p.getServices()) {
+          if (s.getType().equals(service) && !skipAlgorithms.contains(s.getAlgorithm())) {
+            doTest(test, p, s.getAlgorithm(), errors);
+          }
+        }
+      } else {
+        algorithms.removeAll(skipAlgorithms);
+        for (String algorithm : algorithms) {
+          if (p.getService(service, algorithm) != null) {
+            doTest(test, p, algorithm, errors);
+          }
+        }
+      }
+    }
+    errors.flush();
+    if (errBuffer.size() > 0) {
+      fail("Tests failed:\n\n" + errBuffer.toString());
+    }
+  }
+
+  private void doTest(Test test, Provider p, String algorithm, PrintStream errors) {
+    try {
+      test.test(p, algorithm);
+    } catch (Exception e) {
+      errors.append("Failure testing " + service + ":" + algorithm
+          + " from provider " + p.getName() + ":\n");
+      e.printStackTrace(errors);
+    }
+  }
+
+}
diff --git a/srcgen/core-platform-api.txt b/srcgen/core-platform-api.txt
new file mode 100644
index 0000000..c882063
--- /dev/null
+++ b/srcgen/core-platform-api.txt
@@ -0,0 +1,58 @@
+method:com.android.org.conscrypt.ClientSessionContext#setPersistentCache(SSLClientSessionCache)
+method:com.android.org.conscrypt.Conscrypt#getDefaultX509TrustManager()
+method:com.android.org.conscrypt.FileClientSessionCache#usingDirectory(File)
+method:com.android.org.conscrypt.OpenSSLProvider#OpenSSLProvider()
+method:com.android.org.conscrypt.OpenSSLSocketImpl#getAlpnSelectedProtocol()
+method:com.android.org.conscrypt.OpenSSLSocketImpl#getNpnSelectedProtocol()
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setAlpnProtocols(byte[])
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setChannelIdPrivateKey(PrivateKey)
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setHandshakeTimeout(int)
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setHostname(String)
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setNpnProtocols(byte[])
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setSoWriteTimeout(int)
+method:com.android.org.conscrypt.OpenSSLSocketImpl#setUseSessionTickets(boolean)
+method:com.android.org.conscrypt.TrustedCertificateIndex#findAllByIssuerAndSignature(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateIndex#findByIssuerAndSignature(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateIndex#findBySubjectAndPublicKey(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateIndex#index(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateIndex#TrustedCertificateIndex()
+method:com.android.org.conscrypt.TrustedCertificateStore#aliases()
+method:com.android.org.conscrypt.TrustedCertificateStore#allSystemAliases()
+method:com.android.org.conscrypt.TrustedCertificateStore#containsAlias(String)
+method:com.android.org.conscrypt.TrustedCertificateStore#deleteCertificateEntry(String)
+method:com.android.org.conscrypt.TrustedCertificateStore#findAllIssuers(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#findIssuer(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCertificateAlias(Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCertificateAlias(Certificate,boolean)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCertificateChain(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCertificateFile(File,X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCertificate(String)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCertificate(String,boolean)
+method:com.android.org.conscrypt.TrustedCertificateStore#getCreationDate(String)
+method:com.android.org.conscrypt.TrustedCertificateStore#getTrustAnchor(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#installCertificate(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#isUserAddedCertificate(X509Certificate)
+method:com.android.org.conscrypt.TrustedCertificateStore#isUser(String)
+method:com.android.org.conscrypt.TrustedCertificateStore#setDefaultUserDirectory(File)
+method:com.android.org.conscrypt.TrustedCertificateStore#TrustedCertificateStore()
+method:com.android.org.conscrypt.TrustedCertificateStore#userAliases()
+method:com.android.org.conscrypt.TrustManagerImpl#checkClientTrusted(X509Certificate[],String)
+method:com.android.org.conscrypt.TrustManagerImpl#checkClientTrusted(X509Certificate[],String,Socket)
+method:com.android.org.conscrypt.TrustManagerImpl#checkClientTrusted(X509Certificate[],String,SSLEngine)
+method:com.android.org.conscrypt.TrustManagerImpl#checkServerTrusted(X509Certificate[],String,String)
+method:com.android.org.conscrypt.TrustManagerImpl#getTrustedChainForServer(X509Certificate[],String,Socket)
+method:com.android.org.conscrypt.TrustManagerImpl#getTrustedChainForServer(X509Certificate[],String,SSLEngine)
+method:com.android.org.conscrypt.TrustManagerImpl#handleTrustStorageUpdate()
+method:com.android.org.conscrypt.TrustManagerImpl#TrustManagerImpl(KeyStore)
+method:com.android.org.conscrypt.TrustManagerImpl#TrustManagerImpl(KeyStore,CertPinManager,ConscryptCertStore)
+type:com.android.org.conscrypt.CertPinManager
+type:com.android.org.conscrypt.ClientSessionContext
+type:com.android.org.conscrypt.Conscrypt
+type:com.android.org.conscrypt.ConscryptCertStore
+type:com.android.org.conscrypt.FileClientSessionCache
+type:com.android.org.conscrypt.OpenSSLProvider
+type:com.android.org.conscrypt.OpenSSLSocketImpl
+type:com.android.org.conscrypt.SSLClientSessionCache
+type:com.android.org.conscrypt.TrustedCertificateIndex
+type:com.android.org.conscrypt.TrustedCertificateStore
+type:com.android.org.conscrypt.TrustManagerImpl
diff --git a/srcgen/default-constructors.txt b/srcgen/default-constructors.txt
new file mode 100644
index 0000000..70f8a22
--- /dev/null
+++ b/srcgen/default-constructors.txt
@@ -0,0 +1,3 @@
+com.android.org.conscrypt.IvParameters
+com.android.org.conscrypt.OpenSSLRSAKeyFactory
+com.android.org.conscrypt.OpenSSLRSAKeyPairGenerator
diff --git a/srcgen/generate_android_src.sh b/srcgen/generate_android_src.sh
new file mode 100755
index 0000000..70c6d44
--- /dev/null
+++ b/srcgen/generate_android_src.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Copyright (C) 2018 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.
+
+if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
+    echo "Missing environment variables. Did you run build/envsetup.sh and lunch?" >&2
+    exit 1
+fi
+
+PROJECT_DIR=external/conscrypt
+
+PACKAGE_TRANSFORMATIONS="\
+    org.conscrypt:com.android.org.conscrypt \
+"
+
+MODULE_DIRS="\
+    benchmark-android \
+    benchmark-base \
+    common \
+    openjdk \
+    openjdk-integ-tests \
+    platform \
+    testing \
+"
+DEFAULT_CONSTRUCTORS_FILE=${CONSCRYPT_DIR}/srcgen/default-constructors.txt
+
+SOURCE_DIRS="\
+    src/main/java \
+    src/test/java \
+"
+
+# Repackage the project's source.
+source ${ANDROID_BUILD_TOP}/tools/currysrc/scripts/repackage-common.sh
+
+# Remove some unused test files:
+rm -fr ${REPACKAGED_DIR}/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/ConscryptSuite.java
+rm -fr ${REPACKAGED_DIR}/openjdk-integ-tests/src/test/java/com/android/org/conscrypt/ConscryptJava7Suite.java
+
+echo "Reformatting generated code to adhere to format required by the preupload check"
+cd ${PROJECT_DIR}
+CLANG_STABLE_BIN=${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/clang-stable/bin
+${ANDROID_BUILD_TOP}/tools/repohooks/tools/clang-format.py --fix \
+  --clang-format ${CLANG_STABLE_BIN}/clang-format \
+  --git-clang-format ${CLANG_STABLE_BIN}/git-clang-format \
+  --style file \
+  --working-tree \
+  $(git diff --name-only HEAD | grep -E "^repackaged/")
diff --git a/srcgen/intra-core-api.txt b/srcgen/intra-core-api.txt
new file mode 100644
index 0000000..656535d
--- /dev/null
+++ b/srcgen/intra-core-api.txt
@@ -0,0 +1,207 @@
+method:com.android.org.conscrypt.DESEDESecretKeyFactory#DESEDESecretKeyFactory()
+method:com.android.org.conscrypt.DefaultSSLContextImpl#DefaultSSLContextImpl()
+method:com.android.org.conscrypt.ECParameters#ECParameters()
+method:com.android.org.conscrypt.GCMParameters#GCMParameters()
+method:com.android.org.conscrypt.IvParameters$AES#AES()
+method:com.android.org.conscrypt.IvParameters$ChaCha20#ChaCha20()
+method:com.android.org.conscrypt.IvParameters$DESEDE#DESEDE()
+method:com.android.org.conscrypt.IvParameters#IvParameters()
+method:com.android.org.conscrypt.KeyGeneratorImpl$AES#AES()
+method:com.android.org.conscrypt.KeyGeneratorImpl$ARC4#ARC4()
+method:com.android.org.conscrypt.KeyGeneratorImpl$ChaCha20#ChaCha20()
+method:com.android.org.conscrypt.KeyGeneratorImpl$DESEDE#DESEDE()
+method:com.android.org.conscrypt.KeyGeneratorImpl$HmacMD5#HmacMD5()
+method:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA1#HmacSHA1()
+method:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA224#HmacSHA224()
+method:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA256#HmacSHA256()
+method:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA384#HmacSHA384()
+method:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA512#HmacSHA512()
+method:com.android.org.conscrypt.OAEPParameters#OAEPParameters()
+method:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM#GCM()
+method:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM$AES_128#AES_128()
+method:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM$AES_256#AES_256()
+method:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM_SIV#GCM_SIV()
+method:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM_SIV$AES_128#AES_128()
+method:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM_SIV$AES_256#AES_256()
+method:com.android.org.conscrypt.OpenSSLAeadCipherChaCha20#OpenSSLAeadCipherChaCha20()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CBC$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CBC$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CTR#CTR()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$ECB$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$ECB$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$CBC$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$CBC$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$ECB$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$ECB$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$CBC$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$CBC$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$ECB$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$ECB$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherARC4#OpenSSLEvpCipherARC4()
+method:com.android.org.conscrypt.OpenSSLEvpCipherDESEDE$CBC$NoPadding#NoPadding()
+method:com.android.org.conscrypt.OpenSSLEvpCipherDESEDE$CBC$PKCS5Padding#PKCS5Padding()
+method:com.android.org.conscrypt.OpenSSLCipherChaCha20#OpenSSLCipherChaCha20()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA1#SHA1()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA224#SHA224()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA256#SHA256()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA384#SHA384()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA512#SHA512()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$PKCS1#PKCS1()
+method:com.android.org.conscrypt.OpenSSLCipherRSA$Raw#Raw()
+method:com.android.org.conscrypt.OpenSSLContextImpl$TLSv1#TLSv1()
+method:com.android.org.conscrypt.OpenSSLContextImpl$TLSv11#TLSv11()
+method:com.android.org.conscrypt.OpenSSLContextImpl$TLSv12#TLSv12()
+method:com.android.org.conscrypt.OpenSSLContextImpl$TLSv13#TLSv13()
+method:com.android.org.conscrypt.OpenSSLECDHKeyAgreement#OpenSSLECDHKeyAgreement()
+method:com.android.org.conscrypt.OpenSSLECKeyFactory#OpenSSLECKeyFactory()
+method:com.android.org.conscrypt.OpenSSLECKeyPairGenerator#OpenSSLECKeyPairGenerator()
+method:com.android.org.conscrypt.OpenSSLMac$HmacMD5#HmacMD5()
+method:com.android.org.conscrypt.OpenSSLMac$HmacSHA1#HmacSHA1()
+method:com.android.org.conscrypt.OpenSSLMac$HmacSHA224#HmacSHA224()
+method:com.android.org.conscrypt.OpenSSLMac$HmacSHA256#HmacSHA256()
+method:com.android.org.conscrypt.OpenSSLMac$HmacSHA384#HmacSHA384()
+method:com.android.org.conscrypt.OpenSSLMac$HmacSHA512#HmacSHA512()
+method:com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5#MD5()
+method:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1#SHA1()
+method:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA224#SHA224()
+method:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256#SHA256()
+method:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA384#SHA384()
+method:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA512#SHA512()
+method:com.android.org.conscrypt.OpenSSLRSAKeyFactory#OpenSSLRSAKeyFactory()
+method:com.android.org.conscrypt.OpenSSLRSAKeyPairGenerator#OpenSSLRSAKeyPairGenerator()
+method:com.android.org.conscrypt.OpenSSLRandom#OpenSSLRandom()
+method:com.android.org.conscrypt.OpenSSLSignature$MD5RSA#MD5RSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA1ECDSA#SHA1ECDSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA1RSA#SHA1RSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA1RSAPSS#SHA1RSAPSS()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA224ECDSA#SHA224ECDSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA224RSA#SHA224RSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA224RSAPSS#SHA224RSAPSS()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA256ECDSA#SHA256ECDSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA256RSA#SHA256RSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA256RSAPSS#SHA256RSAPSS()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA384ECDSA#SHA384ECDSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA384RSA#SHA384RSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA384RSAPSS#SHA384RSAPSS()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA512ECDSA#SHA512ECDSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA512RSA#SHA512RSA()
+method:com.android.org.conscrypt.OpenSSLSignature$SHA512RSAPSS#SHA512RSAPSS()
+method:com.android.org.conscrypt.OpenSSLSignatureRawECDSA#OpenSSLSignatureRawECDSA()
+method:com.android.org.conscrypt.OpenSSLSignatureRawRSA#OpenSSLSignatureRawRSA()
+method:com.android.org.conscrypt.OpenSSLX509CertificateFactory#OpenSSLX509CertificateFactory()
+method:com.android.org.conscrypt.PSSParameters#PSSParameters()
+type:com.android.org.conscrypt.DESEDESecretKeyFactory
+type:com.android.org.conscrypt.DefaultSSLContextImpl
+type:com.android.org.conscrypt.ECParameters
+type:com.android.org.conscrypt.GCMParameters
+type:com.android.org.conscrypt.IvParameters
+type:com.android.org.conscrypt.IvParameters$AES
+type:com.android.org.conscrypt.IvParameters$ChaCha20
+type:com.android.org.conscrypt.IvParameters$DESEDE
+type:com.android.org.conscrypt.KeyGeneratorImpl
+type:com.android.org.conscrypt.KeyGeneratorImpl$AES
+type:com.android.org.conscrypt.KeyGeneratorImpl$ARC4
+type:com.android.org.conscrypt.KeyGeneratorImpl$ChaCha20
+type:com.android.org.conscrypt.KeyGeneratorImpl$DESEDE
+type:com.android.org.conscrypt.KeyGeneratorImpl$HmacMD5
+type:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA1
+type:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA224
+type:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA256
+type:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA384
+type:com.android.org.conscrypt.KeyGeneratorImpl$HmacSHA512
+type:com.android.org.conscrypt.OAEPParameters
+type:com.android.org.conscrypt.OpenSSLCipher
+type:com.android.org.conscrypt.OpenSSLAeadCipher
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM$AES_128
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM$AES_256
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM_SIV
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM_SIV$AES_128
+type:com.android.org.conscrypt.OpenSSLAeadCipherAES$GCM_SIV$AES_256
+type:com.android.org.conscrypt.OpenSSLAeadCipherChaCha20
+type:com.android.org.conscrypt.OpenSSLEvpCipher
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CBC
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CBC$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CBC$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$CTR
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$ECB
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$ECB$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES$ECB$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$CBC
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$CBC$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$CBC$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$ECB
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$ECB$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_128$ECB$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$CBC
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$CBC$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$CBC$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$ECB
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$ECB$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherAES$AES_256$ECB$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLEvpCipherARC4
+type:com.android.org.conscrypt.OpenSSLEvpCipherDESEDE
+type:com.android.org.conscrypt.OpenSSLEvpCipherDESEDE$CBC
+type:com.android.org.conscrypt.OpenSSLEvpCipherDESEDE$CBC$NoPadding
+type:com.android.org.conscrypt.OpenSSLEvpCipherDESEDE$CBC$PKCS5Padding
+type:com.android.org.conscrypt.OpenSSLCipherChaCha20
+type:com.android.org.conscrypt.OpenSSLCipherRSA
+type:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP
+type:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA1
+type:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA224
+type:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA256
+type:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA384
+type:com.android.org.conscrypt.OpenSSLCipherRSA$OAEP$SHA512
+type:com.android.org.conscrypt.OpenSSLCipherRSA$PKCS1
+type:com.android.org.conscrypt.OpenSSLCipherRSA$Raw
+type:com.android.org.conscrypt.OpenSSLContextImpl
+type:com.android.org.conscrypt.OpenSSLContextImpl$TLSv1
+type:com.android.org.conscrypt.OpenSSLContextImpl$TLSv11
+type:com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
+type:com.android.org.conscrypt.OpenSSLContextImpl$TLSv13
+type:com.android.org.conscrypt.OpenSSLECDHKeyAgreement
+type:com.android.org.conscrypt.OpenSSLECKeyFactory
+type:com.android.org.conscrypt.OpenSSLECKeyPairGenerator
+type:com.android.org.conscrypt.OpenSSLMac
+type:com.android.org.conscrypt.OpenSSLMac$HmacMD5
+type:com.android.org.conscrypt.OpenSSLMac$HmacSHA1
+type:com.android.org.conscrypt.OpenSSLMac$HmacSHA224
+type:com.android.org.conscrypt.OpenSSLMac$HmacSHA256
+type:com.android.org.conscrypt.OpenSSLMac$HmacSHA384
+type:com.android.org.conscrypt.OpenSSLMac$HmacSHA512
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA224
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA384
+type:com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA512
+type:com.android.org.conscrypt.OpenSSLRSAKeyFactory
+type:com.android.org.conscrypt.OpenSSLRSAKeyPairGenerator
+type:com.android.org.conscrypt.OpenSSLRandom
+type:com.android.org.conscrypt.OpenSSLSignature
+type:com.android.org.conscrypt.OpenSSLSignature$MD5RSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA1ECDSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA1RSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA1RSAPSS
+type:com.android.org.conscrypt.OpenSSLSignature$SHA224ECDSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA224RSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA224RSAPSS
+type:com.android.org.conscrypt.OpenSSLSignature$SHA256ECDSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA256RSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA256RSAPSS
+type:com.android.org.conscrypt.OpenSSLSignature$SHA384ECDSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA384RSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA384RSAPSS
+type:com.android.org.conscrypt.OpenSSLSignature$SHA512ECDSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA512RSA
+type:com.android.org.conscrypt.OpenSSLSignature$SHA512RSAPSS
+type:com.android.org.conscrypt.OpenSSLSignatureRawECDSA
+type:com.android.org.conscrypt.OpenSSLSignatureRawRSA
+type:com.android.org.conscrypt.OpenSSLX509CertificateFactory
+type:com.android.org.conscrypt.PSSParameters
diff --git a/srcgen/unsupported-app-usage.json b/srcgen/unsupported-app-usage.json
new file mode 100644
index 0000000..20d30f0
--- /dev/null
+++ b/srcgen/unsupported-app-usage.json
@@ -0,0 +1,334 @@
+// See com.google.currysrc.aosp.Annotations.addUnsupportedAppUsage(Path) method for details on the
+// syntax.
+[
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getAlpnSelectedProtocol()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getApplicationProtocols()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getChannelId()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getHostname()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getHostnameOrIP()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getNpnSelectedProtocol()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#getSoWriteTimeout()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setAlpnProtocols(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setAlpnProtocols(String[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setApplicationProtocols(String[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setChannelIdEnabled(boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setChannelIdPrivateKey(PrivateKey)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setHandshakeTimeout(int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setHostname(String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setNpnProtocols(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setSoWriteTimeout(int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.AbstractConscryptSocket#setUseSessionTickets(boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.ClientSessionContext#getSession(String,int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.ClientSessionContext#setPersistentCache(SSLClientSessionCache)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.ConscryptFileDescriptorSocket#setHostname(String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.ConscryptFileDescriptorSocket#setUseSessionTickets(boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.FileClientSessionCache$Impl#getSessionData(String,int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.FileClientSessionCache#usingDirectory(File)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#ASN1_seq_pack_X509(long[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#ASN1_seq_unpack_X509_bio(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#ASN1_TIME_to_Calendar(long,Calendar)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#BIO_free_all(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#create_BIO_InputStream(OpenSSLBIOInputStream,boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#create_BIO_OutputStream(OutputStream)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#d2i_PKCS7_bio(long,int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#d2i_SSL_SESSION(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#d2i_X509(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#d2i_X509_bio(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#d2i_X509_CRL_bio(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EC_GROUP_clear_free(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EC_GROUP_new_by_curve_name(String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EC_POINT_clear_free(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_CIPHER_CTX_new()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_CIPHER_iv_length(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_get_cipherbyname(String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_get_digestbyname(String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_MD_CTX_create()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_MD_CTX_destroy(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_MD_size(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_PKEY_free(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#EVP_PKEY_new_RSA(byte[],byte[],byte[],byte[],byte[],byte[],byte[],byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#get_X509_REVOKED_ext_oids(long,int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#get_X509_REVOKED_revocationDate(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#i2d_PKCS7(long[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#i2d_SSL_SESSION(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#i2d_X509_REVOKED(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#PEM_read_bio_PKCS7(long,int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#PEM_read_bio_X509(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#PEM_read_bio_X509_CRL(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#RAND_bytes(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#RSA_generate_key_ex(int,byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#SSL_CTX_new()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#SSL_SESSION_cipher(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#SSL_SESSION_free(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#SSL_SESSION_get_time(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#SSL_SESSION_get_version(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#SSL_SESSION_session_id(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#X509_REVOKED_dup(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#X509_REVOKED_get_ext(long,String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#X509_REVOKED_get_ext_oid(long,String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#X509_REVOKED_get_serialNumber(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#X509_REVOKED_print(long,long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.NativeCrypto#X509_supported_extension(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLBIOInputStream#OpenSSLBIOInputStream(InputStream,boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLBIOInputStream#getBioContext()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLBIOInputStream#release()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLContextImpl$TLSv12#TLSv12()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLContextImpl#OpenSSLContextImpl()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLContextImpl#getPreferred()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLKey#OpenSSLKey(long)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLKey#fromPrivateKey(PrivateKey)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLKey#getNativeRef()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLKey#getPublicKey()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLKeyHolder#getOpenSSLKey()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLProvider#OpenSSLProvider()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLRandom#OpenSSLRandom()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketFactoryImpl#OpenSSLSocketFactoryImpl()"
+  },
+  {
+    "@location": "field:com.android.org.conscrypt.OpenSSLSocketFactoryImpl#sslParameters"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#getAlpnSelectedProtocol()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#getChannelId()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#getHostname()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#getHostnameOrIP()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#getNpnSelectedProtocol()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#getSoWriteTimeout()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setAlpnProtocols(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setAlpnProtocols(String[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setChannelIdEnabled(boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setChannelIdPrivateKey(PrivateKey)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setHandshakeTimeout(int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setHostname(String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setNpnProtocols(byte[])"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setSoWriteTimeout(int)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLSocketImpl#setUseSessionTickets(boolean)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.OpenSSLX509Certificate#fromX509PemInputStream(InputStream)"
+  },
+  {
+    "@location": "field:com.android.org.conscrypt.OpenSSLX509Certificate#mContext"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.SSLParametersImpl#getDefault()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.SSLParametersImpl#getDefaultX509TrustManager()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.SSLParametersImpl#getX509TrustManager()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.SSLParametersImpl#setEnabledProtocols(String[])"
+  },
+  {
+    "@location": "field:com.android.org.conscrypt.SSLParametersImpl#x509TrustManager"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.TrustedCertificateStore#TrustedCertificateStore()"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.TrustedCertificateStore#getCertificateChain(X509Certificate)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.TrustManagerImpl#TrustManagerImpl(KeyStore)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.TrustManagerImpl#checkServerTrusted(X509Certificate[],String,String)"
+  },
+  {
+    "@location": "method:com.android.org.conscrypt.X509PublicKey#X509PublicKey(String,byte[])"
+  }
+]
