-
-
Save anonymous/cea075b7a70abfd7359b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 667914386d177bf8eb71fdaef688a75b361ee9c9 | |
Merge: a08c6d2 507c4a2 | |
Author: Koushik Dutta <[email protected]> | |
Date: Sun Jun 29 11:36:10 2014 -0700 | |
WIP on master: a08c6d2 DO NOT SUBMIT: Various fixes in OpenSSLEngineImpl. | |
diff --cc src/main/java/org/conscrypt/NativeCrypto.java | |
index a6dfd34,a6dfd34..5e728fa | |
--- a/src/main/java/org/conscrypt/NativeCrypto.java | |
+++ b/src/main/java/org/conscrypt/NativeCrypto.java | |
@@@ -20,6 -20,6 +20,7 @@@ import java.io.FileDescriptor | |
import java.io.IOException; | |
import java.io.OutputStream; | |
import java.net.SocketTimeoutException; | |
++import java.nio.ByteBuffer; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.PrivateKey; | |
@@@ -1187,7 -1187,7 +1188,7 @@@ public final class NativeCrypto | |
public static native int SSL_read_BIO(long sslNativePointer, | |
byte[] dest, | |
-- long sourceBioRef, | |
++ ByteBuffer buffer, | |
long sinkBioRef, | |
SSLHandshakeCallbacks shc) | |
throws IOException; | |
diff --cc src/main/java/org/conscrypt/OpenSSLEngineImpl.java | |
index f4df6ad,f4df6ad..32988b5 | |
--- a/src/main/java/org/conscrypt/OpenSSLEngineImpl.java | |
+++ b/src/main/java/org/conscrypt/OpenSSLEngineImpl.java | |
@@@ -16,6 -16,6 +16,8 @@@ | |
package org.conscrypt; | |
++import android.util.Log; | |
++ | |
import java.io.IOException; | |
import java.nio.ByteBuffer; | |
import java.nio.ReadOnlyBufferException; | |
@@@ -383,15 -383,15 +385,17 @@@ public class OpenSSLEngineImpl extends | |
} else if (dsts == null) { | |
throw new IllegalArgumentException("dsts == null"); | |
} | |
-- for (int i = offset; i < length; i++) { | |
-- ByteBuffer dst = dsts[i]; | |
++ checkIndex(dsts.length, offset, length); | |
++ int dstRemaining = 0; | |
++ for (int i = 0; i < length; i++) { | |
++ ByteBuffer dst = dsts[offset + i]; | |
if (dst == null) { | |
throw new IllegalArgumentException("one of the dst == null"); | |
} else if (dst.isReadOnly()) { | |
throw new ReadOnlyBufferException(); | |
} | |
++ dstRemaining += dst.remaining(); | |
} | |
-- checkIndex(dsts.length, offset, length); | |
synchronized (stateLock) { | |
// If the inbound direction is closed. we can't send anymore. | |
@@@ -431,39 -431,39 +435,36 @@@ | |
return new SSLEngineResult(Status.OK, handshakeStatus, 0, 0); | |
} | |
++ if (dstRemaining == 0) { | |
++ return new SSLEngineResult(Status.BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0); | |
++ } | |
++ | |
++ ByteBuffer srcDuplicate = src.duplicate(); | |
try { | |
-- ByteBuffer buffer = mBuffer; | |
-- if (buffer == null) { | |
-- buffer = ByteBuffer.allocate(8192); | |
-- buffer.position(buffer.capacity()); | |
-- mBuffer = buffer; | |
-- } | |
++ int positionBeforeRead = srcDuplicate.position(); | |
++ int produced = 0; | |
++ for (int i = 0; i < length; i++) { | |
++ ByteBuffer dst = dsts[offset + i]; | |
++ ByteBuffer arrayDst = dst; | |
++ if (dst.isDirect() || dst.arrayOffset() != 0 || dst.position() != 0 || dst.limit() != dst.capacity()) { | |
++ arrayDst = ByteBuffer.allocate(dst.remaining()); | |
++ } | |
-- int consumed; | |
-- if (!buffer.hasRemaining()) { | |
-- ByteBuffer srcDuplicate = src.duplicate(); | |
-- OpenSSLBIOSource source = OpenSSLBIOSource.wrap(srcDuplicate); | |
-- try { | |
-- /* | |
-- * We can't just use .mark() here because the caller might be | |
-- * using it. | |
-- */ | |
-- int positionBeforeRead = srcDuplicate.position(); | |
-- int internalProduced = NativeCrypto.SSL_read_BIO(sslNativePointer, buffer.array(), source.getContext(), | |
-- localToRemoteSink.getContext(), this); | |
-- buffer.clear(); | |
-- buffer.limit(internalProduced); | |
-- consumed = srcDuplicate.position() - positionBeforeRead; | |
-- } finally { | |
-- source.release(); | |
++ int internalProduced = NativeCrypto.SSL_read_BIO(sslNativePointer, arrayDst.array(), srcDuplicate, | |
++ localToRemoteSink.getContext(), this); | |
++ if (internalProduced <= 0) { | |
++ Log.i("CONSCRYPT READER: ", "" + internalProduced); | |
++ continue; | |
++ } | |
++ arrayDst.position(arrayDst.position() + internalProduced); | |
++ produced += internalProduced; | |
++ if (dst != arrayDst) { | |
++ arrayDst.flip(); | |
++ dst.put(arrayDst); | |
} | |
-- src.position(srcDuplicate.position()); | |
-- } | |
-- else { | |
-- consumed = 0; | |
} | |
-- | |
-- int produced = writeByteBufferToByteBuffers(buffer, dsts); | |
++ int consumed = srcDuplicate.position() - positionBeforeRead; | |
++ src.position(srcDuplicate.position()); | |
return new SSLEngineResult(Status.OK, getHandshakeStatus(), consumed, produced); | |
} catch (IOException e) { | |
throw new SSLException(e); | |
@@@ -564,13 -564,13 +565,16 @@@ | |
int toWrite = Math.min(sink.available(), dst.remaining()); | |
dst.put(sink.toByteArray(), sink.position(), toWrite); | |
sink.skip(toWrite); | |
++ if (sink.available() > 0) | |
++ Log.i("CONSCRYPT", "~~~~ DATA STILL IN SINK"); | |
return toWrite; | |
} | |
-- private int writeByteBufferToByteBuffers(ByteBuffer buffer, ByteBuffer[] dsts) | |
++ private int writeByteBufferToByteBuffers(ByteBuffer buffer, ByteBuffer[] dsts, int offset, int length) | |
throws SSLException { | |
int totalRead = 0; | |
-- for (ByteBuffer dst: dsts) { | |
++ for (int i = 0; i < length; i++) { | |
++ ByteBuffer dst = dsts[offset + i]; | |
if (!buffer.hasRemaining()) { | |
return totalRead; | |
} | |
diff --cc src/main/native/org_conscrypt_NativeCrypto.cpp | |
index e3d0f98,e3d0f98..6a58f28 | |
--- a/src/main/native/org_conscrypt_NativeCrypto.cpp | |
+++ b/src/main/native/org_conscrypt_NativeCrypto.cpp | |
@@@ -149,6 -149,6 +149,11 @@@ static jmethodID integer_valueOfMethod | |
static jmethodID openSslInputStream_readLineMethod; | |
static jmethodID outputStream_writeMethod; | |
static jmethodID outputStream_flushMethod; | |
++static jmethodID byteBuffer_remaining; | |
++static jmethodID byteBuffer_get_position; | |
++static jmethodID byteBuffer_set_position; | |
++static jmethodID byteBuffer_array; | |
++static jmethodID byteBuffer_arrayOffset; | |
struct OPENSSL_Delete { | |
void operator()(void* p) const { | |
@@@ -8644,18 -8644,18 +8649,18 @@@ static int sslRead(JNIEnv* env, SSL* ss | |
} | |
static jint NativeCrypto_SSL_read_BIO(JNIEnv* env, jclass, jlong sslRef, jbyteArray destJava, | |
-- jlong sourceBioRef, jlong sinkBioRef, jobject shc) { | |
++ jobject sourceByteBuffer, jlong sinkBioRef, jobject shc) { | |
SSL* ssl = to_SSL(env, sslRef, true); | |
-- BIO* rbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sourceBioRef)); | |
BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sinkBioRef)); | |
JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO dest=%p sourceBio=%p sinkBio=%p shc=%p", | |
-- ssl, destJava, rbio, wbio, shc); | |
++ ssl, destJava, sourceByteBuffer, wbio, shc); | |
if (ssl == NULL) { | |
return 0; | |
} | |
-- if (rbio == NULL || wbio == NULL) { | |
-- jniThrowNullPointerException(env, "rbio == null || wbio == null"); | |
-- JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => rbio == null || wbio == null", ssl); | |
++ if (sourceByteBuffer == NULL || wbio == NULL) { | |
++ jniThrowNullPointerException(env, "sourceByteBuffer == null || wbio == null"); | |
++ JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => sourceByteBuffer == null || wbio == null", | |
++ ssl); | |
return -1; | |
} | |
if (shc == NULL) { | |
@@@ -8692,9 -8692,9 +8697,34 @@@ | |
return -1; | |
} | |
-- ScopedSslBio sslBio(ssl, rbio, wbio); | |
++ int result; | |
++ int position = env->CallIntMethod(sourceByteBuffer, byteBuffer_get_position); | |
++ int remaining = env->CallIntMethod(sourceByteBuffer, byteBuffer_remaining); | |
++ if (NULL == env->GetDirectBufferAddress(sourceByteBuffer)) { | |
++ int arrayOffset = env->CallIntMethod(sourceByteBuffer, byteBuffer_arrayOffset); | |
++ jbyteArray array = (jbyteArray)env->CallObjectMethod(sourceByteBuffer, byteBuffer_array); | |
++ ScopedByteArrayRW source(env, array); | |
++ jbyte* buf = source.get(); | |
++ BIO* rbio = BIO_new_mem_buf(buf + arrayOffset + position, remaining); | |
++ int before = BIO_pending(rbio); | |
++ ScopedSslBio sslBio(ssl, rbio, wbio); | |
++ result = SSL_read(ssl, dest.get(), dest.size()); | |
++ int after = BIO_pending(rbio); | |
++ __android_log_print(ANDROID_LOG_INFO,LOG_TAG, "pending: %d %d %d", before, after, dest.size()); | |
++ env->CallObjectMethod(sourceByteBuffer, byteBuffer_set_position, position + (before - after)); | |
++ BIO_free(rbio); | |
++ } | |
++ else { | |
++ jbyte* buf = (jbyte*)env->GetDirectBufferAddress(sourceByteBuffer); | |
++ BIO* rbio = BIO_new_mem_buf(buf + position, remaining); | |
++ int before = BIO_pending(rbio); | |
++ ScopedSslBio sslBio(ssl, rbio, wbio); | |
++ result = SSL_read(ssl, dest.get(), dest.size()); | |
++ int after = BIO_pending(rbio); | |
++ env->CallObjectMethod(sourceByteBuffer, byteBuffer_set_position, position + (before - after)); | |
++ BIO_free(rbio); | |
++ } | |
-- int result = SSL_read(ssl, dest.get(), dest.size()); | |
appData->clearCallbackState(); | |
// callbacks can happen if server requests renegotiation | |
if (env->ExceptionCheck()) { | |
@@@ -9700,7 -9700,7 +9730,7 @@@ static JNINativeMethod sNativeCryptoMet | |
NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[J"), | |
NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[J"), | |
NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"), | |
-- NATIVE_METHOD(NativeCrypto, SSL_read_BIO, "(J[BJJ" SSL_CALLBACKS ")I"), | |
++ NATIVE_METHOD(NativeCrypto, SSL_read_BIO, "(J[BLjava/nio/ByteBuffer;J" SSL_CALLBACKS ")I"), | |
NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"), | |
NATIVE_METHOD(NativeCrypto, SSL_write_BIO, "(J[BIJ" SSL_CALLBACKS ")I"), | |
NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"), | |
@@@ -9782,6 -9782,6 +9812,13 @@@ static void initialize_conscrypt(JNIEnv | |
outputStream_writeMethod = getMethodRef(env, outputStreamClass, "write", "([B)V"); | |
outputStream_flushMethod = getMethodRef(env, outputStreamClass, "flush", "()V"); | |
++ jclass bbclass = env->FindClass("java/nio/ByteBuffer"); | |
++ byteBuffer_remaining = getMethodRef(env, bbclass, "remaining", "()I"); | |
++ byteBuffer_get_position = getMethodRef(env, bbclass, "position", "()I"); | |
++ byteBuffer_set_position = getMethodRef(env, bbclass, "position", "(I)Ljava/nio/Buffer;"); | |
++ byteBuffer_array = getMethodRef(env, bbclass, "array", "()[B");; | |
++ byteBuffer_arrayOffset = getMethodRef(env, bbclass, "arrayOffset", "()I");; | |
++ | |
#ifdef CONSCRYPT_UNBUNDLED | |
findAsynchronousCloseMonitorFuncs(); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment