Skip to content

Instantly share code, notes, and snippets.

/-

Created July 23, 2014 20:52
Show Gist options
  • Save anonymous/cea075b7a70abfd7359b to your computer and use it in GitHub Desktop.
Save anonymous/cea075b7a70abfd7359b to your computer and use it in GitHub Desktop.
commit 667914386d177bf8eb71fdaef688a75b361ee9c9
Merge: a08c6d2 507c4a2
Author: Koushik Dutta <koushd@gmail.com>
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