Merge "Unit tests for all registered ECDH KeyAgreement instances."
diff --git a/luni/src/main/java/java/security/Security.java b/luni/src/main/java/java/security/Security.java
index b5bd02a..7294f69 100644
--- a/luni/src/main/java/java/security/Security.java
+++ b/luni/src/main/java/java/security/Security.java
@@ -72,8 +72,8 @@
 
     // Register default providers
     private static void registerDefaultProviders() {
-        secprops.put("security.provider.1", "org.apache.harmony.xnet.provider.jsse.OpenSSLProvider");
-        secprops.put("security.provider.2", "org.apache.harmony.security.provider.cert.DRLCertFactory");
+        secprops.put("security.provider.1", "org.apache.harmony.security.provider.cert.DRLCertFactory");
+        secprops.put("security.provider.2", "org.apache.harmony.xnet.provider.jsse.OpenSSLProvider");
         secprops.put("security.provider.3", "org.bouncycastle.jce.provider.BouncyCastleProvider");
         secprops.put("security.provider.4", "org.apache.harmony.security.provider.crypto.CryptoProvider");
         secprops.put("security.provider.5", "org.apache.harmony.xnet.provider.jsse.JSSEProvider");
diff --git a/luni/src/main/java/java/security/security.properties b/luni/src/main/java/java/security/security.properties
index b124271..a6e1be0 100644
--- a/luni/src/main/java/java/security/security.properties
+++ b/luni/src/main/java/java/security/security.properties
@@ -18,10 +18,10 @@
 # Providers
 # See also: J2SE doc. "How to Implement a Provider for the JavaTM Cryptography Architecture"
 #
-# Android's provider of OpenSSL backed implementations
-security.provider.1=org.apache.harmony.xnet.provider.jsse.OpenSSLProvider
-# Favor Harmony's CertificateFactory.X509 over BouncyCastle's
-security.provider.2=org.apache.harmony.security.provider.cert.DRLCertFactory
+# Favor Harmony's CertificateFactory.X509 over all others
+security.provider.1=org.apache.harmony.security.provider.cert.DRLCertFactory
+# Android's provider of OpenSSL-backed implementations
+security.provider.2=org.apache.harmony.xnet.provider.jsse.OpenSSLProvider
 # Android's stripped down BouncyCastle provider
 security.provider.3=com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
 # Remaining Harmony providers
diff --git a/luni/src/main/java/java/util/regex/Matcher.java b/luni/src/main/java/java/util/regex/Matcher.java
index 162fe53..320e14c 100644
--- a/luni/src/main/java/java/util/regex/Matcher.java
+++ b/luni/src/main/java/java/util/regex/Matcher.java
@@ -31,7 +31,7 @@
      * The address of the native peer.
      * Uses of this must be manually synchronized to avoid native crashes.
      */
-    private int address;
+    private long address;
 
     /**
      * Holds the input text.
@@ -656,16 +656,16 @@
         }
     }
 
-    private static native void closeImpl(int addr);
-    private static native boolean findImpl(int addr, String s, int startIndex, int[] offsets);
-    private static native boolean findNextImpl(int addr, String s, int[] offsets);
-    private static native int groupCountImpl(int addr);
-    private static native boolean hitEndImpl(int addr);
-    private static native boolean lookingAtImpl(int addr, String s, int[] offsets);
-    private static native boolean matchesImpl(int addr, String s, int[] offsets);
-    private static native int openImpl(int patternAddr);
-    private static native boolean requireEndImpl(int addr);
-    private static native void setInputImpl(int addr, String s, int start, int end);
-    private static native void useAnchoringBoundsImpl(int addr, boolean value);
-    private static native void useTransparentBoundsImpl(int addr, boolean value);
+    private static native void closeImpl(long addr);
+    private static native boolean findImpl(long addr, String s, int startIndex, int[] offsets);
+    private static native boolean findNextImpl(long addr, String s, int[] offsets);
+    private static native int groupCountImpl(long addr);
+    private static native boolean hitEndImpl(long addr);
+    private static native boolean lookingAtImpl(long addr, String s, int[] offsets);
+    private static native boolean matchesImpl(long addr, String s, int[] offsets);
+    private static native long openImpl(long patternAddr);
+    private static native boolean requireEndImpl(long addr);
+    private static native void setInputImpl(long addr, String s, int start, int end);
+    private static native void useAnchoringBoundsImpl(long addr, boolean value);
+    private static native void useTransparentBoundsImpl(long addr, boolean value);
 }
diff --git a/luni/src/main/java/java/util/regex/Pattern.java b/luni/src/main/java/java/util/regex/Pattern.java
index cbd5965..44b749e 100644
--- a/luni/src/main/java/java/util/regex/Pattern.java
+++ b/luni/src/main/java/java/util/regex/Pattern.java
@@ -285,7 +285,7 @@
     private final String pattern;
     private final int flags;
 
-    transient int address;
+    transient long address;
 
     /**
      * Returns a {@link Matcher} for this pattern applied to the given {@code input}.
@@ -452,6 +452,6 @@
         compile();
     }
 
-    private static native void closeImpl(int addr);
-    private static native int compileImpl(String regex, int flags);
+    private static native void closeImpl(long addr);
+    private static native long compileImpl(String regex, int flags);
 }
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
index 2496a93..971e292 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
@@ -41,7 +41,7 @@
     volatile int maximumSize;
     volatile int timeout;
 
-    final int sslCtxNativePointer = NativeCrypto.SSL_CTX_new();
+    final long sslCtxNativePointer = NativeCrypto.SSL_CTX_new();
 
     /** Identifies OpenSSL sessions. */
     static final int OPEN_SSL = 1;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
index 384e91f..ed712df 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
@@ -18,6 +18,7 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.net.SocketTimeoutException;
 import java.nio.ByteOrder;
 import java.security.MessageDigest;
@@ -54,94 +55,94 @@
     // --- ENGINE functions ----------------------------------------------------
     public static native void ENGINE_load_dynamic();
 
-    public static native int ENGINE_by_id(String id);
+    public static native long ENGINE_by_id(String id);
 
-    public static native int ENGINE_add(int e);
+    public static native int ENGINE_add(long e);
 
-    public static native int ENGINE_init(int e);
+    public static native int ENGINE_init(long e);
 
-    public static native int ENGINE_finish(int e);
+    public static native int ENGINE_finish(long e);
 
-    public static native int ENGINE_free(int e);
+    public static native int ENGINE_free(long e);
 
-    public static native int ENGINE_load_private_key(int e, String key_id);
+    public static native long ENGINE_load_private_key(long e, String key_id);
 
-    public static native String ENGINE_get_id(int engineRef);
+    public static native String ENGINE_get_id(long engineRef);
 
-    public static native int ENGINE_ctrl_cmd_string(int engineRef, String cmd, String arg,
+    public static native int ENGINE_ctrl_cmd_string(long engineRef, String cmd, String arg,
             int cmd_optional);
 
     // --- DSA/RSA public/private key handling functions -----------------------
 
-    public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
-                                              byte[] pub_key, byte[] priv_key);
+    public static native long EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
+                                               byte[] pub_key, byte[] priv_key);
 
-    public static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
+    public static native long EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
             byte[] dmp1, byte[] dmq1, byte[] iqmp);
 
-    public static native int EVP_PKEY_new_mac_key(int type, byte[] key);
+    public static native long EVP_PKEY_new_mac_key(int type, byte[] key);
 
-    public static native int EVP_PKEY_size(int pkey);
+    public static native int EVP_PKEY_size(long pkey);
 
-    public static native int EVP_PKEY_type(int pkey);
+    public static native int EVP_PKEY_type(long pkey);
 
-    public static native String EVP_PKEY_print_public(int pkeyRef);
+    public static native String EVP_PKEY_print_public(long pkeyRef);
 
-    public static native String EVP_PKEY_print_private(int pkeyRef);
+    public static native String EVP_PKEY_print_private(long pkeyRef);
 
-    public static native void EVP_PKEY_free(int pkey);
+    public static native void EVP_PKEY_free(long pkey);
 
-    public static native int EVP_PKEY_cmp(int pkey1, int pkey2);
+    public static native int EVP_PKEY_cmp(long pkey1, long pkey2);
 
-    public static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int pkey);
+    public static native byte[] i2d_PKCS8_PRIV_KEY_INFO(long pkey);
 
-    public static native int d2i_PKCS8_PRIV_KEY_INFO(byte[] data);
+    public static native long d2i_PKCS8_PRIV_KEY_INFO(byte[] data);
 
-    public static native byte[] i2d_PUBKEY(int pkey);
+    public static native byte[] i2d_PUBKEY(long pkey);
 
-    public static native int d2i_PUBKEY(byte[] data);
+    public static native long d2i_PUBKEY(byte[] data);
 
-    public static native int RSA_generate_key_ex(int modulusBits, byte[] publicExponent);
+    public static native long RSA_generate_key_ex(int modulusBits, byte[] publicExponent);
 
-    public static native int RSA_size(int pkey);
+    public static native int RSA_size(long pkey);
 
-    public static native int RSA_private_encrypt(int flen, byte[] from, byte[] to, int pkey,
+    public static native int RSA_private_encrypt(int flen, byte[] from, byte[] to, long pkey,
             int padding);
 
-    public static native int RSA_public_decrypt(int flen, byte[] from, byte[] to, int pkey,
+    public static native int RSA_public_decrypt(int flen, byte[] from, byte[] to, long pkey,
             int padding) throws BadPaddingException, SignatureException;
 
-    public static native int RSA_public_encrypt(int flen, byte[] from, byte[] to, int pkey,
+    public static native int RSA_public_encrypt(int flen, byte[] from, byte[] to, long pkey,
             int padding);
 
-    public static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, int pkey,
+    public static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, long pkey,
             int padding) throws BadPaddingException, SignatureException;
 
     /**
      * @return array of {n, e}
      */
-    public static native byte[][] get_RSA_public_params(int rsa);
+    public static native byte[][] get_RSA_public_params(long rsa);
 
     /**
      * @return array of {n, e, d, p, q, dmp1, dmq1, iqmp}
      */
-    public static native byte[][] get_RSA_private_params(int rsa);
+    public static native byte[][] get_RSA_private_params(long rsa);
 
-    public static native int DSA_generate_key(int primeBits, byte[] seed, byte[] g, byte[] p,
+    public static native long DSA_generate_key(int primeBits, byte[] seed, byte[] g, byte[] p,
             byte[] q);
 
     /**
      * @return array of {g, p, q, y(pub), x(priv)}
      */
-    public static native byte[][] get_DSA_params(int dsa);
+    public static native byte[][] get_DSA_params(long dsa);
 
-    public static native byte[] i2d_RSAPublicKey(int rsa);
+    public static native byte[] i2d_RSAPublicKey(long rsa);
 
-    public static native byte[] i2d_RSAPrivateKey(int rsa);
+    public static native byte[] i2d_RSAPrivateKey(long rsa);
 
-    public static native byte[] i2d_DSAPublicKey(int dsa);
+    public static native byte[] i2d_DSAPublicKey(long dsa);
 
-    public static native byte[] i2d_DSAPrivateKey(int dsa);
+    public static native byte[] i2d_DSAPrivateKey(long dsa);
 
     // --- EC functions --------------------------
 
@@ -175,133 +176,133 @@
      */
     public static final int POINT_CONVERSION_HYBRID = 4;
 
-    public static native int EVP_PKEY_new_EC_KEY(int groupRef, int pubkeyRef, byte[] privkey);
+    public static native long EVP_PKEY_new_EC_KEY(long groupRef, long pubkeyRef, byte[] privkey);
 
-    public static native int EC_GROUP_new_by_curve_name(String curveName);
+    public static native long EC_GROUP_new_by_curve_name(String curveName);
 
-    public static native int EC_GROUP_new_curve(int type, byte[] p, byte[] a, byte[] b);
+    public static native long EC_GROUP_new_curve(int type, byte[] p, byte[] a, byte[] b);
 
-    public static native int EC_GROUP_dup(int groupRef);
+    public static native long EC_GROUP_dup(long groupRef);
 
-    public static native void EC_GROUP_set_asn1_flag(int groupRef, int flag);
+    public static native void EC_GROUP_set_asn1_flag(long groupRef, int flag);
 
-    public static native void EC_GROUP_set_point_conversion_form(int groupRef, int form);
+    public static native void EC_GROUP_set_point_conversion_form(long groupRef, int form);
 
-    public static native String EC_GROUP_get_curve_name(int groupRef);
+    public static native String EC_GROUP_get_curve_name(long groupRef);
 
-    public static native byte[][] EC_GROUP_get_curve(int groupRef);
+    public static native byte[][] EC_GROUP_get_curve(long groupRef);
 
-    public static native void EC_GROUP_clear_free(int ctx);
+    public static native void EC_GROUP_clear_free(long ctx);
 
-    public static native boolean EC_GROUP_cmp(int ctx1, int ctx2);
+    public static native boolean EC_GROUP_cmp(long ctx1, long ctx2);
 
-    public static native void EC_GROUP_set_generator(int groupCtx, int pointCtx, byte[] n, byte[] h);
+    public static native void EC_GROUP_set_generator(long groupCtx, long pointCtx, byte[] n, byte[] h);
 
-    public static native int EC_GROUP_get_generator(int groupCtx);
+    public static native long EC_GROUP_get_generator(long groupCtx);
 
-    public static native int get_EC_GROUP_type(int groupCtx);
+    public static native int get_EC_GROUP_type(long groupCtx);
 
-    public static native byte[] EC_GROUP_get_order(int groupCtx);
+    public static native byte[] EC_GROUP_get_order(long groupCtx);
 
-    public static native byte[] EC_GROUP_get_cofactor(int groupCtx);
+    public static native byte[] EC_GROUP_get_cofactor(long groupCtx);
 
-    public static native int EC_POINT_new(int groupRef);
+    public static native long EC_POINT_new(long groupRef);
 
-    public static native void EC_POINT_clear_free(int pointRef);
+    public static native void EC_POINT_clear_free(long pointRef);
 
-    public static native boolean EC_POINT_cmp(int groupRef, int pointRef1, int pointRef2);
+    public static native boolean EC_POINT_cmp(long groupRef, long pointRef1, long pointRef2);
 
-    public static native byte[][] EC_POINT_get_affine_coordinates(int groupCtx, int pointCtx);
+    public static native byte[][] EC_POINT_get_affine_coordinates(long groupCtx, long pointCtx);
 
-    public static native void EC_POINT_set_affine_coordinates(int groupCtx, int pointCtx, byte[] x,
+    public static native void EC_POINT_set_affine_coordinates(long groupCtx, long pointCtx, byte[] x,
             byte[] y);
 
-    public static native int EC_KEY_generate_key(int groupRef);
+    public static native long EC_KEY_generate_key(long groupRef);
 
-    public static native int EC_KEY_get0_group(int pkeyRef);
+    public static native long EC_KEY_get0_group(long pkeyRef);
 
-    public static native byte[] EC_KEY_get_private_key(int keyRef);
+    public static native byte[] EC_KEY_get_private_key(long keyRef);
 
-    public static native int EC_KEY_get_public_key(int keyRef);
+    public static native long EC_KEY_get_public_key(long keyRef);
 
     // --- Message digest functions --------------
 
-    public static native int EVP_get_digestbyname(String name);
+    public static native long EVP_get_digestbyname(String name);
 
-    public static native int EVP_MD_size(int evp_md);
+    public static native int EVP_MD_size(long evp_md);
 
-    public static native int EVP_MD_block_size(int evp_md);
+    public static native int EVP_MD_block_size(long evp_md);
 
     // --- Message digest context functions --------------
 
-    public static native int EVP_MD_CTX_create();
+    public static native long EVP_MD_CTX_create();
 
-    public static native void EVP_MD_CTX_init(int ctx);
+    public static native void EVP_MD_CTX_init(long ctx);
 
-    public static native void EVP_MD_CTX_destroy(int ctx);
+    public static native void EVP_MD_CTX_destroy(long ctx);
 
-    public static native int EVP_MD_CTX_copy(int ctx);
+    public static native long EVP_MD_CTX_copy(long ctx);
 
     // --- Digest handling functions -------------------------------------------
 
-    public static native int EVP_DigestInit(int evp_md);
+    public static native long EVP_DigestInit(long evp_md);
 
-    public static native void EVP_DigestUpdate(int ctx, byte[] buffer, int offset, int length);
+    public static native void EVP_DigestUpdate(long ctx, byte[] buffer, int offset, int length);
 
-    public static native int EVP_DigestFinal(int ctx, byte[] hash, int offset);
+    public static native int EVP_DigestFinal(long ctx, byte[] hash, int offset);
 
     // --- MAC handling functions ----------------------------------------------
 
-    public static native void EVP_DigestSignInit(int evp_md_ctx, int evp_md, int evp_pkey);
+    public static native void EVP_DigestSignInit(long evp_md_ctx, long evp_md, long evp_pkey);
 
-    public static native void EVP_DigestSignUpdate(int evp_md_ctx, byte[] in);
+    public static native void EVP_DigestSignUpdate(long evp_md_ctx, byte[] in);
 
-    public static native byte[] EVP_DigestSignFinal(int evp_md_ctx);
+    public static native byte[] EVP_DigestSignFinal(long evp_md_ctx);
 
     // --- Signature handling functions ----------------------------------------
 
-    public static native int EVP_SignInit(String algorithm);
+    public static native long EVP_SignInit(String algorithm);
 
-    public static native void EVP_SignUpdate(int ctx, byte[] buffer,
+    public static native void EVP_SignUpdate(long ctx, byte[] buffer,
                                                int offset, int length);
 
-    public static native int EVP_SignFinal(int ctx, byte[] signature, int offset, int key);
+    public static native int EVP_SignFinal(long ctx, byte[] signature, int offset, long key);
 
-    public static native int EVP_VerifyInit(String algorithm);
+    public static native long EVP_VerifyInit(String algorithm);
 
-    public static native void EVP_VerifyUpdate(int ctx, byte[] buffer,
+    public static native void EVP_VerifyUpdate(long ctx, byte[] buffer,
                                                int offset, int length);
 
-    public static native int EVP_VerifyFinal(int ctx, byte[] signature,
-                                             int offset, int length, int key);
+    public static native int EVP_VerifyFinal(long ctx, byte[] signature,
+                                             int offset, int length, long key);
 
 
     // --- Block ciphers -------------------------------------------------------
 
-    public static native int EVP_get_cipherbyname(String string);
+    public static native long EVP_get_cipherbyname(String string);
 
-    public static native void EVP_CipherInit_ex(int ctx, int evpCipher, byte[] key, byte[] iv,
+    public static native void EVP_CipherInit_ex(long ctx, long evpCipher, byte[] key, byte[] iv,
             boolean encrypting);
 
-    public static native int EVP_CipherUpdate(int ctx, byte[] out, int outOffset, byte[] in,
+    public static native int EVP_CipherUpdate(long ctx, byte[] out, int outOffset, byte[] in,
             int inOffset, int inLength);
 
-    public static native int EVP_CipherFinal_ex(int ctx, byte[] out, int outOffset)
+    public static native int EVP_CipherFinal_ex(long ctx, byte[] out, int outOffset)
             throws BadPaddingException, IllegalBlockSizeException;
 
-    public static native int EVP_CIPHER_iv_length(int evpCipher);
+    public static native int EVP_CIPHER_iv_length(long evpCipher);
 
-    public static native int EVP_CIPHER_CTX_new();
+    public static native long EVP_CIPHER_CTX_new();
 
-    public static native int EVP_CIPHER_CTX_block_size(int ctx);
+    public static native int EVP_CIPHER_CTX_block_size(long ctx);
 
-    public static native int get_EVP_CIPHER_CTX_buf_len(int ctx);
+    public static native int get_EVP_CIPHER_CTX_buf_len(long ctx);
 
-    public static native void EVP_CIPHER_CTX_set_padding(int ctx, boolean enablePadding);
+    public static native void EVP_CIPHER_CTX_set_padding(long ctx, boolean enablePadding);
 
-    public static native void EVP_CIPHER_CTX_set_key_length(int ctx, int keyBitSize);
+    public static native void EVP_CIPHER_CTX_set_key_length(long ctx, int keyBitSize);
 
-    public static native void EVP_CIPHER_CTX_cleanup(int ctx);
+    public static native void EVP_CIPHER_CTX_cleanup(long ctx);
 
     // --- RAND seeding --------------------------------------------------------
 
@@ -337,6 +338,18 @@
             throw new AssertionError(e);
         }
     }
+    // --- BIO stream creation -------------------------------------------------
+
+    public static native long create_BIO_InputStream(OpenSSLBIOInputStream is);
+
+    public static native long create_BIO_OutputStream(OutputStream os);
+
+    public static native int BIO_read(long bioRef, byte[] buffer);
+
+    public static native void BIO_write(long bioRef, byte[] buffer, int offset, int length)
+            throws IOException;
+
+    public static native void BIO_free(long bioRef);
 
     // --- SSL handling --------------------------------------------------------
 
@@ -499,7 +512,7 @@
     public static final long SSL_OP_NO_TLSv1_1                             = 0x10000000L;
     public static final long SSL_OP_NO_TLSv1_2                             = 0x08000000L;
 
-    public static native int SSL_CTX_new();
+    public static native long SSL_CTX_new();
 
     public static String[] getDefaultCipherSuites() {
         return new String[] {
@@ -545,23 +558,23 @@
         return SUPPORTED_CIPHER_SUITES.clone();
     }
 
-    public static native void SSL_CTX_free(int ssl_ctx);
+    public static native void SSL_CTX_free(long ssl_ctx);
 
-    public static native void SSL_CTX_set_session_id_context(int ssl_ctx, byte[] sid_ctx);
+    public static native void SSL_CTX_set_session_id_context(long ssl_ctx, byte[] sid_ctx);
 
-    public static native int SSL_new(int ssl_ctx) throws SSLException;
+    public static native long SSL_new(long ssl_ctx) throws SSLException;
 
-    public static native void SSL_enable_tls_channel_id(int ssl) throws SSLException;
+    public static native void SSL_enable_tls_channel_id(long ssl) throws SSLException;
 
-    public static native byte[] SSL_get_tls_channel_id(int ssl) throws SSLException;
+    public static native byte[] SSL_get_tls_channel_id(long ssl) throws SSLException;
 
-    public static native void SSL_use_OpenSSL_PrivateKey_for_tls_channel_id(int ssl, int pkey)
+    public static native void SSL_use_OpenSSL_PrivateKey_for_tls_channel_id(long ssl, long pkey)
             throws SSLException;
 
     public static native void SSL_use_PKCS8_PrivateKey_for_tls_channel_id(
-            int ssl, byte[] pkcs8EncodedPrivateKey) throws SSLException;
+            long ssl, byte[] pkcs8EncodedPrivateKey) throws SSLException;
 
-    public static void SSL_set1_tls_channel_id(int ssl, ECPrivateKey privateKey)
+    public static void SSL_set1_tls_channel_id(long ssl, ECPrivateKey privateKey)
             throws SSLException {
         if (privateKey == null) {
             throw new NullPointerException("privateKey == null");
@@ -586,13 +599,13 @@
         return certificateBytes;
     }
 
-    public static native void SSL_use_certificate(int ssl, byte[][] asn1DerEncodedCertificateChain);
+    public static native void SSL_use_certificate(long ssl, byte[][] asn1DerEncodedCertificateChain);
 
-    public static native void SSL_use_OpenSSL_PrivateKey(int ssl, int pkey);
+    public static native void SSL_use_OpenSSL_PrivateKey(long ssl, long pkey);
 
-    public static native void SSL_use_PrivateKey(int ssl, byte[] pkcs8EncodedPrivateKey);
+    public static native void SSL_use_PrivateKey(long ssl, byte[] pkcs8EncodedPrivateKey);
 
-    public static native void SSL_check_private_key(int ssl) throws SSLException;
+    public static native void SSL_check_private_key(long ssl) throws SSLException;
 
     public static byte[][] encodeIssuerX509Principals(X509Certificate[] certificates)
             throws CertificateEncodingException {
@@ -603,19 +616,19 @@
         return principalBytes;
     }
 
-    public static native void SSL_set_client_CA_list(int ssl, byte[][] asn1DerEncodedX500Principals);
+    public static native void SSL_set_client_CA_list(long ssl, byte[][] asn1DerEncodedX500Principals);
 
-    public static native long SSL_get_mode(int ssl);
+    public static native long SSL_get_mode(long ssl);
 
-    public static native long SSL_set_mode(int ssl, long mode);
+    public static native long SSL_set_mode(long ssl, long mode);
 
-    public static native long SSL_clear_mode(int ssl, long mode);
+    public static native long SSL_clear_mode(long ssl, long mode);
 
-    public static native long SSL_get_options(int ssl);
+    public static native long SSL_get_options(long ssl);
 
-    public static native long SSL_set_options(int ssl, long options);
+    public static native long SSL_set_options(long ssl, long options);
 
-    public static native long SSL_clear_options(int ssl, long options);
+    public static native long SSL_clear_options(long ssl, long options);
 
     public static String[] getDefaultProtocols() {
         return new String[] { SUPPORTED_PROTOCOL_SSLV3,
@@ -631,7 +644,7 @@
         };
     }
 
-    public static void setEnabledProtocols(int ssl, String[] protocols) {
+    public static void setEnabledProtocols(long ssl, String[] protocols) {
         checkEnabledProtocols(protocols);
         // openssl uses negative logic letting you disable protocols.
         // so first, assume we need to set all (disable all) and clear none (enable none).
@@ -682,9 +695,9 @@
         return protocols;
     }
 
-    public static native void SSL_set_cipher_lists(int ssl, String[] ciphers);
+    public static native void SSL_set_cipher_lists(long ssl, String[] ciphers);
 
-    public static void setEnabledCipherSuites(int ssl, String[] cipherSuites) {
+    public static void setEnabledCipherSuites(long ssl, String[] cipherSuites) {
         checkEnabledCipherSuites(cipherSuites);
         List<String> opensslSuites = new ArrayList<String>();
         for (int i = 0; i < cipherSuites.length; i++) {
@@ -731,17 +744,17 @@
     public static final int SSL_VERIFY_PEER =                 0x01;
     public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02;
 
-    public static native void SSL_set_verify(int sslNativePointer, int mode);
+    public static native void SSL_set_verify(long sslNativePointer, int mode);
 
-    public static native void SSL_set_session(int sslNativePointer, int sslSessionNativePointer)
+    public static native void SSL_set_session(long sslNativePointer, long sslSessionNativePointer)
         throws SSLException;
 
     public static native void SSL_set_session_creation_enabled(
-            int sslNativePointer, boolean creationEnabled) throws SSLException;
+            long sslNativePointer, boolean creationEnabled) throws SSLException;
 
-    public static native void SSL_set_tlsext_host_name(int sslNativePointer, String hostname)
+    public static native void SSL_set_tlsext_host_name(long sslNativePointer, String hostname)
             throws SSLException;
-    public static native String SSL_get_servername(int sslNativePointer);
+    public static native String SSL_get_servername(long sslNativePointer);
 
     /**
      * Enables NPN for all SSL connections in the context.
@@ -757,17 +770,17 @@
      * <p>In either case the caller should pass a non-null byte array of NPN
      * protocols to {@link #SSL_do_handshake}.
      */
-    public static native void SSL_CTX_enable_npn(int sslCtxNativePointer);
+    public static native void SSL_CTX_enable_npn(long sslCtxNativePointer);
 
     /**
      * Disables NPN for all SSL connections in the context.
      */
-    public static native void SSL_CTX_disable_npn(int sslCtxNativePointer);
+    public static native void SSL_CTX_disable_npn(long sslCtxNativePointer);
 
     /**
      * Returns the sslSessionNativePointer of the negotiated session
      */
-    public static native int SSL_do_handshake(int sslNativePointer,
+    public static native int SSL_do_handshake(long sslNativePointer,
                                               FileDescriptor fd,
                                               SSLHandshakeCallbacks shc,
                                               int timeoutMillis,
@@ -775,29 +788,29 @@
                                               byte[] npnProtocols)
         throws SSLException, SocketTimeoutException, CertificateException;
 
-    public static native byte[] SSL_get_npn_negotiated_protocol(int sslNativePointer);
+    public static native byte[] SSL_get_npn_negotiated_protocol(long sslNativePointer);
 
     /**
      * Currently only intended for forcing renegotiation for testing.
      * Not used within OpenSSLSocketImpl.
      */
-    public static native void SSL_renegotiate(int sslNativePointer) throws SSLException;
+    public static native void SSL_renegotiate(long sslNativePointer) throws SSLException;
 
     /**
      * Returns the local ASN.1 DER encoded X509 certificates.
      */
-    public static native byte[][] SSL_get_certificate(int sslNativePointer);
+    public static native byte[][] SSL_get_certificate(long sslNativePointer);
 
     /**
      * Returns the peer ASN.1 DER encoded X509 certificates.
      */
-    public static native byte[][] SSL_get_peer_cert_chain(int sslNativePointer);
+    public static native byte[][] SSL_get_peer_cert_chain(long sslNativePointer);
 
     /**
      * Reads with the native SSL_read function from the encrypted data stream
      * @return -1 if error or the end of the stream is reached.
      */
-    public static native int SSL_read(int sslNativePointer,
+    public static native int SSL_read(long sslNativePointer,
                                       FileDescriptor fd,
                                       SSLHandshakeCallbacks shc,
                                       byte[] b, int off, int len, int readTimeoutMillis)
@@ -806,32 +819,32 @@
     /**
      * Writes with the native SSL_write function to the encrypted data stream.
      */
-    public static native void SSL_write(int sslNativePointer,
+    public static native void SSL_write(long sslNativePointer,
                                         FileDescriptor fd,
                                         SSLHandshakeCallbacks shc,
                                         byte[] b, int off, int len, int writeTimeoutMillis)
         throws IOException;
 
-    public static native void SSL_interrupt(int sslNativePointer);
-    public static native void SSL_shutdown(int sslNativePointer,
+    public static native void SSL_interrupt(long sslNativePointer);
+    public static native void SSL_shutdown(long sslNativePointer,
                                            FileDescriptor fd,
                                            SSLHandshakeCallbacks shc) throws IOException;
 
-    public static native void SSL_free(int sslNativePointer);
+    public static native void SSL_free(long sslNativePointer);
 
-    public static native byte[] SSL_SESSION_session_id(int sslSessionNativePointer);
+    public static native byte[] SSL_SESSION_session_id(long sslSessionNativePointer);
 
-    public static native long SSL_SESSION_get_time(int sslSessionNativePointer);
+    public static native long SSL_SESSION_get_time(long sslSessionNativePointer);
 
-    public static native String SSL_SESSION_get_version(int sslSessionNativePointer);
+    public static native String SSL_SESSION_get_version(long sslSessionNativePointer);
 
-    public static native String SSL_SESSION_cipher(int sslSessionNativePointer);
+    public static native String SSL_SESSION_cipher(long sslSessionNativePointer);
 
-    public static native void SSL_SESSION_free(int sslSessionNativePointer);
+    public static native void SSL_SESSION_free(long sslSessionNativePointer);
 
-    public static native byte[] i2d_SSL_SESSION(int sslSessionNativePointer);
+    public static native byte[] i2d_SSL_SESSION(long sslSessionNativePointer);
 
-    public static native int d2i_SSL_SESSION(byte[] data);
+    public static native long d2i_SSL_SESSION(byte[] data);
 
     /**
      * A collection of callbacks from the native OpenSSL code that are
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLBIOInputStream.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLBIOInputStream.java
new file mode 100644
index 0000000..c2109b6
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLBIOInputStream.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.io.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.
+ */
+public class OpenSSLBIOInputStream extends FilterInputStream {
+    private long ctx;
+
+    public OpenSSLBIOInputStream(InputStream is) {
+        super(is);
+
+        ctx = NativeCrypto.create_BIO_InputStream(this);
+    }
+
+    public long getBioContext() {
+        return ctx;
+    }
+
+    public int readLine(byte[] buffer) throws IOException {
+        if (buffer == null || buffer.length == 0) {
+            return 0;
+        }
+
+        int offset = 0;
+        int inputByte = read();
+        while (offset < buffer.length && inputByte != '\n' && inputByte != -1) {
+            buffer[offset++] = (byte) inputByte;
+            inputByte = read();
+        }
+
+        if (inputByte == '\n') {
+            buffer[offset++] = '\n';
+        }
+
+        return offset;
+    }
+}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipher.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipher.java
index 007ff41..6ca8835 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipher.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipher.java
@@ -239,7 +239,7 @@
 
         checkSupportedKeySize(encodedKey.length);
 
-        final int cipherType = NativeCrypto.EVP_get_cipherbyname(getCipherName(encodedKey.length,
+        final long cipherType = NativeCrypto.EVP_get_cipherbyname(getCipherName(encodedKey.length,
                 mode));
         if (cipherType == 0) {
             throw new InvalidAlgorithmParameterException("Cannot find name for key length = "
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherContext.java
index b978b42..eb99334 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLCipherContext.java
@@ -17,9 +17,9 @@
 package org.apache.harmony.xnet.provider.jsse;
 
 class OpenSSLCipherContext {
-    private final int context;
+    private final long context;
 
-    OpenSSLCipherContext(int ctx) {
+    OpenSSLCipherContext(long ctx) {
         if (ctx == 0) {
             throw new NullPointerException("ctx == 0");
         }
@@ -36,7 +36,7 @@
         }
     }
 
-    int getContext() {
+    long getContext() {
         return context;
     }
 }
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLDigestContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLDigestContext.java
index 92c29bf..b3bd1a0 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLDigestContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLDigestContext.java
@@ -17,9 +17,9 @@
 package org.apache.harmony.xnet.provider.jsse;
 
 public class OpenSSLDigestContext {
-    private final int context;
+    private final long context;
 
-    public OpenSSLDigestContext(int ctx) {
+    public OpenSSLDigestContext(long ctx) {
         if (ctx == 0) {
             throw new NullPointerException("ctx == 0");
         }
@@ -36,7 +36,7 @@
         }
     }
 
-    int getContext() {
+    long getContext() {
         return context;
     }
 }
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECGroupContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECGroupContext.java
index fa116ce..173ce79 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECGroupContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECGroupContext.java
@@ -27,9 +27,9 @@
 import java.security.spec.EllipticCurve;
 
 public final class OpenSSLECGroupContext {
-    private final int groupCtx;
+    private final long groupCtx;
 
-    public OpenSSLECGroupContext(int groupCtx) {
+    public OpenSSLECGroupContext(long groupCtx) {
         this.groupCtx = groupCtx;
     }
 
@@ -42,7 +42,7 @@
             curveName = "prime192v1";
         }
 
-        final int ctx = NativeCrypto.EC_GROUP_new_by_curve_name(curveName);
+        final long ctx = NativeCrypto.EC_GROUP_new_by_curve_name(curveName);
         if (ctx == 0) {
             return null;
         }
@@ -56,7 +56,7 @@
 
     public static OpenSSLECGroupContext getInstance(int type, BigInteger p, BigInteger a,
             BigInteger b, BigInteger x, BigInteger y, BigInteger n, BigInteger h) {
-        final int ctx = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(), a.toByteArray(),
+        final long ctx = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(), a.toByteArray(),
                 b.toByteArray());
         if (ctx == 0) {
             return null;
@@ -106,7 +106,7 @@
         return super.hashCode();
     }
 
-    public int getContext() {
+    public long getContext() {
         return groupCtx;
     }
 
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPointContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPointContext.java
index 755e9f7..7c5c067 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPointContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPointContext.java
@@ -21,9 +21,9 @@
 
 final class OpenSSLECPointContext {
     private final OpenSSLECGroupContext group;
-    private final int pointCtx;
+    private final long pointCtx;
 
-    OpenSSLECPointContext(OpenSSLECGroupContext group, int pointCtx) {
+    OpenSSLECPointContext(OpenSSLECGroupContext group, long pointCtx) {
         this.group = group;
         this.pointCtx = pointCtx;
     }
@@ -67,7 +67,7 @@
         return super.hashCode();
     }
 
-    public int getContext() {
+    public long getContext() {
         return pointCtx;
     }
 
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPrivateKey.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPrivateKey.java
index 530fdd7..cc6c0a3 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPrivateKey.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPrivateKey.java
@@ -44,7 +44,7 @@
     }
 
     public OpenSSLECPrivateKey(OpenSSLKey key) {
-        final int origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
+        final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
         this.group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
         this.key = key;
     }
@@ -153,7 +153,7 @@
 
         key = new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(encoded));
 
-        final int origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
+        final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
         group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
     }
 
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPublicKey.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPublicKey.java
index 72c7212..9b667ad 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPublicKey.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECPublicKey.java
@@ -45,7 +45,7 @@
     }
 
     public OpenSSLECPublicKey(OpenSSLKey key) {
-        final int origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
+        final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
         this.group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
         this.key = key;
     }
@@ -158,7 +158,7 @@
 
         key = new OpenSSLKey(NativeCrypto.d2i_PUBKEY(encoded));
 
-        final int origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
+        final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
         group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
     }
 
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLEngine.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLEngine.java
index c4cfc6c..4e02aad 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLEngine.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLEngine.java
@@ -30,14 +30,14 @@
     private static final Object mLoadingLock = new Object();
 
     /** The ENGINE's native handle. */
-    private final int ctx;
+    private final long ctx;
 
     public static OpenSSLEngine getInstance(String engine) throws IllegalArgumentException {
         if (engine == null) {
             throw new NullPointerException("engine == null");
         }
 
-        final int engineCtx;
+        final long engineCtx;
         synchronized (mLoadingLock) {
             engineCtx = NativeCrypto.ENGINE_by_id(engine);
             if (engineCtx == 0) {
@@ -50,7 +50,7 @@
         return new OpenSSLEngine(engineCtx);
     }
 
-    private OpenSSLEngine(int engineCtx) {
+    private OpenSSLEngine(long engineCtx) {
         ctx = engineCtx;
 
         if (NativeCrypto.ENGINE_init(engineCtx) == 0) {
@@ -64,7 +64,7 @@
             throw new NullPointerException("id == null");
         }
 
-        final int keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
+        final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
         if (keyRef == 0) {
             return null;
         }
@@ -82,7 +82,7 @@
             throw new NullPointerException("id == null");
         }
 
-        final int keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
+        final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
         if (keyRef == 0) {
             return null;
         }
@@ -95,7 +95,7 @@
         }
     }
 
-    int getEngineContext() {
+    long getEngineContext() {
         return ctx;
     }
 
@@ -135,6 +135,6 @@
 
     @Override
     public int hashCode() {
-        return ctx;
+      return (int) ctx;
     }
 }
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLKey.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLKey.java
index 1e6561d..bdc06e9 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLKey.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLKey.java
@@ -23,19 +23,19 @@
 import javax.crypto.SecretKey;
 
 public class OpenSSLKey {
-    private final int ctx;
+    private final long ctx;
 
     private final OpenSSLEngine engine;
 
     private final String alias;
 
-    public OpenSSLKey(int ctx) {
+    public OpenSSLKey(long ctx) {
         this.ctx = ctx;
         engine = null;
         alias = null;
     }
 
-    public OpenSSLKey(int ctx, OpenSSLEngine engine, String alias) {
+    public OpenSSLKey(long ctx, OpenSSLEngine engine, String alias) {
         this.ctx = ctx;
         this.engine = engine;
         this.alias = alias;
@@ -46,7 +46,7 @@
      * life cycle of this native pointer is managed by the {@code OpenSSLKey}
      * instance and must not be destroyed or freed by users of this API.
      */
-    public int getPkeyContext() {
+    public long getPkeyContext() {
         return ctx;
     }
 
@@ -147,8 +147,8 @@
     @Override
     public int hashCode() {
         int hash = 1;
-        hash = hash * 17 + ctx;
-        hash = hash * 31 + (engine == null ? 0 : engine.getEngineContext());
+        hash = hash * 17 + (int) ctx;
+        hash = hash * 31 + (int) (engine == null ? 0 : engine.getEngineContext());
         return hash;
     }
 }
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMac.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMac.java
index 01118a3..54d9f25 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMac.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMac.java
@@ -33,7 +33,7 @@
      * Holds the EVP_MD for the hashing algorithm, e.g.
      * EVP_get_digestbyname("sha1");
      */
-    private final int evp_md;
+    private final long evp_md;
 
     /**
      * The key type of the secret key.
@@ -55,7 +55,7 @@
      */
     private final byte[] singleByte = new byte[1];
 
-    protected OpenSSLMac(int evp_md, int size, int evp_pkey_type) {
+    protected OpenSSLMac(long evp_md, int size, int evp_pkey_type) {
         this.evp_md = evp_md;
         this.size = size;
         this.evp_pkey_type = evp_pkey_type;
@@ -121,7 +121,7 @@
     }
 
     public static class HmacMD5 extends OpenSSLMac {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
 
         public HmacMD5() {
@@ -130,7 +130,7 @@
     }
 
     public static class HmacSHA1 extends OpenSSLMac {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
 
         public HmacSHA1() {
@@ -139,7 +139,7 @@
     }
 
     public static class HmacSHA256 extends OpenSSLMac {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
 
         public HmacSHA256() throws NoSuchAlgorithmException {
@@ -148,7 +148,7 @@
     }
 
     public static class HmacSHA384 extends OpenSSLMac {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
 
         public HmacSHA384() throws NoSuchAlgorithmException {
@@ -157,7 +157,7 @@
     }
 
     public static class HmacSHA512 extends OpenSSLMac {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
 
         public HmacSHA512() {
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java
index ba431bd..9d59a7c 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java
@@ -27,12 +27,12 @@
     /**
      * Holds a pointer to the native message digest context.
      */
-    private int ctx;
+    private long ctx;
 
     /**
      * Holds the EVP_MD for the hashing algorithm, e.g. EVP_get_digestbyname("sha1");
      */
-    private final int evp_md;
+    private final long evp_md;
 
     /**
      * Holds the output size of the message digest.
@@ -48,7 +48,7 @@
      * Creates a new OpenSSLMessageDigest instance for the given algorithm
      * name.
      */
-    private OpenSSLMessageDigestJDK(String algorithm, int evp_md, int size)
+    private OpenSSLMessageDigestJDK(String algorithm, long evp_md, int size)
             throws NoSuchAlgorithmException {
         super(algorithm);
         this.evp_md = evp_md;
@@ -90,7 +90,7 @@
         return d;
     }
 
-    private int getCtx() {
+    private long getCtx() {
         if (ctx == 0) {
             ctx = NativeCrypto.EVP_DigestInit(evp_md);
         }
@@ -113,7 +113,7 @@
     }
 
     public static class MD5 extends OpenSSLMessageDigestJDK {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
         public MD5() throws NoSuchAlgorithmException {
             super("MD5",EVP_MD, SIZE);
@@ -121,7 +121,7 @@
     }
 
     public static class SHA1 extends OpenSSLMessageDigestJDK {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
         public SHA1() throws NoSuchAlgorithmException {
             super("SHA-1", EVP_MD, SIZE);
@@ -129,7 +129,7 @@
     }
 
     public static class SHA256 extends OpenSSLMessageDigestJDK {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
         public SHA256() throws NoSuchAlgorithmException {
             super("SHA-256", EVP_MD, SIZE);
@@ -137,7 +137,7 @@
     }
 
     public static class SHA384 extends OpenSSLMessageDigestJDK {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
         public SHA384() throws NoSuchAlgorithmException {
             super("SHA-384", EVP_MD, SIZE);
@@ -145,7 +145,7 @@
     }
 
     public static class SHA512 extends OpenSSLMessageDigestJDK {
-        private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
+        private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
         private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
         public SHA512() throws NoSuchAlgorithmException {
             super("SHA-512", EVP_MD, SIZE);
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
index 003122f..1465027 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
@@ -44,7 +44,7 @@
     private boolean isValid = true;
     private final Map<String, Object> values = new HashMap<String, Object>();
     private volatile javax.security.cert.X509Certificate[] peerCertificateChain;
-    protected int sslSessionNativePointer;
+    protected long sslSessionNativePointer;
     private String peerHost;
     private int peerPort = -1;
     private String cipherSuite;
@@ -56,7 +56,7 @@
      * Class constructor creates an SSL session context given the appropriate
      * SSL parameters.
      */
-    protected OpenSSLSessionImpl(int sslSessionNativePointer, X509Certificate[] localCertificates,
+    protected OpenSSLSessionImpl(long sslSessionNativePointer, X509Certificate[] localCertificates,
             X509Certificate[] peerCertificates, String peerHost, int peerPort,
             AbstractSessionContext sessionContext) {
         this.sslSessionNativePointer = sslSessionNativePointer;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java
index 4affbae..34115ea 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java
@@ -43,7 +43,7 @@
     /**
      * Holds a pointer to the native message digest context.
      */
-    private int ctx;
+    private long ctx;
 
     /**
      * The current OpenSSL key we're operating on.
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index 2cc09fd..777c5b3 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -64,7 +64,7 @@
         extends javax.net.ssl.SSLSocket
         implements NativeCrypto.SSLHandshakeCallbacks {
 
-    private int sslNativePointer;
+    private long sslNativePointer;
     private InputStream is;
     private OutputStream os;
     private final Object handshakeLock = new Object();
@@ -266,7 +266,7 @@
 
         final boolean client = sslParameters.getUseClientMode();
 
-        final int sslCtxNativePointer = (client) ?
+        final long sslCtxNativePointer = (client) ?
             sslParameters.getClientSessionContext().sslCtxNativePointer :
             sslParameters.getServerSessionContext().sslCtxNativePointer;
 
diff --git a/luni/src/main/java/sun/misc/Unsafe.java b/luni/src/main/java/sun/misc/Unsafe.java
index 33bb9f1..884340b 100644
--- a/luni/src/main/java/sun/misc/Unsafe.java
+++ b/luni/src/main/java/sun/misc/Unsafe.java
@@ -27,8 +27,10 @@
  * of Java.
  */
 public final class Unsafe {
-    /** non-null; unique instance of this class */
+    /** Traditional dalvik name. */
     private static final Unsafe THE_ONE = new Unsafe();
+    /** Traditional RI name. */
+    private static final Unsafe theUnsafe = THE_ONE;
 
     /**
      * This class is only privately instantiable.
@@ -339,4 +341,10 @@
             throw new IllegalArgumentException("valid for Threads only");
         }
     }
+
+    /**
+     * Allocates an instance of the given class without running the constructor.
+     * The class' <clinit> will be run, if necessary.
+     */
+    public native Object allocateInstance(Class<?> c);
 }
diff --git a/luni/src/main/native/JniConstants.cpp b/luni/src/main/native/JniConstants.cpp
index efac219..b88eba9 100644
--- a/luni/src/main/native/JniConstants.cpp
+++ b/luni/src/main/native/JniConstants.cpp
@@ -37,12 +37,14 @@
 jclass JniConstants::inetAddressClass;
 jclass JniConstants::inetSocketAddressClass;
 jclass JniConstants::inflaterClass;
+jclass JniConstants::inputStreamClass;
 jclass JniConstants::integerClass;
 jclass JniConstants::localeDataClass;
 jclass JniConstants::longClass;
 jclass JniConstants::methodClass;
 jclass JniConstants::mutableIntClass;
 jclass JniConstants::mutableLongClass;
+jclass JniConstants::outputStreamClass;
 jclass JniConstants::parsePositionClass;
 jclass JniConstants::patternSyntaxExceptionClass;
 jclass JniConstants::realToStringClass;
@@ -89,12 +91,14 @@
     inetAddressClass = findClass(env, "java/net/InetAddress");
     inetSocketAddressClass = findClass(env, "java/net/InetSocketAddress");
     inflaterClass = findClass(env, "java/util/zip/Inflater");
+    inputStreamClass = findClass(env, "java/io/InputStream");
     integerClass = findClass(env, "java/lang/Integer");
     localeDataClass = findClass(env, "libcore/icu/LocaleData");
     longClass = findClass(env, "java/lang/Long");
     methodClass = findClass(env, "java/lang/reflect/Method");
     mutableIntClass = findClass(env, "libcore/util/MutableInt");
     mutableLongClass = findClass(env, "libcore/util/MutableLong");
+    outputStreamClass = findClass(env, "java/io/OutputStream");
     parsePositionClass = findClass(env, "java/text/ParsePosition");
     patternSyntaxExceptionClass = findClass(env, "java/util/regex/PatternSyntaxException");
     realToStringClass = findClass(env, "java/lang/RealToString");
diff --git a/luni/src/main/native/JniConstants.h b/luni/src/main/native/JniConstants.h
index 1928441..bb5aebb 100644
--- a/luni/src/main/native/JniConstants.h
+++ b/luni/src/main/native/JniConstants.h
@@ -58,12 +58,14 @@
     static jclass inetAddressClass;
     static jclass inetSocketAddressClass;
     static jclass inflaterClass;
+    static jclass inputStreamClass;
     static jclass integerClass;
     static jclass localeDataClass;
     static jclass longClass;
     static jclass methodClass;
     static jclass mutableIntClass;
     static jclass mutableLongClass;
+    static jclass outputStreamClass;
     static jclass parsePositionClass;
     static jclass patternSyntaxExceptionClass;
     static jclass realToStringClass;
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 29866c7..c94cd5d 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -73,6 +73,7 @@
     REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
     REGISTER(register_org_apache_harmony_xml_ExpatParser);
     REGISTER(register_org_apache_harmony_xnet_provider_jsse_NativeCrypto);
+    REGISTER(register_sun_misc_Unsafe);
 #undef REGISTER
     return JNI_VERSION_1_6;
 }
diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp
index 9b58301..2e5259e 100644
--- a/luni/src/main/native/java_util_regex_Matcher.cpp
+++ b/luni/src/main/native/java_util_regex_Matcher.cpp
@@ -30,7 +30,7 @@
 
 // ICU documentation: http://icu-project.org/apiref/icu4c/classRegexMatcher.html
 
-static RegexMatcher* toRegexMatcher(jint address) {
+static RegexMatcher* toRegexMatcher(jlong address) {
     return reinterpret_cast<RegexMatcher*>(static_cast<uintptr_t>(address));
 }
 
@@ -42,7 +42,7 @@
  */
 class MatcherAccessor {
 public:
-    MatcherAccessor(JNIEnv* env, jint address, jstring javaInput, bool reset) {
+    MatcherAccessor(JNIEnv* env, jlong address, jstring javaInput, bool reset) {
         init(env, address);
 
         mJavaInput = javaInput;
@@ -63,7 +63,7 @@
         }
     }
 
-    MatcherAccessor(JNIEnv* env, jint address) {
+    MatcherAccessor(JNIEnv* env, jlong address) {
         init(env, address);
     }
 
@@ -96,7 +96,7 @@
     }
 
 private:
-    void init(JNIEnv* env, jint address) {
+    void init(JNIEnv* env, jlong address) {
         mEnv = env;
         mJavaInput = NULL;
         mMatcher = toRegexMatcher(address);
@@ -117,11 +117,11 @@
     void operator=(const MatcherAccessor&);
 };
 
-static void Matcher_closeImpl(JNIEnv*, jclass, jint address) {
+static void Matcher_closeImpl(JNIEnv*, jclass, jlong address) {
     delete toRegexMatcher(address);
 }
 
-static jint Matcher_findImpl(JNIEnv* env, jclass, jint addr, jstring javaText, jint startIndex, jintArray offsets) {
+static jint Matcher_findImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jint startIndex, jintArray offsets) {
     MatcherAccessor matcher(env, addr, javaText, false);
     UBool result = matcher->find(startIndex, matcher.status());
     if (result) {
@@ -130,7 +130,7 @@
     return result;
 }
 
-static jint Matcher_findNextImpl(JNIEnv* env, jclass, jint addr, jstring javaText, jintArray offsets) {
+static jint Matcher_findNextImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jintArray offsets) {
     MatcherAccessor matcher(env, addr, javaText, false);
     if (matcher.status() != U_ZERO_ERROR) {
         return -1;
@@ -142,17 +142,17 @@
     return result;
 }
 
-static jint Matcher_groupCountImpl(JNIEnv* env, jclass, jint addr) {
+static jint Matcher_groupCountImpl(JNIEnv* env, jclass, jlong addr) {
     MatcherAccessor matcher(env, addr);
     return matcher->groupCount();
 }
 
-static jint Matcher_hitEndImpl(JNIEnv* env, jclass, jint addr) {
+static jint Matcher_hitEndImpl(JNIEnv* env, jclass, jlong addr) {
     MatcherAccessor matcher(env, addr);
     return matcher->hitEnd();
 }
 
-static jint Matcher_lookingAtImpl(JNIEnv* env, jclass, jint addr, jstring javaText, jintArray offsets) {
+static jint Matcher_lookingAtImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jintArray offsets) {
     MatcherAccessor matcher(env, addr, javaText, false);
     UBool result = matcher->lookingAt(matcher.status());
     if (result) {
@@ -161,7 +161,7 @@
     return result;
 }
 
-static jint Matcher_matchesImpl(JNIEnv* env, jclass, jint addr, jstring javaText, jintArray offsets) {
+static jint Matcher_matchesImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jintArray offsets) {
     MatcherAccessor matcher(env, addr, javaText, false);
     UBool result = matcher->matches(matcher.status());
     if (result) {
@@ -170,47 +170,47 @@
     return result;
 }
 
-static jint Matcher_openImpl(JNIEnv* env, jclass, jint patternAddr) {
+static jlong Matcher_openImpl(JNIEnv* env, jclass, jlong patternAddr) {
     RegexPattern* pattern = reinterpret_cast<RegexPattern*>(static_cast<uintptr_t>(patternAddr));
     UErrorCode status = U_ZERO_ERROR;
     RegexMatcher* result = pattern->matcher(status);
     maybeThrowIcuException(env, "RegexPattern::matcher", status);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(result));
+    return reinterpret_cast<uintptr_t>(result);
 }
 
-static jint Matcher_requireEndImpl(JNIEnv* env, jclass, jint addr) {
+static jint Matcher_requireEndImpl(JNIEnv* env, jclass, jlong addr) {
     MatcherAccessor matcher(env, addr);
     return matcher->requireEnd();
 }
 
-static void Matcher_setInputImpl(JNIEnv* env, jclass, jint addr, jstring javaText, jint start, jint end) {
+static void Matcher_setInputImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jint start, jint end) {
     MatcherAccessor matcher(env, addr, javaText, true);
     matcher->region(start, end, matcher.status());
 }
 
-static void Matcher_useAnchoringBoundsImpl(JNIEnv* env, jclass, jint addr, jboolean value) {
+static void Matcher_useAnchoringBoundsImpl(JNIEnv* env, jclass, jlong addr, jboolean value) {
     MatcherAccessor matcher(env, addr);
     matcher->useAnchoringBounds(value);
 }
 
-static void Matcher_useTransparentBoundsImpl(JNIEnv* env, jclass, jint addr, jboolean value) {
+static void Matcher_useTransparentBoundsImpl(JNIEnv* env, jclass, jlong addr, jboolean value) {
     MatcherAccessor matcher(env, addr);
     matcher->useTransparentBounds(value);
 }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Matcher, closeImpl, "(I)V"),
-    NATIVE_METHOD(Matcher, findImpl, "(ILjava/lang/String;I[I)Z"),
-    NATIVE_METHOD(Matcher, findNextImpl, "(ILjava/lang/String;[I)Z"),
-    NATIVE_METHOD(Matcher, groupCountImpl, "(I)I"),
-    NATIVE_METHOD(Matcher, hitEndImpl, "(I)Z"),
-    NATIVE_METHOD(Matcher, lookingAtImpl, "(ILjava/lang/String;[I)Z"),
-    NATIVE_METHOD(Matcher, matchesImpl, "(ILjava/lang/String;[I)Z"),
-    NATIVE_METHOD(Matcher, openImpl, "(I)I"),
-    NATIVE_METHOD(Matcher, requireEndImpl, "(I)Z"),
-    NATIVE_METHOD(Matcher, setInputImpl, "(ILjava/lang/String;II)V"),
-    NATIVE_METHOD(Matcher, useAnchoringBoundsImpl, "(IZ)V"),
-    NATIVE_METHOD(Matcher, useTransparentBoundsImpl, "(IZ)V"),
+    NATIVE_METHOD(Matcher, closeImpl, "(J)V"),
+    NATIVE_METHOD(Matcher, findImpl, "(JLjava/lang/String;I[I)Z"),
+    NATIVE_METHOD(Matcher, findNextImpl, "(JLjava/lang/String;[I)Z"),
+    NATIVE_METHOD(Matcher, groupCountImpl, "(J)I"),
+    NATIVE_METHOD(Matcher, hitEndImpl, "(J)Z"),
+    NATIVE_METHOD(Matcher, lookingAtImpl, "(JLjava/lang/String;[I)Z"),
+    NATIVE_METHOD(Matcher, matchesImpl, "(JLjava/lang/String;[I)Z"),
+    NATIVE_METHOD(Matcher, openImpl, "(J)J"),
+    NATIVE_METHOD(Matcher, requireEndImpl, "(J)Z"),
+    NATIVE_METHOD(Matcher, setInputImpl, "(JLjava/lang/String;II)V"),
+    NATIVE_METHOD(Matcher, useAnchoringBoundsImpl, "(JZ)V"),
+    NATIVE_METHOD(Matcher, useTransparentBoundsImpl, "(JZ)V"),
 };
 void register_java_util_regex_Matcher(JNIEnv* env) {
     jniRegisterNativeMethods(env, "java/util/regex/Matcher", gMethods, NELEM(gMethods));
diff --git a/luni/src/main/native/java_util_regex_Pattern.cpp b/luni/src/main/native/java_util_regex_Pattern.cpp
index bd1f326..1a99d0a 100644
--- a/luni/src/main/native/java_util_regex_Pattern.cpp
+++ b/luni/src/main/native/java_util_regex_Pattern.cpp
@@ -27,7 +27,7 @@
 
 // ICU documentation: http://icu-project.org/apiref/icu4c/classRegexPattern.html
 
-static RegexPattern* toRegexPattern(jint addr) {
+static RegexPattern* toRegexPattern(jlong addr) {
     return reinterpret_cast<RegexPattern*>(static_cast<uintptr_t>(addr));
 }
 
@@ -71,11 +71,11 @@
     env->Throw(reinterpret_cast<jthrowable>(exception));
 }
 
-static void Pattern_closeImpl(JNIEnv*, jclass, jint addr) {
+static void Pattern_closeImpl(JNIEnv*, jclass, jlong addr) {
     delete toRegexPattern(addr);
 }
 
-static jint Pattern_compileImpl(JNIEnv* env, jclass, jstring javaRegex, jint flags) {
+static jlong Pattern_compileImpl(JNIEnv* env, jclass, jstring javaRegex, jint flags) {
     flags |= UREGEX_ERROR_ON_UNKNOWN_ESCAPES;
 
     UErrorCode status = U_ZERO_ERROR;
@@ -91,12 +91,12 @@
     if (!U_SUCCESS(status)) {
         throwPatternSyntaxException(env, status, javaRegex, error);
     }
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(result));
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(result));
 }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Pattern, closeImpl, "(I)V"),
-    NATIVE_METHOD(Pattern, compileImpl, "(Ljava/lang/String;I)I"),
+    NATIVE_METHOD(Pattern, closeImpl, "(J)V"),
+    NATIVE_METHOD(Pattern, compileImpl, "(Ljava/lang/String;I)J"),
 };
 void register_java_util_regex_Pattern(JNIEnv* env) {
     jniRegisterNativeMethods(env, "java/util/regex/Pattern", gMethods, NELEM(gMethods));
diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
index 2c0f82a..1b68077 100644
--- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
@@ -65,6 +65,14 @@
 // don't overwhelm logcat
 #define WITH_JNI_TRACE_DATA_CHUNK_SIZE 512
 
+static JavaVM* gJavaVM;
+static jclass openSslOutputStreamClass;
+
+static jmethodID inputStream_readMethod;
+static jmethodID openSslInputStream_readLineMethod;
+static jmethodID outputStream_writeMethod;
+static jmethodID outputStream_flushMethod;
+
 struct BIO_Delete {
     void operator()(BIO* p) const {
         BIO_free(p);
@@ -481,7 +489,7 @@
  * @param throwIfNull whether to throw if the SSL pointer is NULL
  * @returns the pointer, which may be NULL
  */
-static SSL_CTX* to_SSL_CTX(JNIEnv* env, int ssl_ctx_address, bool throwIfNull) {
+static SSL_CTX* to_SSL_CTX(JNIEnv* env, jlong ssl_ctx_address, bool throwIfNull) {
     SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
     if ((ssl_ctx == NULL) && throwIfNull) {
         JNI_TRACE("ssl_ctx == null");
@@ -490,7 +498,7 @@
     return ssl_ctx;
 }
 
-static SSL* to_SSL(JNIEnv* env, int ssl_address, bool throwIfNull) {
+static SSL* to_SSL(JNIEnv* env, jlong ssl_address, bool throwIfNull) {
     SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
     if ((ssl == NULL) && throwIfNull) {
         JNI_TRACE("ssl == null");
@@ -499,7 +507,7 @@
     return ssl;
 }
 
-static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, int ssl_session_address, bool throwIfNull) {
+static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, jlong ssl_session_address, bool throwIfNull) {
     SSL_SESSION* ssl_session
         = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
     if ((ssl_session == NULL) && throwIfNull) {
@@ -611,6 +619,219 @@
 }
 
 /**
+ * BIO for InputStream
+ */
+class BIO_Stream {
+public:
+    BIO_Stream(jobject stream) :
+            mEof(false) {
+        JNIEnv* env = getEnv();
+        mStream = env->NewGlobalRef(stream);
+    }
+
+    ~BIO_Stream() {
+        JNIEnv* env = getEnv();
+
+        env->DeleteGlobalRef(mStream);
+    }
+
+    bool isEof() const {
+        JNI_TRACE("isEof? %s", mEof ? "yes" : "no");
+        return mEof;
+    }
+
+    int flush() {
+        JNIEnv* env = getEnv();
+        if (env == NULL) {
+            return -1;
+        }
+
+        env->CallVoidMethod(mStream, outputStream_flushMethod);
+        if (env->ExceptionCheck()) {
+            return -1;
+        }
+
+        return 1;
+    }
+
+protected:
+    jobject getStream() {
+        return mStream;
+    }
+
+    void setEof(bool eof) {
+        mEof = eof;
+    }
+
+    JNIEnv* getEnv() {
+        JNIEnv* env;
+
+        if (gJavaVM->AttachCurrentThread(&env, NULL) < 0) {
+            return NULL;
+        }
+
+        return env;
+    }
+
+private:
+    jobject mStream;
+    bool mEof;
+};
+
+class BIO_InputStream : public BIO_Stream {
+public:
+    BIO_InputStream(jobject stream) :
+            BIO_Stream(stream) {
+    }
+
+    int read(char *buf, int len) {
+        return read_internal(buf, len, inputStream_readMethod);
+    }
+
+    int gets(char *buf, int len) {
+        int read = read_internal(buf, len - 1, openSslInputStream_readLineMethod);
+        buf[read] = '\0';
+        JNI_TRACE("BIO::gets \"%s\"", buf);
+        return read;
+    }
+
+private:
+    int read_internal(char *buf, int len, jmethodID method) {
+        JNIEnv* env = getEnv();
+        if (env == NULL) {
+            JNI_TRACE("BIO_InputStream::read could not get JNIEnv");
+            return -1;
+        }
+
+        ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
+        if (javaBytes.get() == NULL) {
+            JNI_TRACE("BIO_InputStream::read failed call to NewByteArray");
+            return -1;
+        }
+
+        jint read = env->CallIntMethod(getStream(), method, javaBytes.get());
+        if (env->ExceptionCheck()) {
+            JNI_TRACE("BIO_InputStream::read failed call to InputStream#read");
+            return -1;
+        }
+
+        /* Java uses -1 to indicate EOF condition. */
+        if (read == -1) {
+            setEof(true);
+            read = 0;
+        } else if (read > 0) {
+            env->GetByteArrayRegion(javaBytes.get(), 0, read, reinterpret_cast<jbyte*>(buf));
+        }
+
+        return read;
+    }
+};
+
+class BIO_OutputStream : public BIO_Stream {
+public:
+    BIO_OutputStream(jobject stream) :
+            BIO_Stream(stream) {
+    }
+
+    int write(const char *buf, int len) {
+        JNIEnv* env = getEnv();
+        if (env == NULL) {
+            JNI_TRACE("BIO_OutputStream::write => could not get JNIEnv");
+            return -1;
+        }
+
+        ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
+        if (javaBytes.get() == NULL) {
+            JNI_TRACE("BIO_OutputStream::write => failed call to NewByteArray");
+            return -1;
+        }
+
+        env->SetByteArrayRegion(javaBytes.get(), 0, len, reinterpret_cast<const jbyte*>(buf));
+
+        env->CallVoidMethod(getStream(), outputStream_writeMethod, javaBytes.get());
+        if (env->ExceptionCheck()) {
+            JNI_TRACE("BIO_OutputStream::write => failed call to OutputStream#write");
+            return -1;
+        }
+
+        return 1;
+    }
+};
+
+static int bio_stream_create(BIO *b) {
+    b->init = 1;
+    b->num = 0;
+    b->ptr = NULL;
+    b->flags = 0;
+    return 1;
+}
+
+static int bio_stream_destroy(BIO *b) {
+    if (b == NULL) {
+        return 0;
+    }
+
+    if (b->ptr != NULL) {
+        delete static_cast<BIO_Stream*>(b->ptr);
+        b->ptr = NULL;
+    }
+
+    b->init = 0;
+    b->flags = 0;
+    return 1;
+}
+
+static int bio_stream_read(BIO *b, char *buf, int len) {
+    BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
+    return stream->read(buf, len);
+}
+
+static int bio_stream_write(BIO *b, const char *buf, int len) {
+    BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
+    return stream->write(buf, len);
+}
+
+static int bio_stream_puts(BIO *b, const char *buf) {
+    BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
+    return stream->write(buf, strlen(buf));
+}
+
+static int bio_stream_gets(BIO *b, char *buf, int len) {
+    BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
+    return stream->gets(buf, len);
+}
+
+static void bio_stream_assign(BIO *b, BIO_Stream* stream) {
+    b->ptr = static_cast<void*>(stream);
+}
+
+static long bio_stream_ctrl(BIO *b, int cmd, long, void *) {
+    BIO_Stream* stream = static_cast<BIO_Stream*>(b->ptr);
+
+    switch (cmd) {
+    case BIO_CTRL_EOF:
+        return stream->isEof() ? 1 : 0;
+    case BIO_CTRL_FLUSH:
+        return stream->flush();
+    default:
+        return 0;
+    }
+}
+
+static BIO_METHOD stream_bio_method = {
+        ( 100 | 0x0400 ), /* source/sink BIO */
+        "InputStream/OutputStream BIO",
+        bio_stream_write, /* bio_write */
+        bio_stream_read, /* bio_read */
+        bio_stream_puts, /* bio_puts */
+        bio_stream_gets, /* bio_gets */
+        bio_stream_ctrl, /* bio_ctrl */
+        bio_stream_create, /* bio_create */
+        bio_stream_destroy, /* bio_free */
+        NULL, /* no bio_callback_ctrl */
+};
+
+/**
  * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
  * suppose there are not many other ways to do this on a Linux system (modulo
  * isomorphism).
@@ -692,7 +913,7 @@
     ENGINE_load_dynamic();
 }
 
-static jint NativeCrypto_ENGINE_by_id(JNIEnv* env, jclass, jstring idJava) {
+static jlong NativeCrypto_ENGINE_by_id(JNIEnv* env, jclass, jstring idJava) {
     JNI_TRACE("ENGINE_by_id(%p)", idJava);
 
     ScopedUtfChars id(env, idJava);
@@ -708,10 +929,10 @@
     }
 
     JNI_TRACE("ENGINE_by_id(\"%s\") => %p", id.c_str(), e);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(e));
+    return reinterpret_cast<uintptr_t>(e);
 }
 
-static jint NativeCrypto_ENGINE_add(JNIEnv* env, jclass, jint engineRef) {
+static jint NativeCrypto_ENGINE_add(JNIEnv* env, jclass, jlong engineRef) {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
     JNI_TRACE("ENGINE_add(%p)", e);
 
@@ -732,7 +953,7 @@
     return ret;
 }
 
-static jint NativeCrypto_ENGINE_init(JNIEnv* env, jclass, jint engineRef) {
+static jint NativeCrypto_ENGINE_init(JNIEnv* env, jclass, jlong engineRef) {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
     JNI_TRACE("ENGINE_init(%p)", e);
 
@@ -746,7 +967,7 @@
     return ret;
 }
 
-static jint NativeCrypto_ENGINE_finish(JNIEnv* env, jclass, jint engineRef) {
+static jint NativeCrypto_ENGINE_finish(JNIEnv* env, jclass, jlong engineRef) {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
     JNI_TRACE("ENGINE_finish(%p)", e);
 
@@ -760,7 +981,7 @@
     return ret;
 }
 
-static jint NativeCrypto_ENGINE_free(JNIEnv* env, jclass, jint engineRef) {
+static jint NativeCrypto_ENGINE_free(JNIEnv* env, jclass, jlong engineRef) {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
     JNI_TRACE("ENGINE_free(%p)", e);
 
@@ -774,7 +995,7 @@
     return ret;
 }
 
-static jint NativeCrypto_ENGINE_load_private_key(JNIEnv* env, jclass, jint engineRef,
+static jlong NativeCrypto_ENGINE_load_private_key(JNIEnv* env, jclass, jlong engineRef,
         jstring idJava) {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
     JNI_TRACE("ENGINE_load_private_key(%p, %p)", e, idJava);
@@ -792,10 +1013,10 @@
     }
 
     JNI_TRACE("ENGINE_load_private_key(%p, %p) => %p", e, idJava, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
-static jstring NativeCrypto_ENGINE_get_id(JNIEnv* env, jclass, jint engineRef)
+static jstring NativeCrypto_ENGINE_get_id(JNIEnv* env, jclass, jlong engineRef)
 {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
     JNI_TRACE("ENGINE_get_id(%p)", e);
@@ -813,7 +1034,7 @@
     return idJava.release();
 }
 
-static jint NativeCrypto_ENGINE_ctrl_cmd_string(JNIEnv* env, jclass, jint engineRef,
+static jint NativeCrypto_ENGINE_ctrl_cmd_string(JNIEnv* env, jclass, jlong engineRef,
         jstring cmdJava, jstring argJava, jint cmd_optional)
 {
     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
@@ -860,7 +1081,7 @@
  * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
  *                                           byte[] pub_key, byte[] priv_key);
  */
-static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
+static jlong NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
                                                jbyteArray p, jbyteArray q, jbyteArray g,
                                                jbyteArray pub_key, jbyteArray priv_key) {
     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
@@ -869,54 +1090,54 @@
     Unique_DSA dsa(DSA_new());
     if (dsa.get() == NULL) {
         jniThrowRuntimeException(env, "DSA_new failed");
-        return NULL;
+        return 0;
     }
 
     if (!arrayToBignum(env, p, &dsa->p)) {
-        return NULL;
+        return 0;
     }
 
     if (!arrayToBignum(env, q, &dsa->q)) {
-        return NULL;
+        return 0;
     }
 
     if (!arrayToBignum(env, g, &dsa->g)) {
-        return NULL;
+        return 0;
     }
 
     if (pub_key != NULL && !arrayToBignum(env, pub_key, &dsa->pub_key)) {
-        return NULL;
+        return 0;
     }
 
     if (priv_key != NULL && !arrayToBignum(env, priv_key, &dsa->priv_key)) {
-        return NULL;
+        return 0;
     }
 
     if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL
             || (dsa->pub_key == NULL && dsa->priv_key == NULL)) {
         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
-        return NULL;
+        return 0;
     }
 
     Unique_EVP_PKEY pkey(EVP_PKEY_new());
     if (pkey.get() == NULL) {
         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
-        return NULL;
+        return 0;
     }
     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
         jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
-        return NULL;
+        return 0;
     }
     OWNERSHIP_TRANSFERRED(dsa);
     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
               p, q, g, pub_key, priv_key, pkey.get());
-    return pkey.release();
+    return reinterpret_cast<jlong>(pkey.release());
 }
 
 /**
  * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
  */
-static jint NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
+static jlong NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
                                                jbyteArray n, jbyteArray e, jbyteArray d,
                                                jbyteArray p, jbyteArray q,
                                                jbyteArray dmp1, jbyteArray dmq1,
@@ -1007,11 +1228,11 @@
     OWNERSHIP_TRANSFERRED(rsa);
     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p dmp1=%p, dmq1=%p, iqmp=%p) => %p",
             n, e, d, p, q, dmp1, dmq1, iqmp, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
-static jint NativeCrypto_EVP_PKEY_new_EC_KEY(JNIEnv* env, jclass, jint groupRef,
-        int pubkeyRef, jbyteArray keyJavaBytes) {
+static jlong NativeCrypto_EVP_PKEY_new_EC_KEY(JNIEnv* env, jclass, jlong groupRef,
+        jlong pubkeyRef, jbyteArray keyJavaBytes) {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     const EC_POINT* pubkey = reinterpret_cast<const EC_POINT*>(pubkeyRef);
     JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p)", group, pubkey, keyJavaBytes);
@@ -1086,10 +1307,10 @@
     OWNERSHIP_TRANSFERRED(eckey);
 
     JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => %p", group, pubkey, keyJavaBytes, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
-static jint NativeCrypto_EVP_PKEY_new_mac_key(JNIEnv* env, jclass, jint pkeyType,
+static jlong NativeCrypto_EVP_PKEY_new_mac_key(JNIEnv* env, jclass, jint pkeyType,
         jbyteArray keyJavaBytes)
 {
     JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p)", pkeyType, keyJavaBytes);
@@ -1108,10 +1329,10 @@
     }
 
     JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => %p", pkeyType, keyJavaBytes, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
-static int NativeCrypto_EVP_PKEY_type(JNIEnv* env, jclass, jint pkeyRef) {
+static int NativeCrypto_EVP_PKEY_type(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EVP_PKEY_type(%p)", pkey);
 
@@ -1128,7 +1349,7 @@
 /**
  * private static native int EVP_PKEY_size(int pkey);
  */
-static int NativeCrypto_EVP_PKEY_size(JNIEnv* env, jclass, jint pkeyRef) {
+static int NativeCrypto_EVP_PKEY_size(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EVP_PKEY_size(%p)", pkey);
 
@@ -1142,7 +1363,7 @@
     return result;
 }
 
-static jstring NativeCrypto_EVP_PKEY_print_public(JNIEnv* env, jclass, jint pkeyRef) {
+static jstring NativeCrypto_EVP_PKEY_print_public(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EVP_PKEY_print_public(%p)", pkey);
 
@@ -1172,7 +1393,7 @@
     return description;
 }
 
-static jstring NativeCrypto_EVP_PKEY_print_private(JNIEnv* env, jclass, jint pkeyRef) {
+static jstring NativeCrypto_EVP_PKEY_print_private(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EVP_PKEY_print_private(%p)", pkey);
 
@@ -1202,7 +1423,7 @@
     return description;
 }
 
-static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, jint pkeyRef) {
+static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EVP_PKEY_free(%p)", pkey);
 
@@ -1211,7 +1432,7 @@
     }
 }
 
-static jint NativeCrypto_EVP_PKEY_cmp(JNIEnv* env, jclass, jint pkey1Ref, jint pkey2Ref) {
+static jint NativeCrypto_EVP_PKEY_cmp(JNIEnv* env, jclass, jlong pkey1Ref, jlong pkey2Ref) {
     EVP_PKEY* pkey1 = reinterpret_cast<EVP_PKEY*>(pkey1Ref);
     EVP_PKEY* pkey2 = reinterpret_cast<EVP_PKEY*>(pkey2Ref);
     JNI_TRACE("EVP_PKEY_cmp(%p, %p)", pkey1, pkey2);
@@ -1234,7 +1455,7 @@
 /*
  * static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int, byte[])
  */
-static jbyteArray NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jint pkeyRef) {
+static jbyteArray NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("i2d_PKCS8_PRIV_KEY_INFO(%p)", pkey);
 
@@ -1256,7 +1477,7 @@
 /*
  * static native int d2i_PKCS8_PRIV_KEY_INFO(byte[])
  */
-static jint NativeCrypto_d2i_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jbyteArray keyJavaBytes) {
+static jlong NativeCrypto_d2i_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jbyteArray keyJavaBytes) {
     JNI_TRACE("d2i_PKCS8_PRIV_KEY_INFO(%p)", keyJavaBytes);
 
     ScopedByteArrayRO bytes(env, keyJavaBytes);
@@ -1281,13 +1502,13 @@
     }
 
     JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => %p", keyJavaBytes, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
 /*
  * static native byte[] i2d_PUBKEY(int)
  */
-static jbyteArray NativeCrypto_i2d_PUBKEY(JNIEnv* env, jclass, jint pkeyRef) {
+static jbyteArray NativeCrypto_i2d_PUBKEY(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("i2d_PUBKEY(%p)", pkey);
 
@@ -1302,7 +1523,7 @@
 /*
  * static native int d2i_PUBKEY(byte[])
  */
-static jint NativeCrypto_d2i_PUBKEY(JNIEnv* env, jclass, jbyteArray javaBytes) {
+static jlong NativeCrypto_d2i_PUBKEY(JNIEnv* env, jclass, jbyteArray javaBytes) {
     JNI_TRACE("d2i_PUBKEY(%p)", javaBytes);
 
     ScopedByteArrayRO bytes(env, javaBytes);
@@ -1319,13 +1540,13 @@
         return 0;
     }
 
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
 /*
  * public static native int RSA_generate_key(int modulusBits, byte[] publicExponent);
  */
-static jint NativeCrypto_RSA_generate_key_ex(JNIEnv* env, jclass, jint modulusBits,
+static jlong NativeCrypto_RSA_generate_key_ex(JNIEnv* env, jclass, jint modulusBits,
         jbyteArray publicExponent) {
     JNI_TRACE("RSA_generate_key_ex(%d, %p)", modulusBits, publicExponent);
 
@@ -1359,10 +1580,10 @@
 
     OWNERSHIP_TRANSFERRED(rsa);
     JNI_TRACE("RSA_generate_key_ex(n=%d, e=%p) => %p", modulusBits, publicExponent, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
-static jint NativeCrypto_RSA_size(JNIEnv* env, jclass, jint pkeyRef) {
+static jint NativeCrypto_RSA_size(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("RSA_size(%p)", pkey);
 
@@ -1380,7 +1601,7 @@
 
 static jint RSA_crypt_operation(RSACryptOperation operation,
         const char* caller __attribute__ ((unused)), JNIEnv* env, jint flen,
-        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jint pkeyRef, jint padding) {
+        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("%s(%d, %p, %p, %p)", caller, flen, fromJavaBytes, toJavaBytes, pkey);
 
@@ -1414,22 +1635,22 @@
 }
 
 static jint NativeCrypto_RSA_private_encrypt(JNIEnv* env, jclass, jint flen,
-        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jint pkeyRef, jint padding) {
+        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
     return RSA_crypt_operation(RSA_private_encrypt, __FUNCTION__,
                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
 }
 static jint NativeCrypto_RSA_public_decrypt(JNIEnv* env, jclass, jint flen,
-        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jint pkeyRef, jint padding) {
+        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
     return RSA_crypt_operation(RSA_public_decrypt, __FUNCTION__,
                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
 }
 static jint NativeCrypto_RSA_public_encrypt(JNIEnv* env, jclass, jint flen,
-        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jint pkeyRef, jint padding) {
+        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
     return RSA_crypt_operation(RSA_public_encrypt, __FUNCTION__,
                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
 }
 static jint NativeCrypto_RSA_private_decrypt(JNIEnv* env, jclass, jint flen,
-        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jint pkeyRef, jint padding) {
+        jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
     return RSA_crypt_operation(RSA_private_decrypt, __FUNCTION__,
                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
 }
@@ -1437,7 +1658,7 @@
 /*
  * public static native byte[][] get_RSA_public_params(int);
  */
-static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jint pkeyRef) {
+static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("get_RSA_public_params(%p)", pkey);
 
@@ -1475,7 +1696,7 @@
 /*
  * public static native byte[][] get_RSA_private_params(int);
  */
-static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jint pkeyRef) {
+static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("get_RSA_public_params(%p)", pkey);
 
@@ -1563,7 +1784,7 @@
 /*
  * public static native int DSA_generate_key(int, byte[]);
  */
-static jint NativeCrypto_DSA_generate_key(JNIEnv* env, jclass, jint primeBits,
+static jlong NativeCrypto_DSA_generate_key(JNIEnv* env, jclass, jint primeBits,
         jbyteArray seedJavaBytes, jbyteArray gBytes, jbyteArray pBytes, jbyteArray qBytes) {
     JNI_TRACE("DSA_generate_key(%d, %p, %p, %p, %p)", primeBits, seedJavaBytes,
             gBytes, pBytes, qBytes);
@@ -1636,13 +1857,13 @@
 
     OWNERSHIP_TRANSFERRED(dsa);
     JNI_TRACE("DSA_generate_key(n=%d, e=%p) => %p", primeBits, seedPtr.get(), pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
 /*
  * public static native byte[][] get_DSA_params(int);
  */
-static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jint pkeyRef) {
+static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jlong pkeyRef) {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("get_DSA_params(%p)", pkey);
 
@@ -1721,7 +1942,7 @@
     return 0;
 }
 
-static jint NativeCrypto_EC_GROUP_new_by_curve_name(JNIEnv* env, jclass, jstring curveNameJava)
+static jlong NativeCrypto_EC_GROUP_new_by_curve_name(JNIEnv* env, jclass, jstring curveNameJava)
 {
     JNI_TRACE("EC_GROUP_new_by_curve_name(%p)", curveNameJava);
 
@@ -1745,10 +1966,10 @@
     }
 
     JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => %p", curveName.c_str(), group);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(group));
+    return reinterpret_cast<uintptr_t>(group);
 }
 
-static void NativeCrypto_EC_GROUP_set_asn1_flag(JNIEnv* env, jclass, jint groupRef,
+static void NativeCrypto_EC_GROUP_set_asn1_flag(JNIEnv* env, jclass, jlong groupRef,
         jint flag)
 {
     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
@@ -1765,7 +1986,7 @@
 }
 
 static void NativeCrypto_EC_GROUP_set_point_conversion_form(JNIEnv* env, jclass,
-        jint groupRef, jint form)
+        jlong groupRef, jint form)
 {
     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d)", group, form);
@@ -1780,7 +2001,7 @@
     JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d) => success", group, form);
 }
 
-static jint NativeCrypto_EC_GROUP_new_curve(JNIEnv* env, jclass, jint type, jbyteArray pJava,
+static jlong NativeCrypto_EC_GROUP_new_curve(JNIEnv* env, jclass, jint type, jbyteArray pJava,
         jbyteArray aJava, jbyteArray bJava)
 {
     JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p)", type, pJava, aJava, bJava);
@@ -1821,10 +2042,10 @@
     }
 
     JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p) => %p", type, pJava, aJava, bJava, group);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(group));
+    return reinterpret_cast<uintptr_t>(group);
 }
 
-static jint NativeCrypto_EC_GROUP_dup(JNIEnv* env, jclass, jint groupRef) {
+static jlong NativeCrypto_EC_GROUP_dup(JNIEnv* env, jclass, jlong groupRef) {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_dup(%p)", group);
 
@@ -1836,10 +2057,10 @@
 
      EC_GROUP* groupDup = EC_GROUP_dup(group);
      JNI_TRACE("EC_GROUP_dup(%p) => %p", group, groupDup);
-     return static_cast<jint>(reinterpret_cast<uintptr_t>(groupDup));
+     return reinterpret_cast<uintptr_t>(groupDup);
 }
 
-static jstring NativeCrypto_EC_GROUP_get_curve_name(JNIEnv* env, jclass, jint groupRef) {
+static jstring NativeCrypto_EC_GROUP_get_curve_name(JNIEnv* env, jclass, jlong groupRef) {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_get_curve_name(%p)", group);
 
@@ -1860,7 +2081,7 @@
     return env->NewStringUTF(shortName);
 }
 
-static jobjectArray NativeCrypto_EC_GROUP_get_curve(JNIEnv* env, jclass, jint groupRef)
+static jobjectArray NativeCrypto_EC_GROUP_get_curve(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_get_curve(%p)", group);
@@ -1913,7 +2134,7 @@
     return joa;
 }
 
-static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jint groupRef)
+static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_get_order(%p)", group);
@@ -1940,7 +2161,7 @@
     return orderArray;
 }
 
-static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jint groupRef)
+static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_get_cofactor(%p)", group);
@@ -1967,7 +2188,7 @@
     return cofactorArray;
 }
 
-static jint NativeCrypto_get_EC_GROUP_type(JNIEnv* env, jclass, jint groupRef)
+static jint NativeCrypto_get_EC_GROUP_type(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("get_EC_GROUP_type(%p)", group);
@@ -1982,7 +2203,7 @@
     return type;
 }
 
-static void NativeCrypto_EC_GROUP_clear_free(JNIEnv* env, jclass, jint groupRef)
+static void NativeCrypto_EC_GROUP_clear_free(JNIEnv* env, jclass, jlong groupRef)
 {
     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_clear_free(%p)", group);
@@ -1997,7 +2218,7 @@
     JNI_TRACE("EC_GROUP_clear_free(%p) => success", group);
 }
 
-static jboolean NativeCrypto_EC_GROUP_cmp(JNIEnv* env, jclass, jint group1Ref, jint group2Ref)
+static jboolean NativeCrypto_EC_GROUP_cmp(JNIEnv* env, jclass, jlong group1Ref, jlong group2Ref)
 {
     const EC_GROUP* group1 = reinterpret_cast<const EC_GROUP*>(group1Ref);
     const EC_GROUP* group2 = reinterpret_cast<const EC_GROUP*>(group2Ref);
@@ -2015,7 +2236,7 @@
     return ret == 0;
 }
 
-static void NativeCrypto_EC_GROUP_set_generator(JNIEnv* env, jclass, jint groupRef, jint pointRef, jbyteArray njavaBytes, jbyteArray hjavaBytes)
+static void NativeCrypto_EC_GROUP_set_generator(JNIEnv* env, jclass, jlong groupRef, jlong pointRef, jbyteArray njavaBytes, jbyteArray hjavaBytes)
 {
     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
     const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
@@ -2048,7 +2269,7 @@
     JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => %d", group, point, njavaBytes, hjavaBytes, ret);
 }
 
-static jint NativeCrypto_EC_GROUP_get_generator(JNIEnv* env, jclass, jint groupRef)
+static jlong NativeCrypto_EC_GROUP_get_generator(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_GROUP_get_generator(%p)", group);
@@ -2069,10 +2290,10 @@
     }
 
     JNI_TRACE("EC_GROUP_get_generator(%p) => %p", group, dup.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(dup.release()));
+    return reinterpret_cast<uintptr_t>(dup.release());
 }
 
-static jint NativeCrypto_EC_POINT_new(JNIEnv* env, jclass, jint groupRef)
+static jlong NativeCrypto_EC_POINT_new(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_POINT_new(%p)", group);
@@ -2089,10 +2310,10 @@
         return 0;
     }
 
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(point));
+    return reinterpret_cast<uintptr_t>(point);
 }
 
-static void NativeCrypto_EC_POINT_clear_free(JNIEnv* env, jclass, jint groupRef) {
+static void NativeCrypto_EC_POINT_clear_free(JNIEnv* env, jclass, jlong groupRef) {
     EC_POINT* group = reinterpret_cast<EC_POINT*>(groupRef);
     JNI_TRACE("EC_POINT_clear_free(%p)", group);
 
@@ -2106,8 +2327,7 @@
     JNI_TRACE("EC_POINT_clear_free(%p) => success", group);
 }
 
-static jboolean NativeCrypto_EC_POINT_cmp(JNIEnv* env, jclass, jint groupRef, jint point1Ref,
-        jint point2Ref)
+static jboolean NativeCrypto_EC_POINT_cmp(JNIEnv* env, jclass, jlong groupRef, jlong point1Ref, jlong point2Ref)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     const EC_POINT* point1 = reinterpret_cast<const EC_POINT*>(point1Ref);
@@ -2128,7 +2348,7 @@
 }
 
 static void NativeCrypto_EC_POINT_set_affine_coordinates(JNIEnv* env, jclass,
-        jint groupRef, jint pointRef, jbyteArray xjavaBytes, jbyteArray yjavaBytes)
+        jlong groupRef, jlong pointRef, jbyteArray xjavaBytes, jbyteArray yjavaBytes)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     EC_POINT* point = reinterpret_cast<EC_POINT*>(pointRef);
@@ -2175,8 +2395,8 @@
             xjavaBytes, yjavaBytes, ret);
 }
 
-static jobjectArray NativeCrypto_EC_POINT_get_affine_coordinates(JNIEnv* env, jclass, jint groupRef,
-        jint pointRef)
+static jobjectArray NativeCrypto_EC_POINT_get_affine_coordinates(JNIEnv* env, jclass, jlong groupRef,
+        jlong pointRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
@@ -2224,7 +2444,7 @@
     return joa;
 }
 
-static jint NativeCrypto_EC_KEY_generate_key(JNIEnv* env, jclass, jint groupRef)
+static jlong NativeCrypto_EC_KEY_generate_key(JNIEnv* env, jclass, jlong groupRef)
 {
     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
     JNI_TRACE("EC_KEY_generate_key(%p)", group);
@@ -2261,10 +2481,10 @@
     OWNERSHIP_TRANSFERRED(eckey);
 
     JNI_TRACE("EC_KEY_generate_key(%p) => %p", group, pkey.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
+    return reinterpret_cast<uintptr_t>(pkey.release());
 }
 
-static jint NativeCrypto_EC_KEY_get0_group(JNIEnv* env, jclass, jint pkeyRef)
+static jlong NativeCrypto_EC_KEY_get0_group(JNIEnv* env, jclass, jlong pkeyRef)
 {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EC_KEY_get0_group(%p)", pkey);
@@ -2284,10 +2504,10 @@
 
     const EC_GROUP* group = EC_KEY_get0_group(pkey->pkey.ec);
     JNI_TRACE("EC_KEY_get0_group(%p) => %p", pkey, group);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(group));
+    return reinterpret_cast<uintptr_t>(group);
 }
 
-static jbyteArray NativeCrypto_EC_KEY_get_private_key(JNIEnv* env, jclass, jint pkeyRef)
+static jbyteArray NativeCrypto_EC_KEY_get_private_key(JNIEnv* env, jclass, jlong pkeyRef)
 {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EC_KEY_get_private_key(%p)", pkey);
@@ -2310,7 +2530,7 @@
     return privBytes;
 }
 
-static jint NativeCrypto_EC_KEY_get_public_key(JNIEnv* env, jclass, jint pkeyRef)
+static jlong NativeCrypto_EC_KEY_get_public_key(JNIEnv* env, jclass, jlong pkeyRef)
 {
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("EC_KEY_get_public_key(%p)", pkey);
@@ -2330,10 +2550,10 @@
     }
 
     JNI_TRACE("EC_KEY_get_public_key(%p) => %p", pkey, dup.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(dup.release()));
+    return reinterpret_cast<uintptr_t>(dup.release());
 }
 
-static jint NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
+static jlong NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
     JNI_TRACE("EVP_MD_CTX_create()");
 
     Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
@@ -2343,10 +2563,10 @@
     }
 
     JNI_TRACE("EVP_MD_CTX_create() => %p", ctx.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
+    return reinterpret_cast<uintptr_t>(ctx.release());
 }
 
-static void NativeCrypto_EVP_MD_CTX_init(JNIEnv*, jclass, jint ctxRef) {
+static void NativeCrypto_EVP_MD_CTX_init(JNIEnv*, jclass, jlong ctxRef) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_MD_CTX_init(%p)", ctx);
 
@@ -2355,7 +2575,7 @@
     }
 }
 
-static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, jint ctxRef) {
+static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, jlong ctxRef) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_MD_CTX_destroy(%p)", ctx);
 
@@ -2364,7 +2584,7 @@
     }
 }
 
-static jint NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, jint ctxRef) {
+static jlong NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, jlong ctxRef) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p)", ctx);
 
@@ -2389,13 +2609,13 @@
     }
 
     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p) => %p", ctx, copy);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(copy));
+    return reinterpret_cast<uintptr_t>(copy);
 }
 
 /*
  * public static native int EVP_DigestFinal(int, byte[], int)
  */
-static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, jint ctxRef,
+static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, jlong ctxRef,
                                          jbyteArray hash, jint offset) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
@@ -2425,7 +2645,7 @@
 /*
  * public static native int EVP_DigestInit(int)
  */
-static jint NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, jint evpMdRef) {
+static jlong NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, jlong evpMdRef) {
     EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
     JNI_TRACE("NativeCrypto_EVP_DigestInit(%p)", evp_md);
 
@@ -2448,13 +2668,13 @@
             return 0;
         }
     }
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
+    return reinterpret_cast<uintptr_t>(ctx.release());
 }
 
 /*
  * public static native int EVP_get_digestbyname(java.lang.String)
  */
-static jint NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) {
+static jlong NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) {
     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%p)", algorithm);
 
     if (algorithm == NULL) {
@@ -2475,13 +2695,14 @@
     }
 
     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => %p", algorithmChars.c_str(), evp_md);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(evp_md));
+    return reinterpret_cast<uintptr_t>(evp_md);
 }
 
 /*
  * public static native int EVP_MD_size(int)
  */
-static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, EVP_MD* evp_md) {
+static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, jint evpMdRef) {
+    EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
     JNI_TRACE("NativeCrypto_EVP_MD_size(%p)", evp_md);
 
     if (evp_md == NULL) {
@@ -2497,7 +2718,8 @@
 /*
  * public static int void EVP_MD_block_size(int)
  */
-static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, EVP_MD* evp_md) {
+static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, jlong evpMdRef) {
+    EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
     JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p)", evp_md);
 
     if (evp_md == NULL) {
@@ -2513,7 +2735,7 @@
 /*
  * public static native void EVP_DigestUpdate(int, byte[], int, int)
  */
-static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, jint ctxRef,
+static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, jlong ctxRef,
                                           jbyteArray buffer, jint offset, jint length) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_DigestUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
@@ -2541,7 +2763,7 @@
 }
 
 static void NativeCrypto_EVP_DigestSignInit(JNIEnv* env, jclass, jint evpMdCtxRef,
-        const jint evpMdRef, jint pkeyRef)
+        const jlong evpMdRef, jlong pkeyRef)
 {
     EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
     const EVP_MD* md = reinterpret_cast<const EVP_MD*>(evpMdRef);
@@ -2609,7 +2831,7 @@
             inLength);
 }
 
-static jbyteArray NativeCrypto_EVP_DigestSignFinal(JNIEnv* env, jclass, jint evpMdCtxRef)
+static jbyteArray NativeCrypto_EVP_DigestSignFinal(JNIEnv* env, jclass, jlong evpMdCtxRef)
 {
     EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
     JNI_TRACE("EVP_DigestSignFinal(%p)", mdCtx);
@@ -2645,7 +2867,7 @@
     return outJavaBytes.release();
 }
 
-static jint NativeCrypto_EVP_SignInit(JNIEnv* env, jclass, jstring algorithm) {
+static jlong NativeCrypto_EVP_SignInit(JNIEnv* env, jclass, jstring algorithm) {
     JNI_TRACE("NativeCrypto_EVP_SignInit(%p)", algorithm);
 
     if (algorithm == NULL) {
@@ -2683,13 +2905,13 @@
     }
 
     JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => %p", algorithmChars.c_str(), ctx.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
+    return reinterpret_cast<uintptr_t>(ctx.release());
 }
 
 /*
  * public static native void EVP_SignUpdate(int, byte[], int, int)
  */
-static void NativeCrypto_EVP_SignUpdate(JNIEnv* env, jclass, jint ctxRef,
+static void NativeCrypto_EVP_SignUpdate(JNIEnv* env, jclass, jlong ctxRef,
                                           jbyteArray buffer, jint offset, jint length) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_SignUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
@@ -2714,8 +2936,8 @@
 /*
  * public static native int EVP_SignFinal(int, byte[], int, int)
  */
-static jint NativeCrypto_EVP_SignFinal(JNIEnv* env, jclass, jint ctxRef, jbyteArray signature,
-        jint offset, jint pkeyRef) {
+static jint NativeCrypto_EVP_SignFinal(JNIEnv* env, jclass, jlong ctxRef, jbyteArray signature,
+        jint offset, jlong pkeyRef) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p)", ctx, signature, offset, pkey);
@@ -2746,7 +2968,7 @@
 /*
  * public static native int EVP_VerifyInit(java.lang.String)
  */
-static jint NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jstring algorithm) {
+static jlong NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jstring algorithm) {
     JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p)", algorithm);
 
     if (algorithm == NULL) {
@@ -2780,13 +3002,13 @@
             return 0;
         }
     }
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
+    return reinterpret_cast<uintptr_t>(ctx.release());
 }
 
 /*
  * public static native void EVP_VerifyUpdate(int, byte[], int, int)
  */
-static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, jint ctxRef,
+static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, jlong ctxRef,
                                           jbyteArray buffer, jint offset, jint length) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
@@ -2811,8 +3033,8 @@
 /*
  * public static native int EVP_VerifyFinal(int, byte[], int, int, int)
  */
-static jint NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, jint ctxRef, jbyteArray buffer,
-                                        jint offset, jint length, jint pkeyRef) {
+static jint NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, jlong ctxRef, jbyteArray buffer,
+                                        jint offset, jint length, jlong pkeyRef) {
     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
@@ -2847,7 +3069,7 @@
     return ok;
 }
 
-static jint NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algorithm) {
+static jlong NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algorithm) {
     JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
     if (algorithm == NULL) {
         JNI_TRACE("EVP_get_cipherbyname(%p) => threw exception algorithm == null", algorithm);
@@ -2867,10 +3089,10 @@
     }
 
     JNI_TRACE("EVP_get_cipherbyname(%s) => %p", algorithmChars.c_str(), evp_cipher);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(evp_cipher));
+    return reinterpret_cast<uintptr_t>(evp_cipher);
 }
 
-static void NativeCrypto_EVP_CipherInit_ex(JNIEnv* env, jclass, jint ctxRef, jint evpCipherRef,
+static void NativeCrypto_EVP_CipherInit_ex(JNIEnv* env, jclass, jlong ctxRef, jlong evpCipherRef,
         jbyteArray keyArray, jbyteArray ivArray, jboolean encrypting) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
@@ -2921,7 +3143,7 @@
  *  public static native int EVP_CipherUpdate(int ctx, byte[] out, int outOffset, byte[] in,
  *          int inOffset);
  */
-static jint NativeCrypto_EVP_CipherUpdate(JNIEnv* env, jclass, jint ctxRef, jbyteArray outArray,
+static jint NativeCrypto_EVP_CipherUpdate(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
         jint outOffset, jbyteArray inArray, jint inOffset, jint inLength) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d)", ctx, outArray, outOffset, inArray, inOffset);
@@ -2972,7 +3194,7 @@
     return outl;
 }
 
-static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jint ctxRef, jbyteArray outArray,
+static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
         jint outOffset) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     JNI_TRACE("EVP_CipherFinal_ex(%p, %p, %d)", ctx, outArray, outOffset);
@@ -3001,7 +3223,7 @@
     return outl;
 }
 
-static jint NativeCrypto_EVP_CIPHER_iv_length(JNIEnv* env, jclass, jint evpCipherRef) {
+static jint NativeCrypto_EVP_CIPHER_iv_length(JNIEnv* env, jclass, jlong evpCipherRef) {
     const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
     JNI_TRACE("EVP_CIPHER_iv_length(%p)", evpCipher);
 
@@ -3016,7 +3238,7 @@
     return ivLength;
 }
 
-static jint NativeCrypto_EVP_CIPHER_CTX_new(JNIEnv* env, jclass) {
+static jlong NativeCrypto_EVP_CIPHER_CTX_new(JNIEnv* env, jclass) {
     JNI_TRACE("EVP_CIPHER_CTX_new()");
 
     Unique_EVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
@@ -3027,10 +3249,10 @@
     }
 
     JNI_TRACE("EVP_CIPHER_CTX_new() => %p", ctx.get());
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
+    return reinterpret_cast<uintptr_t>(ctx.release());
 }
 
-static jint NativeCrypto_EVP_CIPHER_CTX_block_size(JNIEnv* env, jclass, jint ctxRef) {
+static jint NativeCrypto_EVP_CIPHER_CTX_block_size(JNIEnv* env, jclass, jlong ctxRef) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     JNI_TRACE("EVP_CIPHER_CTX_block_size(%p)", ctx);
 
@@ -3045,7 +3267,7 @@
     return blockSize;
 }
 
-static jint NativeCrypto_get_EVP_CIPHER_CTX_buf_len(JNIEnv* env, jclass, jint ctxRef) {
+static jint NativeCrypto_get_EVP_CIPHER_CTX_buf_len(JNIEnv* env, jclass, jlong ctxRef) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p)", ctx);
 
@@ -3060,7 +3282,7 @@
     return buf_len;
 }
 
-static void NativeCrypto_EVP_CIPHER_CTX_set_padding(JNIEnv* env, jclass, jint ctxRef, jboolean enablePaddingBool) {
+static void NativeCrypto_EVP_CIPHER_CTX_set_padding(JNIEnv* env, jclass, jlong ctxRef, jboolean enablePaddingBool) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     jint enablePadding = enablePaddingBool ? 1 : 0;
     JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d)", ctx, enablePadding);
@@ -3075,7 +3297,7 @@
     JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d) => success", ctx, enablePadding);
 }
 
-static void NativeCrypto_EVP_CIPHER_CTX_set_key_length(JNIEnv* env, jclass, jint ctxRef,
+static void NativeCrypto_EVP_CIPHER_CTX_set_key_length(JNIEnv* env, jclass, jlong ctxRef,
         jint keySizeBits) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d)", ctx, keySizeBits);
@@ -3090,7 +3312,7 @@
     JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d) => success", ctx, keySizeBits);
 }
 
-static void NativeCrypto_EVP_CIPHER_CTX_cleanup(JNIEnv*, jclass, jint ctxRef) {
+static void NativeCrypto_EVP_CIPHER_CTX_cleanup(JNIEnv*, jclass, jlong ctxRef) {
     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
     JNI_TRACE("EVP_CIPHER_CTX_cleanup(%p)", ctx);
 
@@ -3218,6 +3440,127 @@
     return env->NewStringUTF(output);
 }
 
+static jlong NativeCrypto_create_BIO_InputStream(JNIEnv* env, jclass, jobject streamObj) {
+    JNI_TRACE("create_BIO_InputStream(%p)", streamObj);
+
+    if (streamObj == NULL) {
+        jniThrowNullPointerException(env, "stream == null");
+        return 0;
+    }
+
+    Unique_BIO bio(BIO_new(&stream_bio_method));
+    if (bio.get() == NULL) {
+        return 0;
+    }
+
+    bio_stream_assign(bio.get(), new BIO_InputStream(streamObj));
+
+    JNI_TRACE("create_BIO_InputStream(%p) => %p", streamObj, bio.get());
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
+}
+
+static jlong NativeCrypto_create_BIO_OutputStream(JNIEnv* env, jclass, jobject streamObj) {
+    JNI_TRACE("create_BIO_OutputStream(%p)", streamObj);
+
+    if (streamObj == NULL) {
+        jniThrowNullPointerException(env, "stream == null");
+        return 0;
+    }
+
+    Unique_BIO bio(BIO_new(&stream_bio_method));
+    if (bio.get() == NULL) {
+        return 0;
+    }
+
+    bio_stream_assign(bio.get(), new BIO_OutputStream(streamObj));
+
+    JNI_TRACE("create_BIO_OutputStream(%p) => %p", streamObj, bio.get());
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
+}
+
+static int NativeCrypto_BIO_read(JNIEnv* env, jclass, jlong bioRef, jbyteArray outputJavaBytes) {
+    BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
+    JNI_TRACE("BIO_read(%p, %p)", bio, outputJavaBytes);
+
+    if (outputJavaBytes == NULL) {
+        jniThrowNullPointerException(env, "output == null");
+        JNI_TRACE("BIO_read(%p, %p) => output == null", bio, outputJavaBytes);
+        return 0;
+    }
+
+    int outputSize = env->GetArrayLength(outputJavaBytes);
+
+    UniquePtr<unsigned char[]> buffer(new unsigned char[outputSize]);
+    if (buffer.get() == NULL) {
+        jniThrowOutOfMemoryError(env, "Unable to allocate buffer for read");
+        return 0;
+    }
+
+    int read = BIO_read(bio, buffer.get(), outputSize);
+    if (read <= 0) {
+        jniThrowException(env, "java/io/IOException", "BIO_read");
+        JNI_TRACE("BIO_read(%p, %p) => threw IO exception", bio, outputJavaBytes);
+        return 0;
+    }
+
+    env->SetByteArrayRegion(outputJavaBytes, 0, read, reinterpret_cast<jbyte*>(buffer.get()));
+    JNI_TRACE("BIO_read(%p, %p) => %d", bio, outputJavaBytes, read);
+    return read;
+}
+
+static void NativeCrypto_BIO_write(JNIEnv* env, jclass, jlong bioRef, jbyteArray inputJavaBytes,
+        jint offset, jint length) {
+    BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
+    JNI_TRACE("BIO_write(%p, %p, %d, %d)", bio, inputJavaBytes, offset, length);
+
+    if (inputJavaBytes == NULL) {
+        jniThrowNullPointerException(env, "input == null");
+        return;
+    }
+
+    if (offset < 0 || length < 0) {
+        jniThrowException(env, "java/lang/IndexOutOfBoundsException", "offset < 0 || length < 0");
+        JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
+        return;
+    }
+
+    int inputSize = env->GetArrayLength(inputJavaBytes);
+    if (inputSize < offset + length) {
+        jniThrowException(env, "java/lang/IndexOutOfBoundsException",
+                "input.length < offset + length");
+        JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
+        return;
+    }
+
+    UniquePtr<unsigned char[]> buffer(new unsigned char[length]);
+    if (buffer.get() == NULL) {
+        jniThrowOutOfMemoryError(env, "Unable to allocate buffer for write");
+        return;
+    }
+
+    env->GetByteArrayRegion(inputJavaBytes, offset, length, reinterpret_cast<jbyte*>(buffer.get()));
+    if (BIO_write(bio, buffer.get(), length) != 1) {
+        freeOpenSslErrorState();
+        jniThrowException(env, "java/io/IOException", "BIO_write");
+        JNI_TRACE("BIO_write(%p, %p, %d, %d) => IO error", bio, inputJavaBytes, offset, length);
+        return;
+    }
+
+    JNI_TRACE("BIO_write(%p, %p, %d, %d) => success", bio, inputJavaBytes, offset, length);
+}
+
+static void NativeCrypto_BIO_free(JNIEnv* env, jclass, jlong bioRef) {
+    BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
+    JNI_TRACE("BIO_free(%p)", bio);
+
+    if (bio == NULL) {
+        jniThrowNullPointerException(env, "bio == null");
+        return;
+    }
+
+    BIO_free(bio);
+}
+
 #ifdef WITH_JNI_TRACE
 /**
  * Based on example logging call back from SSL_CTX_set_info_callback man page
@@ -3927,7 +4270,7 @@
 /*
  * public static native int SSL_CTX_new();
  */
-static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
+static jlong NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
     Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
     if (sslCtx.get() == NULL) {
         jniThrowRuntimeException(env, "SSL_CTX_new");
@@ -3971,14 +4314,14 @@
     SSL_CTX_set_tmp_ecdh_callback(sslCtx.get(), tmp_ecdh_callback);
 
     JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
-    return (jint) sslCtx.release();
+    return (jlong) sslCtx.release();
 }
 
 /**
  * public static native void SSL_CTX_free(int ssl_ctx)
  */
 static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
-        jclass, jint ssl_ctx_address)
+        jclass, jlong ssl_ctx_address)
 {
     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
@@ -3989,7 +4332,7 @@
 }
 
 static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass,
-                                                        jint ssl_ctx_address, jbyteArray sid_ctx)
+                                                        jlong ssl_ctx_address, jbyteArray sid_ctx)
 {
     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx);
@@ -4022,7 +4365,7 @@
 /**
  * public static native int SSL_new(int ssl_ctx) throws SSLException;
  */
-static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address)
+static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address)
 {
     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
@@ -4048,11 +4391,11 @@
     SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL);
 
     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get());
-    return (jint) ssl.release();
+    return (jlong) ssl.release();
 }
 
 
-static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jint ssl_address)
+static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_enable_tls_channel_id", ssl);
@@ -4070,7 +4413,7 @@
     }
 }
 
-static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jint ssl_address)
+static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id", ssl);
@@ -4109,7 +4452,7 @@
 }
 
 static void NativeCrypto_SSL_use_OpenSSL_PrivateKey_for_tls_channel_id(
-        JNIEnv* env, jclass, jint ssl_address, jint pkeyRef)
+        JNIEnv* env, jclass, jlong ssl_address, jlong pkeyRef)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
@@ -4146,7 +4489,7 @@
 }
 
 static void NativeCrypto_SSL_use_PKCS8_PrivateKey_for_tls_channel_id(
-        JNIEnv* env, jclass, jint ssl_address, jbyteArray privatekey)
+        JNIEnv* env, jclass, jlong ssl_address, jbyteArray privatekey)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey_for_tls_channel_id privatekey=%p", ssl,
@@ -4205,7 +4548,7 @@
     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey_for_tls_channel_id => ok", ssl);
 }
 
-static void NativeCrypto_SSL_use_OpenSSL_PrivateKey(JNIEnv* env, jclass, jint ssl_address, jint pkeyRef) {
+static void NativeCrypto_SSL_use_OpenSSL_PrivateKey(JNIEnv* env, jclass, jlong ssl_address, jlong pkeyRef) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
     JNI_TRACE("ssl=%p SSL_use_OpenSSL_PrivateKey privatekey=%p", ssl, pkey);
@@ -4234,7 +4577,7 @@
 }
 
 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass,
-                                            jint ssl_address, jbyteArray privatekey)
+                                            jlong ssl_address, jbyteArray privatekey)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey privatekey=%p", ssl, privatekey);
@@ -4285,7 +4628,7 @@
 }
 
 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
-                                             jint ssl_address, jobjectArray certificates)
+                                             jlong ssl_address, jobjectArray certificates)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
@@ -4370,7 +4713,7 @@
     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
 }
 
-static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jint ssl_address)
+static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
@@ -4388,7 +4731,7 @@
 }
 
 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
-                                                jint ssl_address, jobjectArray principals)
+                                                jlong ssl_address, jobjectArray principals)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
@@ -4455,7 +4798,7 @@
 /**
  * public static native long SSL_get_mode(int ssl);
  */
-static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jint ssl_address) {
+static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jlong ssl_address) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
     if (ssl == NULL) {
@@ -4470,7 +4813,7 @@
  * public static native long SSL_set_mode(int ssl, long mode);
  */
 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
-        jint ssl_address, jlong mode) {
+        jlong ssl_address, jlong mode) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
     if (ssl == NULL) {
@@ -4485,7 +4828,7 @@
  * public static native long SSL_clear_mode(int ssl, long mode);
  */
 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
-        jint ssl_address, jlong mode) {
+        jlong ssl_address, jlong mode) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
     if (ssl == NULL) {
@@ -4500,7 +4843,7 @@
  * public static native long SSL_get_options(int ssl);
  */
 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
-        jint ssl_address) {
+        jlong ssl_address) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
     if (ssl == NULL) {
@@ -4515,7 +4858,7 @@
  * public static native long SSL_set_options(int ssl, long options);
  */
 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
-        jint ssl_address, jlong options) {
+        jlong ssl_address, jlong options) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
     if (ssl == NULL) {
@@ -4530,7 +4873,7 @@
  * public static native long SSL_clear_options(int ssl, long options);
  */
 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
-        jint ssl_address, jlong options) {
+        jlong ssl_address, jlong options) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
     if (ssl == NULL) {
@@ -4545,7 +4888,7 @@
  * Sets the ciphers suites that are enabled in the SSL
  */
 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
-        jint ssl_address, jobjectArray cipherSuites)
+        jlong ssl_address, jobjectArray cipherSuites)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
@@ -4610,7 +4953,7 @@
  * Sets certificate expectations, especially for server to request client auth
  */
 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
-        jclass, jint ssl_address, jint mode)
+        jclass, jlong ssl_address, jint mode)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
@@ -4624,7 +4967,7 @@
  * Sets the ciphers suites that are enabled in the SSL
  */
 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
-        jint ssl_address, jint ssl_session_address)
+        jlong ssl_address, jlong ssl_session_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
@@ -4651,7 +4994,7 @@
  * Sets the ciphers suites that are enabled in the SSL
  */
 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
-        jint ssl_address, jboolean creation_enabled)
+        jlong ssl_address, jboolean creation_enabled)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
@@ -4663,7 +5006,7 @@
 }
 
 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
-        jint ssl_address, jstring hostname)
+        jlong ssl_address, jstring hostname)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
@@ -4689,7 +5032,7 @@
     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
 }
 
-static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jint ssl_address) {
+static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_address) {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
     if (ssl == NULL) {
@@ -4749,7 +5092,7 @@
     return SSL_TLSEXT_ERR_OK;
 }
 
-static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jint ssl_ctx_address)
+static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
 {
     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
     if (ssl_ctx == NULL) {
@@ -4759,7 +5102,7 @@
     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server
 }
 
-static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jint ssl_ctx_address)
+static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
 {
     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
     if (ssl_ctx == NULL) {
@@ -4770,7 +5113,7 @@
 }
 
 static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
-        jint ssl_address)
+        jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
@@ -4793,7 +5136,7 @@
 /**
  * Perform SSL handshake
  */
-static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jint ssl_address,
+static jlong NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jlong ssl_address,
         jobject fdObject, jobject shc, jint timeout_millis, jboolean client_mode,
         jbyteArray npnProtocols)
 {
@@ -4964,13 +5307,13 @@
     }
     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
-    return (jint) ssl_session;
+    return (jlong) ssl_session;
 }
 
 /**
  * Perform SSL renegotiation
  */
-static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jint ssl_address)
+static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
@@ -4999,7 +5342,7 @@
 /**
  * public static native byte[][] SSL_get_certificate(int ssl);
  */
-static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jint ssl_address)
+static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
@@ -5038,7 +5381,7 @@
 }
 
 // Fills a byte[][] with the peer certificates in the chain.
-static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jint ssl_address)
+static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
@@ -5213,7 +5556,7 @@
  * OpenSSL read function (2): read into buffer at offset n chunks.
  * Returns 1 (success) or value <= 0 (failure).
  */
-static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
+static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
                                   jobject shc, jbyteArray b, jint offset, jint len,
                                   jint read_timeout_millis)
 {
@@ -5420,7 +5763,7 @@
 /**
  * OpenSSL write function (2): write into buffer at offset n chunks.
  */
-static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
+static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
                                    jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
@@ -5470,7 +5813,7 @@
  * Interrupt any pending I/O before closing the socket.
  */
 static void NativeCrypto_SSL_interrupt(
-        JNIEnv* env, jclass, jint ssl_address) {
+        JNIEnv* env, jclass, jlong ssl_address) {
     SSL* ssl = to_SSL(env, ssl_address, false);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
     if (ssl == NULL) {
@@ -5494,7 +5837,7 @@
 /**
  * OpenSSL close SSL socket function.
  */
-static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jint ssl_address,
+static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jlong ssl_address,
                                       jobject fdObject, jobject shc) {
     SSL* ssl = to_SSL(env, ssl_address, false);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
@@ -5574,7 +5917,7 @@
 /**
  * public static native void SSL_free(int ssl);
  */
-static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jint ssl_address)
+static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jlong ssl_address)
 {
     SSL* ssl = to_SSL(env, ssl_address, true);
     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
@@ -5592,7 +5935,7 @@
  * Gets and returns in a byte array the ID of the actual SSL session.
  */
 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
-                                                      jint ssl_session_address) {
+                                                      jlong ssl_session_address) {
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
     if (ssl_session == NULL) {
@@ -5612,7 +5955,7 @@
  * Gets and returns in a long integer the creation's time of the
  * actual SSL session.
  */
-static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jint ssl_session_address) {
+static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jlong ssl_session_address) {
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
     if (ssl_session == NULL) {
@@ -5629,7 +5972,7 @@
  * Gets and returns in a string the version of the SSL protocol. If it
  * returns the string "unknown" it means that no connection is established.
  */
-static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jint ssl_session_address) {
+static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jlong ssl_session_address) {
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
     if (ssl_session == NULL) {
@@ -5643,7 +5986,7 @@
 /**
  * Gets and returns in a string the cipher negotiated for the SSL session.
  */
-static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jint ssl_session_address) {
+static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jlong ssl_session_address) {
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
     if (ssl_session == NULL) {
@@ -5658,7 +6001,7 @@
 /**
  * Frees the SSL session.
  */
-static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jint ssl_session_address) {
+static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jlong ssl_session_address) {
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
     if (ssl_session == NULL) {
@@ -5673,7 +6016,7 @@
  * not certificates). Returns a byte[] containing the DER-encoded state.
  * See apache mod_ssl.
  */
-static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jint ssl_session_address) {
+static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jlong ssl_session_address) {
     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
     if (ssl_session == NULL) {
@@ -5686,7 +6029,7 @@
 /**
  * Deserialize the session.
  */
-static jint NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
+static jlong NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
 
     ScopedByteArrayRO bytes(env, javaBytes);
@@ -5717,7 +6060,7 @@
     }
 
     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
-    return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
+    return reinterpret_cast<uintptr_t>(ssl_session);
 }
 
 static jlong NativeCrypto_ERR_peek_last_error(JNIEnv*, jclass) {
@@ -5729,145 +6072,166 @@
 static JNINativeMethod sNativeCryptoMethods[] = {
     NATIVE_METHOD(NativeCrypto, clinit, "()V"),
     NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_add, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_init, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_free, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(ILjava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(ILjava/lang/String;Ljava/lang/String;I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(II[B)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_mac_key, "(I[B)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(II)I"),
-    NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)I"),
-    NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)I"),
-    NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)I"),
-    NATIVE_METHOD(NativeCrypto, RSA_size, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[BII)I"),
-    NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[BII)I"),
-    NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[BII)I"),
-    NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[BII)I"),
-    NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(I)[[B"),
-    NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(I)[[B"),
-    NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)I"),
-    NATIVE_METHOD(NativeCrypto, get_DSA_params, "(I)[[B"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_new_curve, "(I[B[B[B)I"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_dup, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(I)[[B"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(II)Z"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EC_GROUP_set_generator, "(II[B[B)V"),
-    NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, EC_POINT_cmp, "(III)Z"),
-    NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(II[B[B)V"),
-    NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(II)[[B"),
-    NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EC_KEY_get0_group, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()I"),
-    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_init, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(I[BI)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(I[BII)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(I[BII)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(I[BII)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(I[BII)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(I[BIII)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(III)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(I[B)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(II[B[BZ)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(I[BI[BII)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(I[BI)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()I"),
-    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(IZ)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(I)V"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_add, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_init, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_free, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(JLjava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(JLjava/lang/String;Ljava/lang/String;I)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(JJ[B)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_mac_key, "(I[B)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(JJ)I"),
+    NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)J"),
+    NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)J"),
+    NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)J"),
+    NATIVE_METHOD(NativeCrypto, RSA_size, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[BJI)I"),
+    NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[BJI)I"),
+    NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[BJI)I"),
+    NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[BJI)I"),
+    NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(J)[[B"),
+    NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(J)[[B"),
+    NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)J"),
+    NATIVE_METHOD(NativeCrypto, get_DSA_params, "(J)[[B"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_new_curve, "(I[B[B[B)J"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_dup, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(JI)V"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(JI)V"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(J)[[B"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(JJ)Z"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EC_GROUP_set_generator, "(JJ[B[B)V"),
+    NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, EC_POINT_cmp, "(JJJ)Z"),
+    NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(JJ[B[B)V"),
+    NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(JJ)[[B"),
+    NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EC_KEY_get0_group, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()J"),
+    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_init, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(J[BI)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(J[BII)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(J[BII)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(J[BIJ)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(J[BII)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(J[BIIJ)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(JJJ)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(J[B)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)J"),
+    NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(JJ[B[BZ)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(J[BI[BII)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(J[BI)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()J"),
+    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(J)I"),
+    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(JZ)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(JI)V"),
+    NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(J)V"),
     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
     NATIVE_METHOD(NativeCrypto, RAND_bytes, "([B)V"),
     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid, "(Ljava/lang/String;)I"),
     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_longName, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_oid, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()I"),
-    NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(I[B)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_new, "(I)I"),
-    NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, SSL_use_OpenSSL_PrivateKey_for_tls_channel_id, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_use_PKCS8_PrivateKey_for_tls_channel_id, "(I[B)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_use_OpenSSL_PrivateKey, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(I[B)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(I[[B)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(I[[B)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(I)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(IJ)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(IJ)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_options, "(I)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_options, "(IJ)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(IJ)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(I[Ljava/lang/String;)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_session, "(II)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(IZ)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(ILjava/lang/String;)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B)I"),
-    NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(I)[[B"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(I)[[B"),
-    NATIVE_METHOD(NativeCrypto, SSL_read, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
-    NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(I" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
-    NATIVE_METHOD(NativeCrypto, SSL_free, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(I)J"),
-    NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(I)[B"),
-    NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)I"),
-    NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(I)V"),
-    NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(I)[B"),
+    NATIVE_METHOD(NativeCrypto, create_BIO_InputStream, "(Lorg/apache/harmony/xnet/provider/jsse/OpenSSLBIOInputStream;)J"),
+    NATIVE_METHOD(NativeCrypto, create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"),
+    NATIVE_METHOD(NativeCrypto, BIO_read, "(J[B)I"),
+    NATIVE_METHOD(NativeCrypto, BIO_write, "(J[BII)V"),
+    NATIVE_METHOD(NativeCrypto, BIO_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()J"),
+    NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(J[B)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_new, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, SSL_use_OpenSSL_PrivateKey_for_tls_channel_id, "(JJ)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_use_PKCS8_PrivateKey_for_tls_channel_id, "(J[B)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_use_OpenSSL_PrivateKey, "(JJ)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(J[B)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(J[[B)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(J[[B)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(JJ)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(JJ)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_options, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_options, "(JJ)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(JJ)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(J[Ljava/lang/String;)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(JI)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_session, "(JJ)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(JZ)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(JLjava/lang/String;)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B)I"),
+    NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[[B"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[[B"),
+    NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
+    NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(J" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
+    NATIVE_METHOD(NativeCrypto, SSL_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(J)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(J)Ljava/lang/String;"),
+    NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(J)[B"),
+    NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)J"),
+    NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(J)V"),
+    NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(J)[B"),
     NATIVE_METHOD(NativeCrypto, ERR_peek_last_error, "()J"),
 };
 void register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
     JNI_TRACE("register_org_apache_harmony_xnet_provider_jsse_NativeCrypto");
     jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/NativeCrypto",
                              sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
+
+    env->GetJavaVM(&gJavaVM);
+
+    ScopedLocalRef<jclass> localClass(env,
+            env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLBIOInputStream"));
+    openSslOutputStreamClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
+    if (openSslOutputStreamClass == NULL) {
+        ALOGE("failed to find class OpenSSLBIOInputStream");
+        abort();
+    }
+
+    inputStream_readMethod = env->GetMethodID(JniConstants::inputStreamClass, "read", "([B)I");
+    openSslInputStream_readLineMethod = env->GetMethodID(openSslOutputStreamClass, "readLine",
+            "([B)I");
+    outputStream_writeMethod = env->GetMethodID(JniConstants::outputStreamClass, "write", "([B)V");
+    outputStream_flushMethod = env->GetMethodID(JniConstants::outputStreamClass, "flush", "()V");
 }
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 6622f7c..7ea5033 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -51,6 +51,7 @@
 	org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp \
 	readlink.cpp \
 	realpath.cpp \
+	sun_misc_Unsafe.cpp \
 	toStringArray.cpp \
 	valueOf.cpp
 
diff --git a/luni/src/main/native/sun_misc_Unsafe.cpp b/luni/src/main/native/sun_misc_Unsafe.cpp
new file mode 100644
index 0000000..d0a23be
--- /dev/null
+++ b/luni/src/main/native/sun_misc_Unsafe.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Unsafe"
+
+#include "JNIHelp.h"
+#include "JniConstants.h"
+
+static jobject Unsafe_allocateInstance(JNIEnv* env, jclass, jclass c) {
+  return env->AllocObject(c);
+}
+
+static JNINativeMethod gMethods[] = {
+  NATIVE_METHOD(Unsafe, allocateInstance, "(Ljava/lang/Class;)Ljava/lang/Object;"),
+};
+void register_sun_misc_Unsafe(JNIEnv* env) {
+  jniRegisterNativeMethods(env, "sun/misc/Unsafe", gMethods, NELEM(gMethods));
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
index ee7c15b..fa920ce 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
@@ -25,8 +25,10 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
+import java.security.InvalidKeyException;
 import java.security.Provider;
 import java.security.Security;
+import java.security.SignatureException;
 import java.security.cert.CRL;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509CRL;
@@ -41,6 +43,7 @@
 import java.util.Set;
 
 import junit.framework.TestCase;
+import libcore.java.security.StandardNames;
 
 public class X509CRLTest extends TestCase {
     private Provider[] mX509Providers;
@@ -49,10 +52,14 @@
 
     private static final String CERT_DSA = "x509/cert-dsa.der";
 
+    private static final String CERT_CRL_CA = "x509/cert-crl-ca.der";
+
     private static final String CRL_RSA = "x509/crl-rsa.der";
 
     private static final String CRL_RSA_DSA = "x509/crl-rsa-dsa.der";
 
+    private static final String CRL_RSA_DSA_SIGOPT = "x509/crl-rsa-dsa-sigopt.der";
+
     private static final String CRL_UNSUPPORTED = "x509/crl-unsupported.der";
 
     private static final String CRL_RSA_DATES = "x509/crl-rsa-dates.txt";
@@ -63,6 +70,8 @@
 
     private static final String CRL_RSA_TBS = "x509/crl-rsa-tbs.der";
 
+    private static final String CRL_EMPTY = "x509/crl-empty.der";
+
     private final X509Certificate getCertificate(CertificateFactory f, String name)
             throws Exception {
         final InputStream is = Support_Resources.getStream(name);
@@ -153,6 +162,8 @@
                 getThisUpdateNextUpdate(f);
                 getSigAlgName(f);
                 getSigAlgOID(f);
+                getSigAlgParams(f);
+                verify(f);
                 test_toString(f);
                 test_equals(f);
             } catch (Throwable e) {
@@ -167,6 +178,20 @@
         }
     }
 
+    private void verify(CertificateFactory f) throws Exception {
+        X509CRL crlRsa = getCRL(f, CRL_RSA);
+
+        X509Certificate caCert = getCertificate(f, CERT_CRL_CA);
+        crlRsa.verify(caCert.getPublicKey());
+
+        X509Certificate dsaCert = getCertificate(f, CERT_DSA);
+        try {
+            crlRsa.verify(dsaCert.getPublicKey());
+            fail("should not verify using incorrect key type");
+        } catch (InvalidKeyException expected) {
+        }
+    }
+
     private void getType(CertificateFactory f) throws Exception {
         CRL crlRsa = getCRL(f, CRL_RSA);
 
@@ -291,7 +316,7 @@
         assertEquals(result1, result2);
     }
 
-    private void assertRsaCrl(CertificateFactory f, X509CRLEntry rsaEntry) throws Exception {
+    private void assertRsaCrlEntry(CertificateFactory f, X509CRLEntry rsaEntry) throws Exception {
         assertNotNull(rsaEntry);
 
         X509Certificate rsaCert = getCertificate(f, CERT_RSA);
@@ -304,9 +329,11 @@
         assertFalse(rsaEntry.hasExtensions());
         assertNull(rsaEntry.getCriticalExtensionOIDs());
         assertNull(rsaEntry.getNonCriticalExtensionOIDs());
+
+        assertNotNull(rsaEntry.toString());
     }
 
-    private void assertDsaCrl(CertificateFactory f, X509CRLEntry dsaEntry) throws Exception {
+    private void assertDsaCrlEntry(CertificateFactory f, X509CRLEntry dsaEntry) throws Exception {
         X509Certificate dsaCert = getCertificate(f, CERT_DSA);
         Map<String, Date> dates = getCrlDates(CRL_RSA_DSA_DATES);
         Date expectedDate = dates.get("lastUpdate");
@@ -319,9 +346,14 @@
         assertNotNull(dsaEntry.getCriticalExtensionOIDs());
         /* TODO: get the OID */
         assertNotNull(dsaEntry.getNonCriticalExtensionOIDs());
+
+        assertNotNull(dsaEntry.toString());
     }
 
     private void getRevokedCertificates(CertificateFactory f) throws Exception {
+        X509CRL crlEmpty = getCRL(f, CRL_EMPTY);
+        assertNull(crlEmpty.getRevokedCertificates());
+
         X509CRL crlRsa = getCRL(f, CRL_RSA);
         X509Certificate rsaCert = getCertificate(f, CERT_RSA);
         X509Certificate dsaCert = getCertificate(f, CERT_DSA);
@@ -329,14 +361,48 @@
         Set<? extends X509CRLEntry> entries = crlRsa.getRevokedCertificates();
         assertEquals(1, entries.size());
         for (X509CRLEntry e : entries) {
-            assertRsaCrl(f, e);
+            assertRsaCrlEntry(f, e);
         }
 
         X509CRL crlRsaDsa = getCRL(f, CRL_RSA_DSA);
         Set<? extends X509CRLEntry> entries2 = crlRsaDsa.getRevokedCertificates();
         assertEquals(2, entries2.size());
-        assertRsaCrl(f, crlRsaDsa.getRevokedCertificate(rsaCert));
-        assertDsaCrl(f, crlRsaDsa.getRevokedCertificate(dsaCert));
+        assertRsaCrlEntry(f, crlRsaDsa.getRevokedCertificate(rsaCert));
+        assertDsaCrlEntry(f, crlRsaDsa.getRevokedCertificate(dsaCert));
+    }
+
+    private void getSigAlgParams(CertificateFactory f) throws Exception {
+        X509CRL crl1 = getCRL(f, CRL_RSA);
+        final byte[] sigAlgParams = crl1.getSigAlgParams();
+        if (StandardNames.IS_RI) {
+            assertNull(f.getProvider().getName(), sigAlgParams);
+        } else {
+            assertNotNull(f.getProvider().getName(), sigAlgParams);
+            /* ASN.1 NULL */
+            final byte[] expected = new byte[] {
+                    0x05, 0x00,
+            };
+            assertEquals(f.getProvider().getName(), Arrays.toString(expected),
+                    Arrays.toString(sigAlgParams));
+        }
+
+        {
+            X509CRL crlSigOpt = getCRL(f, CRL_RSA_DSA_SIGOPT);
+
+            /* SEQUENCE, INTEGER 1 */
+            final byte[] expected = new byte[] {
+                    /* SEQUENCE, constructed, len=5 */
+                    (byte) 0x30, (byte) 0x05,
+                    /* Type=2, constructed, context-specific, len=3 */
+                    (byte) 0xA2, (byte) 0x03,
+                    /* INTEGER, len=1, value=1 */
+                    (byte) 0x02, (byte) 0x01, (byte) 0x01,
+            };
+
+            final byte[] params = crlSigOpt.getSigAlgParams();
+            assertNotNull(f.getProvider().getName(), params);
+            assertEquals(Arrays.toString(expected), Arrays.toString(params));
+        }
     }
 
     private void test_toString(CertificateFactory f) throws Exception {
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
index 9e0e2f8..8dd1452 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
@@ -105,6 +105,8 @@
 
     private static final String CERT_UNSUPPORTED = "x509/cert-unsupported.der";
 
+    private static final String CERT_SIGOPT = "x509/cert-sigopt.der";
+
     private static final String CERTS_X509_PEM = "x509/certs.pem";
 
     private static final String CERTS_X509_DER = "x509/certs.der";
@@ -639,12 +641,11 @@
     private void getSigAlgParams(CertificateFactory f) throws Exception {
         {
             X509Certificate c = getCertificate(f, CERT_RSA);
-            // Harmony and BC are broken?
-            String provider = f.getProvider().getName();
-            if ("DRLCertFactory".equals(provider) || "BC".equals(provider)) {
-                assertNotNull(c.getSigAlgParams());
-            } else {
+            // RI appears to disagree
+            if (StandardNames.IS_RI) {
                 assertNull(f.getProvider().getName(), c.getSigAlgParams());
+            } else {
+                assertNotNull(f.getProvider().getName(), c.getSigAlgParams());
             }
         }
 
@@ -657,6 +658,24 @@
             X509Certificate c = getCertificate(f, CERT_EC);
             assertNull(f.getProvider().getName(), c.getSigAlgParams());
         }
+
+        {
+            X509Certificate c = getCertificate(f, CERT_SIGOPT);
+
+            /* SEQUENCE, INTEGER 1 */
+            final byte[] expected = new byte[] {
+                    /* SEQUENCE, constructed, len=5 */
+                    (byte) 0x30, (byte) 0x05,
+                    /* Type=2, constructed, context-specific, len=3 */
+                    (byte) 0xA2, (byte) 0x03,
+                    /* INTEGER, len=1, value=1 */
+                    (byte) 0x02, (byte) 0x01, (byte) 0x01,
+            };
+
+            final byte[] params = c.getSigAlgParams();
+            assertNotNull(f.getProvider().getName(), params);
+            assertEquals(Arrays.toString(expected), Arrays.toString(params));
+        }
     }
 
     private void getKeyUsage(CertificateFactory f) throws Exception {
diff --git a/luni/src/test/java/libcore/java/util/FormatterTest.java b/luni/src/test/java/libcore/java/util/FormatterTest.java
index 5c59807..596e946 100644
--- a/luni/src/test/java/libcore/java/util/FormatterTest.java
+++ b/luni/src/test/java/libcore/java/util/FormatterTest.java
@@ -130,4 +130,9 @@
                     output[i], result);
         }
     }
+
+    // https://code.google.com/p/android/issues/detail?id=42936
+    public void test42936() throws Exception {
+        assertEquals("0.00000000000000", String.format("%.15g",0.0d));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
index bd6109b..8d6e186 100644
--- a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
+++ b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
@@ -643,4 +643,12 @@
             t.join();
         }
     }
+
+    // https://code.google.com/p/android/issues/detail?id=33040
+    public void test33040() throws Exception {
+        Pattern p = Pattern.compile("ma");
+        // replaceFirst resets the region; apparently, this was broken in Android 1.6.
+        String result = p.matcher("mama").region(2, 4).replaceFirst("mi");
+        assertEquals("mima", result);
+    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
index d531596..fba683b 100644
--- a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
@@ -17,6 +17,8 @@
 package org.apache.harmony.xnet.provider.jsse;
 
 import dalvik.system.BaseDexClassLoader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.math.BigInteger;
@@ -58,7 +60,7 @@
     /** Corresponds to the native test library "libjavacoretests.so" */
     public static final String TEST_ENGINE_ID = "javacoretests";
 
-    private static final int NULL = 0;
+    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);
@@ -154,7 +156,7 @@
                 16).toByteArray();
     }
 
-    public static void assertEqualSessions(int expected, int actual) {
+    public static void assertEqualSessions(long expected, long actual) {
         assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected),
                               NativeCrypto.SSL_SESSION_session_id(actual));
     }
@@ -188,7 +190,7 @@
         KeyPair kp2 = kpg.generateKeyPair();
         RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate();
 
-        int pkey1 = 0, pkey1_copy = 0, pkey2 = 0;
+        long pkey1 = 0, pkey1_copy = 0, pkey2 = 0;
         try {
             pkey1 = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
                         privKey1.getPublicExponent().toByteArray(),
@@ -254,9 +256,9 @@
     }
 
     public void test_SSL_CTX_new() throws Exception {
-        int c = NativeCrypto.SSL_CTX_new();
+        long c = NativeCrypto.SSL_CTX_new();
         assertTrue(c != NULL);
-        int c2 = NativeCrypto.SSL_CTX_new();
+        long c2 = NativeCrypto.SSL_CTX_new();
         assertTrue(c != c2);
         NativeCrypto.SSL_CTX_free(c);
         NativeCrypto.SSL_CTX_free(c2);
@@ -279,7 +281,7 @@
             fail();
         } catch (NullPointerException expected) {
         }
-        int c = NativeCrypto.SSL_CTX_new();
+        long c = NativeCrypto.SSL_CTX_new();
         try {
             NativeCrypto.SSL_CTX_set_session_id_context(c, null);
             fail();
@@ -295,8 +297,8 @@
     }
 
     public void test_SSL_new() throws Exception {
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         assertTrue(s != NULL);
         assertTrue((NativeCrypto.SSL_get_options(s) & 0x01000000L) != 0); // SSL_OP_NO_SSLv2
@@ -305,7 +307,7 @@
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_1) == 0);
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_2) == 0);
 
-        int s2 = NativeCrypto.SSL_new(c);
+        long s2 = NativeCrypto.SSL_new(c);
         assertTrue(s != s2);
         NativeCrypto.SSL_free(s2);
 
@@ -320,8 +322,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         try {
             NativeCrypto.SSL_use_certificate(s, null);
@@ -342,8 +344,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         try {
             NativeCrypto.SSL_set1_tls_channel_id(s, null);
@@ -377,8 +379,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         try {
             NativeCrypto.SSL_use_PrivateKey(s, null);
@@ -401,8 +403,8 @@
     }
 
     public void test_SSL_check_private_key_no_key_no_cert() throws Exception {
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         // neither private or certificate set
         try {
@@ -416,8 +418,8 @@
     }
 
     public void test_SSL_check_private_key_cert_then_key() throws Exception {
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         // first certificate, then private
         NativeCrypto.SSL_use_certificate(s, getServerCertificates());
@@ -435,8 +437,8 @@
         NativeCrypto.SSL_CTX_free(c);
     }
     public void test_SSL_check_private_key_key_then_cert() throws Exception {
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         // first private, then certificate
         NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey());
@@ -461,8 +463,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         assertTrue(NativeCrypto.SSL_get_mode(s) != 0);
         NativeCrypto.SSL_free(s);
         NativeCrypto.SSL_CTX_free(c);
@@ -475,8 +477,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         // check SSL_MODE_HANDSHAKE_CUTTHROUGH off by default
         assertEquals(0, NativeCrypto.SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
         // set SSL_MODE_HANDSHAKE_CUTTHROUGH on
@@ -499,8 +501,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         assertTrue(NativeCrypto.SSL_get_options(s) != 0);
         NativeCrypto.SSL_free(s);
         NativeCrypto.SSL_CTX_free(c);
@@ -513,8 +515,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
         NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
@@ -529,8 +531,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
         NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
         assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
@@ -547,8 +549,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         try {
             NativeCrypto.SSL_set_cipher_lists(s, null);
@@ -597,8 +599,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE);
         NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
         NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
@@ -613,11 +615,11 @@
     public static class Hooks {
         private ECPrivateKey channelIdPrivateKey;
 
-        public int getContext() throws SSLException {
+        public long getContext() throws SSLException {
             return NativeCrypto.SSL_CTX_new();
         }
-        public int beforeHandshake(int context) throws SSLException {
-            int s = NativeCrypto.SSL_new(context);
+        public long beforeHandshake(long context) throws SSLException {
+            long s = NativeCrypto.SSL_new(context);
             // without this SSL_set_cipher_lists call the tests were
             // negotiating DHE-RSA-AES256-SHA by default which had
             // very slow ephemeral RSA key generation
@@ -628,8 +630,8 @@
             }
             return s;
         }
-        public void clientCertificateRequested(int s) {}
-        public void afterHandshake(int session, int ssl, int context,
+        public void clientCertificateRequested(long s) {}
+        public void afterHandshake(long session, long ssl, long context,
                                    Socket socket, FileDescriptor fd,
                                    SSLHandshakeCallbacks callback)
                 throws Exception {
@@ -654,11 +656,11 @@
 
     public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks {
         private final Socket socket;
-        private final int sslNativePointer;
+        private final long sslNativePointer;
         private final Hooks hooks;
 
         public TestSSLHandshakeCallbacks(Socket socket,
-                                         int sslNativePointer,
+                                         long sslNativePointer,
                                          Hooks hooks) {
             this.socket = socket;
             this.sslNativePointer = sslNativePointer;
@@ -673,7 +675,7 @@
                                            String authMethod)
                 throws CertificateException {
             if (DEBUG) {
-                System.out.println("ssl=0x" + Integer.toString(sslNativePointer, 16)
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
                                    + " verifyCertificateChain"
                                    + " asn1DerEncodedCertificateChain="
                                    + asn1DerEncodedCertificateChain
@@ -690,7 +692,7 @@
         public void clientCertificateRequested(byte[] keyTypes,
                                                byte[][] asn1DerEncodedX500Principals) {
             if (DEBUG) {
-                System.out.println("ssl=0x" + Integer.toString(sslNativePointer, 16)
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
                                    + " clientCertificateRequested"
                                    + " keyTypes=" + keyTypes
                                    + " asn1DerEncodedX500Principals="
@@ -707,7 +709,7 @@
         public boolean handshakeCompletedCalled;
         public void handshakeCompleted() {
             if (DEBUG) {
-                System.out.println("ssl=0x" + Integer.toString(sslNativePointer, 16)
+                System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
                                    + " handshakeCompleted");
             }
             this.handshakeCompletedCalled = true;
@@ -731,8 +733,8 @@
         }
 
         @Override
-        public int beforeHandshake(int c) throws SSLException {
-            int s = super.beforeHandshake(c);
+        public long beforeHandshake(long c) throws SSLException {
+            long s = super.beforeHandshake(c);
             if (privateKey != null) {
                 NativeCrypto.SSL_use_PrivateKey(s, privateKey);
             }
@@ -746,7 +748,7 @@
         }
 
         @Override
-        public void afterHandshake(int session, int ssl, int context,
+        public void afterHandshake(long session, long ssl, long context,
                                    Socket socket, FileDescriptor fd,
                                    SSLHandshakeCallbacks callback)
                 throws Exception {
@@ -760,7 +762,7 @@
           super.afterHandshake(session, ssl, context, socket, fd, callback);
         }
 
-        public void clientCertificateRequested(int s) {
+        public void clientCertificateRequested(long s) {
             fail("Server asked for client certificates");
         }
     }
@@ -779,27 +781,27 @@
                     return new TestSSLHandshakeCallbacks(socket, 0, null);
                 }
                 FileDescriptor fd = socket.getFileDescriptor$();
-                int c = hooks.getContext();
-                int s = hooks.beforeHandshake(c);
+                long c = hooks.getContext();
+                long s = hooks.beforeHandshake(c);
                 TestSSLHandshakeCallbacks callback
                         = new TestSSLHandshakeCallbacks(socket, s, hooks);
                 if (DEBUG) {
-                    System.out.println("ssl=0x" + Integer.toString(s, 16)
+                    System.out.println("ssl=0x" + Long.toString(s, 16)
                                        + " handshake"
-                                       + " context=0x" + Integer.toString(c, 16)
+                                       + " context=0x" + Long.toString(c, 16)
                                        + " socket=" + socket
                                        + " fd=" + fd
                                        + " timeout=" + timeout
                                        + " client=" + client);
                 }
-                int session = NULL;
+                long session = NULL;
                 try {
                     session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client,
                                                             npnProtocols);
                     if (DEBUG) {
-                        System.out.println("ssl=0x" + Integer.toString(s, 16)
+                        System.out.println("ssl=0x" + Long.toString(s, 16)
                                            + " handshake"
-                                           + " session=0x" + Integer.toString(session, 16));
+                                           + " session=0x" + Long.toString(session, 16));
                     }
                 } finally {
                     // Ensure afterHandshake is called to free resources
@@ -821,8 +823,8 @@
     }
 
     public void test_SSL_do_handshake_null_args() throws Exception {
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
 
         try {
             NativeCrypto.SSL_do_handshake(s, null, null, 0, true, null);
@@ -866,7 +868,7 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void clientCertificateRequested(int s) {
+            public void clientCertificateRequested(long s) {
                 super.clientCertificateRequested(s);
                 NativeCrypto.SSL_use_PrivateKey(s, getClientPrivateKey());
                 NativeCrypto.SSL_use_certificate(s, getClientCertificates());
@@ -874,8 +876,8 @@
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
             @Override
-            public int beforeHandshake(int c) throws SSLException {
-                int s = super.beforeHandshake(c);
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
                 NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
                 NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
                 return s;
@@ -917,8 +919,8 @@
             Hooks cHooks = new Hooks();
             Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
                 @Override
-                public int beforeHandshake(int c) throws SSLException {
-                    int s = super.beforeHandshake(c);
+                public long beforeHandshake(long c) throws SSLException {
+                    long s = super.beforeHandshake(c);
                     NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
                     NativeCrypto.SSL_set_verify(s,
                                                 NativeCrypto.SSL_VERIFY_PEER
@@ -950,13 +952,13 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public int beforeHandshake(int context) throws SSLException {
-                int s = super.beforeHandshake(context);
+            public long beforeHandshake(long context) throws SSLException {
+                long s = super.beforeHandshake(context);
                 NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
                 return s;
             }
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -965,14 +967,14 @@
                 super.afterHandshake(session, s, c, sock, fd, callback);
             }
             @Override
-            public void clientCertificateRequested(int s) {
+            public void clientCertificateRequested(long s) {
                 super.clientCertificateRequested(s);
                 throw new RuntimeException("expected");
             }
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1130,27 +1132,27 @@
         }
 
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             NativeCrypto.SSL_set_session(s, NULL);
             NativeCrypto.SSL_free(s);
             NativeCrypto.SSL_CTX_free(c);
         }
 
         {
-            final int clientContext = NativeCrypto.SSL_CTX_new();
-            final int serverContext = NativeCrypto.SSL_CTX_new();
+            final long clientContext = NativeCrypto.SSL_CTX_new();
+            final long serverContext = NativeCrypto.SSL_CTX_new();
             final ServerSocket listener = new ServerSocket(0);
-            final int[] clientSession = new int[] { NULL };
-            final int[] serverSession = new int[] { NULL };
+            final long[] clientSession = new long[] { NULL };
+            final long[] serverSession = new long[] { NULL };
             {
                 Hooks cHooks = new Hooks() {
                     @Override
-                    public int getContext() throws SSLException {
+                    public long getContext() throws SSLException {
                         return clientContext;
                     }
                     @Override
-                    public void afterHandshake(int session, int s, int c,
+                    public void afterHandshake(long session, long s, long c,
                                                Socket sock, FileDescriptor fd,
                                                SSLHandshakeCallbacks callback)
                             throws Exception {
@@ -1160,11 +1162,11 @@
                 };
                 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
                     @Override
-                    public int getContext() throws SSLException {
+                    public long getContext() throws SSLException {
                         return serverContext;
                     }
                     @Override
-                    public void afterHandshake(int session, int s, int c,
+                    public void afterHandshake(long session, long s, long c,
                                                Socket sock, FileDescriptor fd,
                                                SSLHandshakeCallbacks callback)
                             throws Exception {
@@ -1183,17 +1185,17 @@
             {
                 Hooks cHooks = new Hooks() {
                     @Override
-                    public int getContext() throws SSLException {
+                    public long getContext() throws SSLException {
                         return clientContext;
                     }
                     @Override
-                    public int beforeHandshake(int c) throws SSLException {
-                        int s = NativeCrypto.SSL_new(clientContext);
+                    public long beforeHandshake(long c) throws SSLException {
+                        long s = NativeCrypto.SSL_new(clientContext);
                         NativeCrypto.SSL_set_session(s, clientSession[0]);
                         return s;
                     }
                     @Override
-                    public void afterHandshake(int session, int s, int c,
+                    public void afterHandshake(long session, long s, long c,
                                                Socket sock, FileDescriptor fd,
                                                SSLHandshakeCallbacks callback)
                             throws Exception {
@@ -1203,11 +1205,11 @@
                 };
                 Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
                     @Override
-                    public int getContext() throws SSLException {
+                    public long getContext() throws SSLException {
                         return serverContext;
                     }
                     @Override
-                    public void afterHandshake(int session, int s, int c,
+                    public void afterHandshake(long session, long s, long c,
                                                Socket sock, FileDescriptor fd,
                                                SSLHandshakeCallbacks callback)
                             throws Exception {
@@ -1237,8 +1239,8 @@
         }
 
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             NativeCrypto.SSL_set_session_creation_enabled(s, false);
             NativeCrypto.SSL_set_session_creation_enabled(s, true);
             NativeCrypto.SSL_free(s);
@@ -1251,8 +1253,8 @@
         try {
             Hooks cHooks = new Hooks() {
                 @Override
-                public int beforeHandshake(int c) throws SSLException {
-                    int s = super.beforeHandshake(c);
+                public long beforeHandshake(long c) throws SSLException {
+                    long s = super.beforeHandshake(c);
                     NativeCrypto.SSL_set_session_creation_enabled(s, false);
                     return s;
                 }
@@ -1271,8 +1273,8 @@
             Hooks cHooks = new Hooks();
             Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
                 @Override
-                public int beforeHandshake(int c) throws SSLException {
-                    int s = super.beforeHandshake(c);
+                public long beforeHandshake(long c) throws SSLException {
+                    long s = super.beforeHandshake(c);
                     NativeCrypto.SSL_set_session_creation_enabled(s, false);
                     return s;
                 }
@@ -1297,8 +1299,8 @@
         final String hostname = "www.android.com";
 
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
 
             // null hostname
             try {
@@ -1329,15 +1331,15 @@
         // normal
         Hooks cHooks = new Hooks() {
             @Override
-            public int beforeHandshake(int c) throws SSLException {
-                int s = super.beforeHandshake(c);
+            public long beforeHandshake(long c) throws SSLException {
+                long s = super.beforeHandshake(c);
                 NativeCrypto.SSL_set_tlsext_host_name(s, hostname);
                 return s;
             }
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1364,11 +1366,11 @@
         };
 
         Hooks cHooks = new Hooks() {
-            @Override public int beforeHandshake(int context) throws SSLException {
+            @Override public long beforeHandshake(long context) throws SSLException {
                 NativeCrypto.SSL_CTX_enable_npn(context);
                 return super.beforeHandshake(context);
             }
-            @Override public void afterHandshake(int session, int ssl, int context, Socket socket,
+            @Override public void afterHandshake(long session, long ssl, long context, Socket socket,
                     FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
                 byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
                 assertEquals("spdy/2", new String(negotiated));
@@ -1378,11 +1380,11 @@
             }
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
-            @Override public int beforeHandshake(int context) throws SSLException {
+            @Override public long beforeHandshake(long context) throws SSLException {
                 NativeCrypto.SSL_CTX_enable_npn(context);
                 return super.beforeHandshake(context);
             }
-            @Override public void afterHandshake(int session, int ssl, int c, Socket sock,
+            @Override public void afterHandshake(long session, long ssl, long c, Socket sock,
                     FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
                 byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
                 assertEquals("spdy/2", new String(negotiated));
@@ -1409,8 +1411,8 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         assertNull(NativeCrypto.SSL_get_servername(s));
         NativeCrypto.SSL_free(s);
         NativeCrypto.SSL_CTX_free(c);
@@ -1428,7 +1430,7 @@
         final ServerSocket listener = new ServerSocket(0);
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1440,7 +1442,7 @@
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                 throws Exception {
@@ -1465,7 +1467,7 @@
         final ServerSocket listener = new ServerSocket(0);
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                 throws Exception {
@@ -1475,7 +1477,7 @@
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1502,7 +1504,7 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1531,8 +1533,8 @@
 
         // null FileDescriptor
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_read(s, null, DUMMY_CB, null, 0, 0, 0);
                 fail();
@@ -1544,8 +1546,8 @@
 
         // null SSLHandshakeCallbacks
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_read(s, INVALID_FD, null, null, 0, 0, 0);
                 fail();
@@ -1557,8 +1559,8 @@
 
         // null byte array
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, null, 0, 0, 0);
                 fail();
@@ -1570,8 +1572,8 @@
 
         // handshaking not yet performed
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
                 fail();
@@ -1587,7 +1589,7 @@
         {
             Hooks cHooks = new Hooks() {
                 @Override
-                public void afterHandshake(int session, int s, int c,
+                public void afterHandshake(long session, long s, long c,
                                            Socket sock, FileDescriptor fd,
                                            SSLHandshakeCallbacks callback)
                         throws Exception {
@@ -1608,7 +1610,7 @@
             };
             Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
                 @Override
-                public void afterHandshake(int session, int s, int c,
+                public void afterHandshake(long session, long s, long c,
                                            Socket sock, FileDescriptor fd,
                                            SSLHandshakeCallbacks callback)
                         throws Exception {
@@ -1626,7 +1628,7 @@
         try {
             Hooks cHooks = new Hooks() {
                 @Override
-                public void afterHandshake(int session, int s, int c,
+                public void afterHandshake(long session, long s, long c,
                                            Socket sock, FileDescriptor fd,
                                            SSLHandshakeCallbacks callback)
                         throws Exception {
@@ -1636,7 +1638,7 @@
             };
             Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
                 @Override
-                public void afterHandshake(int session, int s, int c,
+                public void afterHandshake(long session, long s, long c,
                                            Socket sock, FileDescriptor fd,
                                            SSLHandshakeCallbacks callback)
                         throws Exception {
@@ -1662,8 +1664,8 @@
 
         // null FileDescriptor
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0);
                 fail();
@@ -1675,8 +1677,8 @@
 
         // null SSLHandshakeCallbacks
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0);
                 fail();
@@ -1688,8 +1690,8 @@
 
         // null byte array
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0);
                 fail();
@@ -1701,8 +1703,8 @@
 
         // handshaking not yet performed
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             try {
                 NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
                 fail();
@@ -1721,8 +1723,8 @@
 
         // also works without handshaking
         {
-            int c = NativeCrypto.SSL_CTX_new();
-            int s = NativeCrypto.SSL_new(c);
+            long c = NativeCrypto.SSL_CTX_new();
+            long s = NativeCrypto.SSL_new(c);
             NativeCrypto.SSL_interrupt(s);
             NativeCrypto.SSL_free(s);
             NativeCrypto.SSL_CTX_free(c);
@@ -1732,7 +1734,7 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1742,7 +1744,7 @@
         };
         Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
             @Override
-            public void afterHandshake(int session, final int s, int c,
+            public void afterHandshake(long session, final long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1783,8 +1785,8 @@
         NativeCrypto.SSL_shutdown(NULL, INVALID_FD, DUMMY_CB);
 
         // handshaking not yet performed
-        int c = NativeCrypto.SSL_CTX_new();
-        int s = NativeCrypto.SSL_new(c);
+        long c = NativeCrypto.SSL_CTX_new();
+        long s = NativeCrypto.SSL_new(c);
         try {
             NativeCrypto.SSL_shutdown(s, INVALID_FD, DUMMY_CB);
         } catch (SSLProtocolException expected) {
@@ -1803,7 +1805,7 @@
         } catch (NullPointerException expected) {
         }
 
-        int c = NativeCrypto.SSL_CTX_new();
+        long c = NativeCrypto.SSL_CTX_new();
         NativeCrypto.SSL_free(NativeCrypto.SSL_new(c));
         NativeCrypto.SSL_CTX_free(c);
 
@@ -1822,7 +1824,7 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1851,7 +1853,7 @@
         {
             Hooks cHooks = new Hooks() {
                 @Override
-                public void afterHandshake(int session, int s, int c,
+                public void afterHandshake(long session, long s, long c,
                                            Socket sock, FileDescriptor fd,
                                            SSLHandshakeCallbacks callback)
                         throws Exception {
@@ -1880,7 +1882,7 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                     throws Exception {
@@ -1907,7 +1909,7 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            public void afterHandshake(long session, long s, long c,
                                        Socket sock, FileDescriptor fd,
                                        SSLHandshakeCallbacks callback)
                         throws Exception {
@@ -1945,13 +1947,13 @@
 
         Hooks cHooks = new Hooks() {
             @Override
-            public void afterHandshake(int session, int s, int c,
+            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);
-                int session2 = NativeCrypto.d2i_SSL_SESSION(b);
+                long session2 = NativeCrypto.d2i_SSL_SESSION(b);
                 assertTrue(session2 != NULL);
 
                 // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840
@@ -1995,7 +1997,7 @@
     public void test_ENGINE_by_id_Failure() throws Exception {
         NativeCrypto.ENGINE_load_dynamic();
 
-        int engine = NativeCrypto.ENGINE_by_id("non-existent");
+        long engine = NativeCrypto.ENGINE_by_id("non-existent");
         if (engine != 0) {
             NativeCrypto.ENGINE_finish(engine);
             fail("should not acquire reference to non-existent engine");
@@ -2007,14 +2009,14 @@
      * immediately.
      */
     public static void loadTestEngine() throws Exception {
-        int testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
+        long testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
         if (testEngine != 0) {
             NativeCrypto.ENGINE_finish(testEngine);
             return;
         }
 
         NativeCrypto.ENGINE_load_dynamic();
-        int dynEngine = NativeCrypto.ENGINE_by_id("dynamic");
+        long dynEngine = NativeCrypto.ENGINE_by_id("dynamic");
         try {
             ClassLoader loader = NativeCryptoTest.class.getClassLoader();
 
@@ -2052,11 +2054,11 @@
     public void test_ENGINE_by_id_TestEngine() throws Exception {
         loadTestEngine();
 
-        int engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
+        long engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
         assertTrue(engine != 0);
         NativeCrypto.ENGINE_add(engine);
 
-        int pkey = NULL;
+        long pkey = NULL;
         try {
             final String rsaPem =
                       "-----BEGIN RSA PRIVATE KEY-----\n"
@@ -2126,7 +2128,7 @@
     }
 
     public void test_EVP_SignInit() throws Exception {
-        final int ctx = NativeCrypto.EVP_SignInit("RSA-SHA256");
+        final long ctx = NativeCrypto.EVP_SignInit("RSA-SHA256");
         assertTrue(ctx != NULL);
         NativeCrypto.EVP_MD_CTX_destroy(ctx);
 
@@ -2150,7 +2152,7 @@
 
         // Test getting params for the wrong kind of key.
         final byte[] seed = new byte[20];
-        int ctx = 0;
+        long ctx = 0;
         try {
             ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
             assertTrue(ctx != NULL);
@@ -2179,7 +2181,7 @@
 
         // Test getting params for the wrong kind of key.
         final byte[] seed = new byte[20];
-        int ctx = 0;
+        long ctx = 0;
         try {
             ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
             assertTrue(ctx != NULL);
@@ -2301,7 +2303,7 @@
 
         // Real key
         {
-            int ctx = 0;
+            long ctx = 0;
             try {
                 ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
                 assertTrue(ctx != NULL);
@@ -2314,7 +2316,7 @@
 
         // Real key with minimum bit size (should be 512 bits)
         {
-            int ctx = 0;
+            long ctx = 0;
             try {
                 ctx = NativeCrypto.DSA_generate_key(0, null, null, null, null);
                 assertTrue(ctx != NULL);
@@ -2327,7 +2329,7 @@
 
         // Bad DSA params.
         {
-            int ctx = 0;
+            long ctx = 0;
             try {
                 ctx = NativeCrypto.DSA_generate_key(0, null, new byte[] {}, new byte[] {},
                         new byte[] {});
@@ -2380,7 +2382,7 @@
 
     private void check_EC_GROUP(int type, String name, String pStr, String aStr, String bStr,
             String xStr, String yStr, String nStr, long hLong) throws Exception {
-        int group1 = NULL, group2 = NULL, point1 = NULL, point2 = NULL, key1 = NULL;
+        long group1 = NULL, group2 = NULL, point1 = NULL, point2 = NULL, key1 = NULL;
         try {
             group1 = NativeCrypto.EC_GROUP_new_by_curve_name(name);
             assertTrue(group1 != NULL);
@@ -2447,7 +2449,7 @@
             assertTrue(NativeCrypto.EC_GROUP_cmp(group1, group2));
 
             key1 = NativeCrypto.EC_KEY_generate_key(group1);
-            int groupTmp = NativeCrypto.EC_KEY_get0_group(key1);
+            long groupTmp = NativeCrypto.EC_KEY_get0_group(key1);
             assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group1),
                     NativeCrypto.EC_GROUP_get_curve_name(groupTmp));
 
@@ -2475,9 +2477,9 @@
     }
 
     public void test_EVP_CipherInit_ex_Null_Failure() throws Exception {
-        final int ctx = NativeCrypto.EVP_CIPHER_CTX_new();
+        final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
         try {
-            final int evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+            final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
 
             try {
                 NativeCrypto.EVP_CipherInit_ex(NULL, evpCipher, null, null, true);
@@ -2498,9 +2500,9 @@
     }
 
     public void test_EVP_CipherInit_ex_Success() throws Exception {
-        final int ctx = NativeCrypto.EVP_CIPHER_CTX_new();
+        final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
         try {
-            final int evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+            final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
             NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true);
         } finally {
             NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
@@ -2508,10 +2510,10 @@
     }
 
     public void test_EVP_CIPHER_iv_length() throws Exception {
-        int aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
+        long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
         assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb));
 
-        int aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc");
+        long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc");
         assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc));
     }
 
@@ -2525,7 +2527,7 @@
         key1 = new OpenSSLKey(NativeCrypto.DSA_generate_key(1024, null, null, null, null));
         assertTrue(key1.getPublicKey() instanceof DSAPublicKey);
 
-        int group1 = NULL;
+        long group1 = NULL;
         try {
             group1 = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
             assertTrue(group1 != NULL);
@@ -2537,4 +2539,35 @@
         }
         assertTrue(key1.getPublicKey() instanceof ECPublicKey);
     }
+
+    public void test_create_BIO_InputStream() throws Exception {
+        byte[] actual = "Test".getBytes();
+        ByteArrayInputStream is = new ByteArrayInputStream(actual);
+
+        long ctx = NativeCrypto.create_BIO_InputStream(new OpenSSLBIOInputStream(is));
+        try {
+            byte[] buffer = new byte[1024];
+            int numRead = NativeCrypto.BIO_read(ctx, buffer);
+            assertEquals(actual.length, numRead);
+            assertEquals(Arrays.toString(actual),
+                    Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead)));
+        } finally {
+            NativeCrypto.BIO_free(ctx);
+        }
+
+    }
+
+    public void test_create_BIO_OutputStream() throws Exception {
+        byte[] actual = "Test".getBytes();
+        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(ctx);
+        }
+    }
 }
diff --git a/luni/src/test/java/sun/misc/UnsafeTest.java b/luni/src/test/java/sun/misc/UnsafeTest.java
index 462d39d..48939f5 100644
--- a/luni/src/test/java/sun/misc/UnsafeTest.java
+++ b/luni/src/test/java/sun/misc/UnsafeTest.java
@@ -18,6 +18,7 @@
 
 import junit.framework.TestCase;
 
+import java.lang.reflect.Field;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 
@@ -48,4 +49,25 @@
         } catch (SecurityException expected) {
         }
     }
+
+    private class AllocateInstanceTestClass {
+        public int i = 123;
+        public String s = "hello";
+        public Object getThis() { return AllocateInstanceTestClass.this; }
+    }
+
+    private static Unsafe getUnsafe() throws Exception {
+        Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
+        Field f = unsafeClass.getDeclaredField("theUnsafe");
+        f.setAccessible(true);
+        return (Unsafe) f.get(null);
+    }
+
+    public void test_allocateInstance() throws Exception {
+        AllocateInstanceTestClass i = (AllocateInstanceTestClass)
+                getUnsafe().allocateInstance(AllocateInstanceTestClass.class);
+        assertEquals(0, i.i);
+        assertEquals(null, i.s);
+        assertEquals(i, i.getThis());
+    }
 }
diff --git a/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java b/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
index 996c94d..e937db9 100644
--- a/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
+++ b/luni/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
@@ -310,10 +310,10 @@
             // Test can not be applied.
             return;
         }
-        Date[] date = new Date[4];
+        Date[] date = new Date[8];
         Calendar calendar = Calendar.getInstance();
         for (int i = 0; i < date.length; i++) {
-            calendar.set(i * 50, Calendar.JANUARY, 1);
+            calendar.set(i * 500, Calendar.JANUARY, 1);
             date[i] = calendar.getTime();
         }
         Date nb_date = tbt_cert.getNotBefore();
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-dirname.der b/support/src/test/java/tests/resources/x509/cert-alt-dirname.der
index 69e4033..e96fc33 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-dirname.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-dirname.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-dns.der b/support/src/test/java/tests/resources/x509/cert-alt-dns.der
index d9b1e87..7f245f1 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-dns.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-dns.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-email.der b/support/src/test/java/tests/resources/x509/cert-alt-email.der
index f10bc43..94db3e9 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-email.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-email.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-none.der b/support/src/test/java/tests/resources/x509/cert-alt-none.der
index fbf543a..6b7ab1d 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-none.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-none.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-other.der b/support/src/test/java/tests/resources/x509/cert-alt-other.der
index 7a06ff7..fb66368 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-other.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-other.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-rid.der b/support/src/test/java/tests/resources/x509/cert-alt-rid.der
index 242a49d..6773b4f 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-rid.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-rid.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-alt-uri.der b/support/src/test/java/tests/resources/x509/cert-alt-uri.der
index 5a9b882..c21ae4c 100644
--- a/support/src/test/java/tests/resources/x509/cert-alt-uri.der
+++ b/support/src/test/java/tests/resources/x509/cert-alt-uri.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-ca.der b/support/src/test/java/tests/resources/x509/cert-ca.der
index 7c787ea..0570113 100644
--- a/support/src/test/java/tests/resources/x509/cert-ca.der
+++ b/support/src/test/java/tests/resources/x509/cert-ca.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der b/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der
index 2886091..c964a0b 100644
--- a/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der
+++ b/support/src/test/java/tests/resources/x509/cert-caWithPathLen.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-crl-ca.der b/support/src/test/java/tests/resources/x509/cert-crl-ca.der
new file mode 100644
index 0000000..d58022c
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/cert-crl-ca.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-dsa.der b/support/src/test/java/tests/resources/x509/cert-dsa.der
index d17c4ce..09f83eb 100644
--- a/support/src/test/java/tests/resources/x509/cert-dsa.der
+++ b/support/src/test/java/tests/resources/x509/cert-dsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-ec.der b/support/src/test/java/tests/resources/x509/cert-ec.der
index 07bdf7a..ca746cc 100644
--- a/support/src/test/java/tests/resources/x509/cert-ec.der
+++ b/support/src/test/java/tests/resources/x509/cert-ec.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der b/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der
index ac36013..33673aa 100644
--- a/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der
+++ b/support/src/test/java/tests/resources/x509/cert-extendedKeyUsage.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-ipv6.der b/support/src/test/java/tests/resources/x509/cert-ipv6.der
index 11b440e..0e6c5ed 100644
--- a/support/src/test/java/tests/resources/x509/cert-ipv6.der
+++ b/support/src/test/java/tests/resources/x509/cert-ipv6.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der b/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der
index cf5e0f1..1d5fdea 100644
--- a/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der
+++ b/support/src/test/java/tests/resources/x509/cert-keyUsage-extraLong.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt b/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt
index d661409..cbd8632 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-dates.txt
@@ -1,2 +1,2 @@
-notBefore=Jan  2 00:03:12 2013 GMT
-notAfter=Dec 31 00:03:12 2022 GMT
+notBefore=Mar  6 00:42:06 2013 GMT
+notAfter=Mar  4 00:42:06 2023 GMT
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der b/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der
index ab9f3db..4fb898b 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-pubkey.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt b/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt
index ec3cebd..07ed8ec 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-serial.txt
@@ -1 +1 @@
-serial=B96143E1D6F31E6F
+serial=BFC278DBB294AC42
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-sig.der b/support/src/test/java/tests/resources/x509/cert-rsa-sig.der
index 62979ee..54361b5 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-sig.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-sig.der
@@ -1 +1 @@
-¨Ñ´Å¯Kܤȁ¿¤Ï±ŸØÍ(¥¨ö˜"‡š,/•ŠIöL.‘1éå	•âãø,¿xÒ»T•K$}‡˜xöy‹ÄÞËi©èiŒ.OŠOðÂÄM.m>×Ë»VbJQö?Ô¥‡¿@·ò×(>„ë_xÑGMÅö…£šz%
\ No newline at end of file
+7ÚáiøopŒ¡_%5óÐý:™%تþ"©ãRëÄǜ—Œo‘ǁ޴òª@àçHēòŒjÚñQÌO§ÑÜA3e“ÏC£ëB ¿±`H¿p÷›Ë>†é.5²ßï€Ä'ÉqÖk{ãäCÕ¾æºqšPl-Ÿ
\ No newline at end of file
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der b/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der
index 5ec2858..cbe67b7 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa-tbs.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-rsa.der b/support/src/test/java/tests/resources/x509/cert-rsa.der
index 23d7cc8..e27787b 100644
--- a/support/src/test/java/tests/resources/x509/cert-rsa.der
+++ b/support/src/test/java/tests/resources/x509/cert-rsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-sigopt.der b/support/src/test/java/tests/resources/x509/cert-sigopt.der
new file mode 100644
index 0000000..d808282
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/cert-sigopt.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-unsupported.der b/support/src/test/java/tests/resources/x509/cert-unsupported.der
index 0239b68..c0db35a 100644
--- a/support/src/test/java/tests/resources/x509/cert-unsupported.der
+++ b/support/src/test/java/tests/resources/x509/cert-unsupported.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der b/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der
index c29c933..e5ec37e 100644
--- a/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der
+++ b/support/src/test/java/tests/resources/x509/cert-userWithPathLen.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/certs-pk7.der b/support/src/test/java/tests/resources/x509/certs-pk7.der
index 327d072..f7f8abc 100644
--- a/support/src/test/java/tests/resources/x509/certs-pk7.der
+++ b/support/src/test/java/tests/resources/x509/certs-pk7.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/certs-pk7.pem b/support/src/test/java/tests/resources/x509/certs-pk7.pem
index acdbefc..feef173 100644
--- a/support/src/test/java/tests/resources/x509/certs-pk7.pem
+++ b/support/src/test/java/tests/resources/x509/certs-pk7.pem
@@ -1,19 +1,19 @@
 -----BEGIN PKCS7-----
-MIIIBgYJKoZIhvcNAQcCoIIH9zCCB/MCAQExADALBgkqhkiG9w0BBwGgggfZMIIE
-vDCCBCWgAwIBAgIJALlhQ+HW8x5vMA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNVBAYT
+MIIICAYJKoZIhvcNAQcCoIIH+TCCB/UCAQExADALBgkqhkiG9w0BBwGgggfbMIIE
+vDCCBCWgAwIBAgIJAL/CeNuylKxCMA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNVBAYT
 AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8xFzAV
-BgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTMwMTAy
-MDAwMzEyWhcNMjIxMjMxMDAwMzEyWjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
+BgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTMwMzA2
+MDA0MjA2WhcNMjMwMzA0MDA0MjA2WjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
 Q2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5pdXMu
 Y29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQC5z1kj/9icpVyMG9YYEk1iVeU6Ik4+xpQmZCiQaA20wiZBw3it85VdgvCq
-bB0CHZ5TKnfxpkAdfbXpGqwynwGKGnKGitH1ol9e+vP560Uwe1y1m+d1vG9S5oHg
-PITk7LOdZDPfzxRpdRbtG+AotiTjwXcIRilb41zAQdlL+V6XFQIDAQABo4ICfDCC
-AngwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFPZXOE58APjzbNY3
-hYjPdgUWlauhMIGSBgNVHSMEgYowgYeAFPZXOE58APjzbNY3hYjPdgUWlauhoWSk
+iQKBgQCxtuZhs1g1NvAYRkbdyDwNh+KLxc/GWDC+reFz9bO8NDmINjLVoe3Pu5S1
+ONXEgpkvSj6v8a9S7FgSShautZd6G1fm6XFB2Nn+eUjN56o86xNHMiEOG+QCTRRu
+pAkZaa3W1WEh+zqq2x0X9JlYY/xpDmP3voGC6rOcfnOoyl/fPQIDAQABo4ICfDCC
+AngwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFL8PXLxMk0+9Upkm
+yqlonexUHoq4MIGSBgNVHSMEgYowgYeAFL8PXLxMk0+9UpkmyqlonexUHoq4oWSk
 YjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJ
 U2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UECxMGTmV0
-T3BzggkAuWFD4dbzHm8wHgYJYIZIAYb4QgENBBEWD1guNTA5IFVuaXQgVGVzdDCB
+T3BzggkAv8J427KUrEIwHgYJYIZIAYb4QgENBBEWD1guNTA5IFVuaXQgVGVzdDCB
 wwYDVR0RBIG7MIG4oA4GAyoDBKAHDAV0ZXN0MYEQeDUwOUBleGFtcGxlLmNvbYIQ
 eDUwOS5leGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1Bd2Vz
 b21lIER1ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UEAxQF4oiG
@@ -22,24 +22,24 @@
 LmNvbYIQeDUwOS5leGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQK
 Ew1Bd2Vzb21lIER1ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UE
 AxQF4oiGxpKGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vP3E9YXdlc29tZW5lc3OH
-BMCoAAGIAyoDBDANBgkqhkiG9w0BAQUFAAOBgQCo0bTFr0vcFaTIgb+kz48OsQSf
-2M0oBRulqPaYIoeaLC+Vikn2H0wukTHp5QkHleLj+Cy/eNK7BVSVSyR9h5h4B/Z5
-FovE3stpqehpgYwuT4pP8AvCxE0uF20+18u7VmJKUX/2P9Slh78bQLfy1yg+hOtf
-EXjRR03F9oWjmnoFJTCCAxUwggLVoAMCAQICCQCfC5LfnVl0OjAJBgcqhkjOOAQD
+BMCoAAGIAyoDBDANBgkqhkiG9w0BAQUFAAOBgQAaN9rhafhvcIyhXyUVNfPQ/Tod
+mSV/2Kr+IgfCjanjUusQxATHnJeMb5HHgd608hmqQODnHUjEk/KMatrxUcxPp9Hc
+QTNlBBWTz0Oj60KgAb+xYEi/cBn3Cxubyxo+hgjpLhc1st/vgMQnyXHWa3vjFuRD
+1b7munGaUBNsFi0BnzCCAxcwggLVoAMCAQICCQDoI9YBeCh6fzAJBgcqhkjOOAQD
 MGAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlT
 YW4gTWF0ZW8xFzAVBgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRP
-cHMwHhcNMTMwMTAyMDAwMzEzWhcNMTMwMjAxMDAwMzEzWjBgMQswCQYDVQQGEwJV
+cHMwHhcNMTMwMzA2MDA0MjA4WhcNMTMwNDA1MDA0MjA4WjBgMQswCQYDVQQGEwJV
 UzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcwFQYD
 VQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIIBtjCCASsGByqG
-SM44BAEwggEeAoGBAImYpx8uzo8B+Q3hxZN46+A80MRrbA18klMPdOVBoMInEe2w
-cxZatUOzqzxqb5V3Qd7lc9wYnTVy3BvDGbVxZ22J8GdtbJ046ZeoZkaIavohekr0
-87VGczxIjO5jxCcTRpFVjB5TPR8m6UlojxRo5y4K0yQ2ciV9lWxXpyBUAHyFAhUA
-7hFB9CwOX6cnV0Ehn6n9mZwsf4sCgYBcX2t572fhu3oWasXVbkA90GcN4RsNEHbL
-iFVk95r0LViFyrKvuYTCEt6J1SVBX+PZ+wU5h0SkI/Ya2RTo0KWkJBkFAcEy36e8
-lJCJMOlBQZwfWt2F1vTgnFPWpBLH2GuYwIB2qEBN9ehLvyPGIbozmSuQ5rE++jK1
-yUzcO9eg6AOBhAACgYAd7BJdvhiNsLKw8RcloBUYYB5jZeQYzOlR8xONopRWzcQX
-nmRug0Y/Zk6gCkGCnZoWYViB2x5TbkQY3l9zT6WT8sfRVoidUUUyNRpgXG4pydSj
-XOCEqD1WS/XMx9VsYsjrkq/6zBxDzcputrYdkS45Yiua+ruyyNwXaghPyKQssqMa
-MBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCADcwCQYHKoZIzjgEAwMvADAsAhRG6gnv
-MAvWYlUjXdBOXVIqUbIelQIUB7T9ah0mDUbOmjJvsDqX2ioJsqmhADEA
+SM44BAEwggEeAoGBAJSFHSZWbyn0lJm3v2VeFoVNPSCM4akS+YxZ8NyYjEwl58aC
+YW/StslxMQeQvow++1bzM2GMMq6i29fSy/y8w/kNgua6mC+H1rkoAPy1zr/qiYD5
+4LgVm53sjur9HZaSP5h5U1u0f7uYrnxd5r8ns/pNJ1HnVdPzbFEgBU0LRjUtAhUA
+vcuQ5p9rxRPOegf2e3DP8dgc+LcCgYAJ2OG3B4JdOOowJidNeIFL2E86nQ9YqY+y
+Qn760g3L23PX+tjJag1vJfvS2pwU1X0w3YwvdoPBFLwBfy0vEwEFqR70iJC/E2st
+3geZqbPjZWkoUS6Rq3++JsKoLxYMLns/2U9/vpl/KF2053Xa3QvTyd0Dxs1o3T0m
+g2rhP8FldAOBhAACgYAYB+w4767ypZaw1RYNLWWl+UFe4L2cfsZKGM5Z8flqcJke
+y5fhk2VPRFa/YXUEYuYkganGQFNqrv2tlLalpcqRX00BXLFGx2WFrhpY1u2YYnDV
+5xGFpLH4MV0Nvw0iDMD+q+Wo2sH5MgUbCmnlwtZ8xhQYF3M2Cyb4fnm+tQsNnKMa
+MBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCADcwCQYHKoZIzjgEAwMxADAuAhUAt3Mt
+TCmXGAdJ8gGtrg/BfAQ/lPoCFQCMlyzUwS31EtfnLSu/SGFR6xxTMqEAMQA=
 -----END PKCS7-----
diff --git a/support/src/test/java/tests/resources/x509/certs.der b/support/src/test/java/tests/resources/x509/certs.der
index 89585a6..d454c5b 100644
--- a/support/src/test/java/tests/resources/x509/certs.der
+++ b/support/src/test/java/tests/resources/x509/certs.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/certs.pem b/support/src/test/java/tests/resources/x509/certs.pem
index 515fbb7..448227e 100644
--- a/support/src/test/java/tests/resources/x509/certs.pem
+++ b/support/src/test/java/tests/resources/x509/certs.pem
@@ -1,18 +1,18 @@
 -----BEGIN CERTIFICATE-----
-MIIEvDCCBCWgAwIBAgIJALlhQ+HW8x5vMA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNV
+MIIEvDCCBCWgAwIBAgIJAL/CeNuylKxCMA0GCSqGSIb3DQEBBQUAMGAxCzAJBgNV
 BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8x
 FzAVBgNVBAoTDkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwHhcNMTMw
-MTAyMDAwMzEyWhcNMjIxMjMxMDAwMzEyWjBgMQswCQYDVQQGEwJVUzETMBEGA1UE
+MzA2MDA0MjA2WhcNMjMwMzA0MDA0MjA2WjBgMQswCQYDVQQGEwJVUzETMBEGA1UE
 CBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5p
 dXMuY29tIEluYzEPMA0GA1UECxMGTmV0T3BzMIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQC5z1kj/9icpVyMG9YYEk1iVeU6Ik4+xpQmZCiQaA20wiZBw3it85Vd
-gvCqbB0CHZ5TKnfxpkAdfbXpGqwynwGKGnKGitH1ol9e+vP560Uwe1y1m+d1vG9S
-5oHgPITk7LOdZDPfzxRpdRbtG+AotiTjwXcIRilb41zAQdlL+V6XFQIDAQABo4IC
-fDCCAngwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFPZXOE58APjz
-bNY3hYjPdgUWlauhMIGSBgNVHSMEgYowgYeAFPZXOE58APjzbNY3hYjPdgUWlauh
+ADCBiQKBgQCxtuZhs1g1NvAYRkbdyDwNh+KLxc/GWDC+reFz9bO8NDmINjLVoe3P
+u5S1ONXEgpkvSj6v8a9S7FgSShautZd6G1fm6XFB2Nn+eUjN56o86xNHMiEOG+QC
+TRRupAkZaa3W1WEh+zqq2x0X9JlYY/xpDmP3voGC6rOcfnOoyl/fPQIDAQABo4IC
+fDCCAngwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFL8PXLxMk0+9
+UpkmyqlonexUHoq4MIGSBgNVHSMEgYowgYeAFL8PXLxMk0+9UpkmyqlonexUHoq4
 oWSkYjBgMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UE
 BxMJU2FuIE1hdGVvMRcwFQYDVQQKEw5HZW5pdXMuY29tIEluYzEPMA0GA1UECxMG
-TmV0T3BzggkAuWFD4dbzHm8wHgYJYIZIAYb4QgENBBEWD1guNTA5IFVuaXQgVGVz
+TmV0T3BzggkAv8J427KUrEIwHgYJYIZIAYb4QgENBBEWD1guNTA5IFVuaXQgVGVz
 dDCBwwYDVR0RBIG7MIG4oA4GAyoDBKAHDAV0ZXN0MYEQeDUwOUBleGFtcGxlLmNv
 bYIQeDUwOS5leGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1B
 d2Vzb21lIER1ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwGA1UEAxQF
@@ -21,27 +21,27 @@
 cGxlLmNvbYIQeDUwOS5leGFtcGxlLmNvbaRQME4xCzAJBgNVBAYTAlVTMRYwFAYD
 VQQKEw1Bd2Vzb21lIER1ZGVzMRcwFQYDVQQLFA7DnGJlciBGcsOuZW5kczEOMAwG
 A1UEAxQF4oiGxpKGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vP3E9YXdlc29tZW5l
-c3OHBMCoAAGIAyoDBDANBgkqhkiG9w0BAQUFAAOBgQCo0bTFr0vcFaTIgb+kz48O
-sQSf2M0oBRulqPaYIoeaLC+Vikn2H0wukTHp5QkHleLj+Cy/eNK7BVSVSyR9h5h4
-B/Z5FovE3stpqehpgYwuT4pP8AvCxE0uF20+18u7VmJKUX/2P9Slh78bQLfy1yg+
-hOtfEXjRR03F9oWjmnoFJQ==
+c3OHBMCoAAGIAyoDBDANBgkqhkiG9w0BAQUFAAOBgQAaN9rhafhvcIyhXyUVNfPQ
+/TodmSV/2Kr+IgfCjanjUusQxATHnJeMb5HHgd608hmqQODnHUjEk/KMatrxUcxP
+p9HcQTNlBBWTz0Oj60KgAb+xYEi/cBn3Cxubyxo+hgjpLhc1st/vgMQnyXHWa3vj
+FuRD1b7munGaUBNsFi0Bnw==
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDFTCCAtWgAwIBAgIJAJ8Lkt+dWXQ6MAkGByqGSM44BAMwYDELMAkGA1UEBhMC
+MIIDFzCCAtWgAwIBAgIJAOgj1gF4KHp/MAkGByqGSM44BAMwYDELMAkGA1UEBhMC
 VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVNhbiBNYXRlbzEXMBUG
-A1UEChMOR2VuaXVzLmNvbSBJbmMxDzANBgNVBAsTBk5ldE9wczAeFw0xMzAxMDIw
-MDAzMTNaFw0xMzAyMDEwMDAzMTNaMGAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
+A1UEChMOR2VuaXVzLmNvbSBJbmMxDzANBgNVBAsTBk5ldE9wczAeFw0xMzAzMDYw
+MDQyMDhaFw0xMzA0MDUwMDQyMDhaMGAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
 YWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8xFzAVBgNVBAoTDkdlbml1cy5j
 b20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMwggG2MIIBKwYHKoZIzjgEATCCAR4CgYEA
-iZinHy7OjwH5DeHFk3jr4DzQxGtsDXySUw905UGgwicR7bBzFlq1Q7OrPGpvlXdB
-3uVz3BidNXLcG8MZtXFnbYnwZ21snTjpl6hmRohq+iF6SvTztUZzPEiM7mPEJxNG
-kVWMHlM9HybpSWiPFGjnLgrTJDZyJX2VbFenIFQAfIUCFQDuEUH0LA5fpydXQSGf
-qf2ZnCx/iwKBgFxfa3nvZ+G7ehZqxdVuQD3QZw3hGw0QdsuIVWT3mvQtWIXKsq+5
-hMIS3onVJUFf49n7BTmHRKQj9hrZFOjQpaQkGQUBwTLfp7yUkIkw6UFBnB9a3YXW
-9OCcU9akEsfYa5jAgHaoQE316Eu/I8YhujOZK5DmsT76MrXJTNw716DoA4GEAAKB
-gB3sEl2+GI2wsrDxFyWgFRhgHmNl5BjM6VHzE42ilFbNxBeeZG6DRj9mTqAKQYKd
-mhZhWIHbHlNuRBjeX3NPpZPyx9FWiJ1RRTI1GmBcbinJ1KNc4ISoPVZL9czH1Wxi
-yOuSr/rMHEPNym62th2RLjliK5r6u7LI3BdqCE/IpCyyoxowGDAJBgNVHRMEAjAA
-MAsGA1UdDwQEAwIANzAJBgcqhkjOOAQDAy8AMCwCFEbqCe8wC9ZiVSNd0E5dUipR
-sh6VAhQHtP1qHSYNRs6aMm+wOpfaKgmyqQ==
+lIUdJlZvKfSUmbe/ZV4WhU09IIzhqRL5jFnw3JiMTCXnxoJhb9K2yXExB5C+jD77
+VvMzYYwyrqLb19LL/LzD+Q2C5rqYL4fWuSgA/LXOv+qJgPnguBWbneyO6v0dlpI/
+mHlTW7R/u5iufF3mvyez+k0nUedV0/NsUSAFTQtGNS0CFQC9y5Dmn2vFE856B/Z7
+cM/x2Bz4twKBgAnY4bcHgl046jAmJ014gUvYTzqdD1ipj7JCfvrSDcvbc9f62Mlq
+DW8l+9LanBTVfTDdjC92g8EUvAF/LS8TAQWpHvSIkL8Tay3eB5mps+NlaShRLpGr
+f74mwqgvFgwuez/ZT3++mX8oXbTnddrdC9PJ3QPGzWjdPSaDauE/wWV0A4GEAAKB
+gBgH7DjvrvKllrDVFg0tZaX5QV7gvZx+xkoYzlnx+WpwmR7Ll+GTZU9EVr9hdQRi
+5iSBqcZAU2qu/a2UtqWlypFfTQFcsUbHZYWuGljW7ZhicNXnEYWksfgxXQ2/DSIM
+wP6r5ajawfkyBRsKaeXC1nzGFBgXczYLJvh+eb61Cw2coxowGDAJBgNVHRMEAjAA
+MAsGA1UdDwQEAwIANzAJBgcqhkjOOAQDAzEAMC4CFQC3cy1MKZcYB0nyAa2uD8F8
+BD+U+gIVAIyXLNTBLfUS1+ctK79IYVHrHFMy
 -----END CERTIFICATE-----
diff --git a/support/src/test/java/tests/resources/x509/create.sh b/support/src/test/java/tests/resources/x509/create.sh
index dfab42e..8362fab 100755
--- a/support/src/test/java/tests/resources/x509/create.sh
+++ b/support/src/test/java/tests/resources/x509/create.sh
@@ -61,6 +61,8 @@
 
 openssl req -config ${DIR}/default.cnf -new -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions unsupported_cert -req -signkey privkey.pem -outform d > cert-unsupported.der
 
+openssl req -config ${DIR}/default.cnf -new -nodes -batch -config ${DIR}/default.cnf -extensions usr_cert -x509 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:1 -outform d > cert-sigopt.der
+
 openssl dsaparam -out dsaparam.pem 1024
 openssl req -config ${DIR}/default.cnf -newkey dsa:dsaparam.pem -keyout dsapriv.pem -nodes -batch | openssl x509 -extfile ${DIR}/default.cnf -extensions keyUsage_cert -req -signkey dsapriv.pem -outform d > cert-dsa.der
 rm -f dsaparam.pem
@@ -76,6 +78,10 @@
 touch /tmp/ca/index.txt.attr
 echo "01" > /tmp/ca/serial
 openssl req -new -nodes -batch -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650 -config default.cnf
+openssl x509 -in cacert.pem -outform d > cert-crl-ca.der
+
+openssl ca -gencrl -crlhours 70 -keyfile cakey.pem -cert cacert.pem -out crl-empty.pem -config default.cnf
+openssl crl -in crl-empty.pem -outform d -out crl-empty.der
 
 openssl x509 -inform d -in cert-rsa.der -out cert-rsa.pem
 openssl ca -revoke cert-rsa.pem -keyfile cakey.pem -cert cacert.pem -config default.cnf
@@ -89,7 +95,9 @@
 openssl x509 -inform d -in cert-dsa.der -out cert-dsa.pem
 openssl ca -revoke cert-dsa.pem -keyfile cakey.pem -cert cacert.pem -crl_reason cessationOfOperation -extensions unsupported_cert -config default.cnf
 openssl ca -gencrl -crldays 30 -keyfile cakey.pem -cert cacert.pem -out crl-rsa-dsa.pem -config default.cnf
+openssl ca -gencrl -crldays 30 -keyfile cakey.pem -cert cacert.pem -out crl-rsa-dsa-sigopt.pem -config default.cnf -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:1
 openssl crl -in crl-rsa-dsa.pem -outform d -out crl-rsa-dsa.der
+openssl crl -in crl-rsa-dsa-sigopt.pem -outform d -out crl-rsa-dsa-sigopt.der
 
 # Unsupported extensions
 openssl ca -gencrl -crlexts unsupported_cert -keyfile cakey.pem -cert cacert.pem -out crl-unsupported.pem -config default.cnf
@@ -98,7 +106,7 @@
 openssl crl -inform d -in crl-rsa.der -noout -lastupdate -nextupdate > crl-rsa-dates.txt
 openssl crl -inform d -in crl-rsa-dsa.der -noout -lastupdate -nextupdate > crl-rsa-dsa-dates.txt
 
-rm -f cert-rsa.pem cert-dsa.pem cacert.pem cakey.pem crl-rsa.pem crl-rsa-dsa.pem crl-unsupported.pem
+rm -f cert-rsa.pem cert-dsa.pem cacert.pem cakey.pem crl-rsa.pem crl-rsa-dsa.pem crl-unsupported.pem crl-empty.pem
 rm -rf /tmp/ca
 
 rm -f privkey.pem
diff --git a/support/src/test/java/tests/resources/x509/crl-empty.der b/support/src/test/java/tests/resources/x509/crl-empty.der
new file mode 100644
index 0000000..c5d21a4
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/crl-empty.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt b/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt
index 50e48f2..4669357 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dates.txt
@@ -1,2 +1,2 @@
-lastUpdate=Jan  2 00:03:13 2013 GMT
-nextUpdate=Jan  4 22:03:13 2013 GMT
+lastUpdate=Mar  6 00:42:08 2013 GMT
+nextUpdate=Mar  8 22:42:08 2013 GMT
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt
index 9976096..7700c7e 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-dates.txt
@@ -1,2 +1,2 @@
-lastUpdate=Jan  2 00:03:13 2013 GMT
-nextUpdate=Feb  1 00:03:13 2013 GMT
+lastUpdate=Mar  6 00:42:08 2013 GMT
+nextUpdate=Apr  5 00:42:08 2013 GMT
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der
new file mode 100644
index 0000000..ec83979
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem
new file mode 100644
index 0000000..87531a2
--- /dev/null
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa-sigopt.pem
@@ -0,0 +1,10 @@
+-----BEGIN X509 CRL-----
+MIIBejCB3wIBATASBgkqhkiG9w0BAQowBaIDAgEBMGAxCzAJBgNVBAYTAlVTMRMw
+EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTYW4gTWF0ZW8xFzAVBgNVBAoT
+Dkdlbml1cy5jb20gSW5jMQ8wDQYDVQQLEwZOZXRPcHMXDTEzMDMwNjAwNDIwOFoX
+DTEzMDQwNTAwNDIwOFowRjAaAgkAv8J427KUrEIXDTEzMDMwNjAwNDIwOFowKAIJ
+AOgj1gF4KHp/Fw0xMzAzMDYwMDQyMDhaMAwwCgYDVR0VBAMKAQUwEgYJKoZIhvcN
+AQEKMAWiAwIBAQOBgQBDETj4knxhTVoHhpHOAwskEfJLk0i5jW6iSn7nJ62ASlwj
+lXjpgIbEkohn6AkzLMiHXTzZDWu0iEiPwNK17RKlxWAiqVoH0igL50Luc6rNcsit
++RNnINYIN67JSkLfCxW2iWSDSONRTnbwCo1/XdcpoUFcNkwy5qDWJvcHdjgtGg==
+-----END X509 CRL-----
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der b/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der
index 9282b30..32366fa 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-dsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-sig.der b/support/src/test/java/tests/resources/x509/crl-rsa-sig.der
index f6ebf4f..80c915b 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-sig.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-sig.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der b/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der
index 679427d..c444c3a 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa-tbs.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-rsa.der b/support/src/test/java/tests/resources/x509/crl-rsa.der
index 994f1a8..bde1720 100644
--- a/support/src/test/java/tests/resources/x509/crl-rsa.der
+++ b/support/src/test/java/tests/resources/x509/crl-rsa.der
Binary files differ
diff --git a/support/src/test/java/tests/resources/x509/crl-unsupported.der b/support/src/test/java/tests/resources/x509/crl-unsupported.der
index 15eef95..19ffc9c 100644
--- a/support/src/test/java/tests/resources/x509/crl-unsupported.der
+++ b/support/src/test/java/tests/resources/x509/crl-unsupported.der
Binary files differ