You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by od...@apache.org on 2010/09/14 15:32:19 UTC

svn commit: r996891 - in /harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main: java/org/apache/harmony/xnet/provider/jsse/ native/jsse/shared/ native/jsse/unix/

Author: odeakin
Date: Tue Sep 14 13:32:09 2010
New Revision: 996891

URL: http://svn.apache.org/viewvc?rev=996891&view=rev
Log:
Applying x-net-6.patch patch for HARMONY-6627 ([classlib][x-net] Creating a JSSE provider based on OpenSSL).

Added:
    harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/libhyjsse.exp
Modified:
    harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java
    harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.c
    harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.h
    harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/exports.txt

Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java?rev=996891&r1=996890&r2=996891&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java Tue Sep 14 13:32:09 2010
@@ -88,12 +88,26 @@ public class SSLEngineImpl extends SSLEn
     // logger
     private Logger.Stream logger = Logger.getStream("engine");
 
-    // Pointer to the OpenSSL SSL struct used for this engine
+    // Pointer to the SSL struct
     private long SSL;
+    // Pointer to the custom struct used for this engine
+    private long SSLEngineAddress;
     
     private SSLEngineResult.HandshakeStatus handshakeStatus;
     
-    private native long initImpl(long context);
+    static {
+        initImpl();
+    }
+    
+    private static native void initImpl();
+    private static native long initSSL(long context);
+    private static native long initSSLEngine(long context);
+    private static native SSLEngineResult.HandshakeStatus connectImpl(long sslEngineAddress);
+    private static native SSLEngineResult.HandshakeStatus acceptImpl(long sslEngineAddress);
+    private static native SSLEngineResult wrapImpl(long sslEngineAddress,
+            byte[] src, int src_len, byte[] dst, int dst_len);
+    private static native SSLEngineResult unwrapImpl(long sslEngineAddress,
+            byte[] src, int src_len, byte[] dst, int dst_len);
     
     /**
      * Ctor
@@ -102,7 +116,8 @@ public class SSLEngineImpl extends SSLEn
     protected SSLEngineImpl(SSLParameters sslParameters) {
         super();
         this.sslParameters = sslParameters;
-        SSL = initImpl(sslParameters.getSSLContextAddress());
+        SSL = initSSL(sslParameters.getSSLContextAddress());
+        SSLEngineAddress = initSSLEngine(SSL);
     }
 
     /**
@@ -114,13 +129,9 @@ public class SSLEngineImpl extends SSLEn
     protected SSLEngineImpl(String host, int port, SSLParameters sslParameters) {
         super(host, port);
         this.sslParameters = sslParameters;
-        SSL = initImpl(sslParameters.getSSLContextAddress());
+        SSL = initSSL(sslParameters.getSSLContextAddress());
+        SSLEngineAddress = initSSLEngine(SSL);
     }
-
-    private native SSLEngineResult.HandshakeStatus connectImpl(long sslContextAddress);
-    private native SSLEngineResult.HandshakeStatus acceptImpl(long sslContextAddress);
-    private native SSLEngineResult wrapImpl(long sslContextAddress,
-            byte[] src, int src_len, byte[] dst, int dst_len);
     
     /**
      * Starts the handshake.
@@ -145,12 +156,12 @@ public class SSLEngineImpl extends SSLEn
                     logger.println("SSLEngineImpl: CLIENT connecting");
                 }
 
-                handshakeStatus = connectImpl(SSL);
+                handshakeStatus = connectImpl(SSLEngineAddress);
             } else {
                 if (logger != null) {
                     logger.println("SSLEngineImpl: SERVER accepting connection");
                 }
-                handshakeStatus = acceptImpl(SSL);
+                handshakeStatus = acceptImpl(SSLEngineAddress);
             }
 //            appData = new SSLEngineAppData();
 //            alertProtocol = new AlertProtocol();
@@ -464,138 +475,142 @@ public class SSLEngineImpl extends SSLEn
             beginHandshake();
         }
 
-        SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
-        // If is is initial handshake or connection closure stage,
-        // check if this call was made in spite of handshake status
-        if ((session == null || engine_was_closed) && (
-                    handshakeStatus.equals(
-                        SSLEngineResult.HandshakeStatus.NEED_WRAP) ||
-                    handshakeStatus.equals(
-                        SSLEngineResult.HandshakeStatus.NEED_TASK))) {
-            return new SSLEngineResult(
-                    getEngineStatus(), handshakeStatus, 0, 0);
-        }
-
-        if (src.remaining() < recordProtocol.getMinRecordSize()) {
-            return new SSLEngineResult(
-                    SSLEngineResult.Status.BUFFER_UNDERFLOW,
-                    getHandshakeStatus(), 0, 0);
-        }
-
-        try {
-            src.mark();
-            // check the destination buffers and count their capacity
-            int capacity = 0;
-            for (int i=offset; i<offset+length; i++) {
-                if (dsts[i] == null) {
-                    throw new IllegalStateException(
-                            "Some of the input parameters are null");
-                }
-                if (dsts[i].isReadOnly()) {
-                    throw new ReadOnlyBufferException();
-                }
-                capacity += dsts[i].remaining();
-            }
-            if (capacity < recordProtocol.getDataSize(src.remaining())) {
-                return new SSLEngineResult(
-                        SSLEngineResult.Status.BUFFER_OVERFLOW,
-                        getHandshakeStatus(), 0, 0);
-            }
-            recProtIS.setSourceBuffer(src);
-            // unwrap the record contained in source buffer, pass it
-            // to appropriate client protocol (alert, handshake, or app)
-            // and retrieve the type of unwrapped data
-            int type = recordProtocol.unwrap();
-            // process the data and return the result
-            switch (type) {
-                case ContentType.HANDSHAKE:
-                case ContentType.CHANGE_CIPHER_SPEC:
-                    if (handshakeProtocol.getStatus().equals(
-                            SSLEngineResult.HandshakeStatus.FINISHED)) {
-                        session = recordProtocol.getSession();
-                    }
-                    break;
-                case ContentType.APPLICATION_DATA:
-                    break;
-                case ContentType.ALERT:
-                    if (alertProtocol.isFatalAlert()) {
-                        alertProtocol.setProcessed();
-                        if (session != null) {
-                            session.invalidate();
-                        }
-                        String description = "Fatal alert received "
-                            + alertProtocol.getAlertDescription();
-                        shutdown();
-                        throw new SSLException(description);
-                    } else {
-                        if (logger != null) {
-                            logger.println("Warning allert has been received: "
-                                + alertProtocol.getAlertDescription());
-                        }
-                        switch(alertProtocol.getDescriptionCode()) {
-                            case AlertProtocol.CLOSE_NOTIFY:
-                                alertProtocol.setProcessed();
-                                close_notify_was_received = true;
-                                if (!close_notify_was_sent) {
-                                    closeOutbound();
-                                    closeInbound();
-                                } else {
-                                    closeInbound();
-                                    shutdown();
-                                }
-                                break;
-                            case AlertProtocol.NO_RENEGOTIATION:
-                                alertProtocol.setProcessed();
-                                if (session == null) {
-                                    // message received during the initial 
-                                    // handshake
-                                    throw new AlertException(
-                                        AlertProtocol.HANDSHAKE_FAILURE,
-                                        new SSLHandshakeException(
-                                            "Received no_renegotiation "
-                                            + "during the initial handshake"));
-                                } else {
-                                    // just stop the handshake
-                                    handshakeProtocol.stop();
-                                }
-                                break;
-                            default:
-                                alertProtocol.setProcessed();
-                        }
-                    }
-                    break;
-            }
-            return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(),
-                    recProtIS.consumed(), 
-                    // place the app. data (if any) into the dest. buffers 
-                    // and get the number of produced bytes:
-                    appData.placeTo(dsts, offset, length));
-        } catch (BufferUnderflowException e) {
-            // there was not enought data ource buffer to make complete packet
-            src.reset();
-            return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW,
-                    getHandshakeStatus(), 0, 0);
-        } catch (AlertException e) {
-            // fatal alert occured
-            alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
-            engine_was_closed = true;
-            src.reset();
-            if (session != null) {
-                session.invalidate();
-            }
-            // shutdown work will be made after the alert will be sent
-            // to another peer (by wrap method)
-            throw e.getReason();
-        } catch (SSLException e) {
-            throw e;
-        } catch (IOException e) {
-            alertProtocol.alert(AlertProtocol.FATAL,
-                    AlertProtocol.INTERNAL_ERROR);
-            engine_was_closed = true;
-            // shutdown work will be made after the alert will be sent
-            // to another peer (by wrap method)
-            throw new SSLException(e.getMessage());
-        }
+        // only use the first buffer at the moment
+        byte[] dst = dsts[0].array();
+        int dst_len = dst.length;
+        return unwrapImpl(SSLEngineAddress, src.array(), src.array().length, dst, dst_len);
+//        SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
+//        // If is is initial handshake or connection closure stage,
+//        // check if this call was made in spite of handshake status
+//        if ((session == null || engine_was_closed) && (
+//                    handshakeStatus.equals(
+//                        SSLEngineResult.HandshakeStatus.NEED_WRAP) ||
+//                    handshakeStatus.equals(
+//                        SSLEngineResult.HandshakeStatus.NEED_TASK))) {
+//            return new SSLEngineResult(
+//                    getEngineStatus(), handshakeStatus, 0, 0);
+//        }
+//
+//        if (src.remaining() < recordProtocol.getMinRecordSize()) {
+//            return new SSLEngineResult(
+//                    SSLEngineResult.Status.BUFFER_UNDERFLOW,
+//                    getHandshakeStatus(), 0, 0);
+//        }
+//
+//        try {
+//            src.mark();
+//            // check the destination buffers and count their capacity
+//            int capacity = 0;
+//            for (int i=offset; i<offset+length; i++) {
+//                if (dsts[i] == null) {
+//                    throw new IllegalStateException(
+//                            "Some of the input parameters are null");
+//                }
+//                if (dsts[i].isReadOnly()) {
+//                    throw new ReadOnlyBufferException();
+//                }
+//                capacity += dsts[i].remaining();
+//            }
+//            if (capacity < recordProtocol.getDataSize(src.remaining())) {
+//                return new SSLEngineResult(
+//                        SSLEngineResult.Status.BUFFER_OVERFLOW,
+//                        getHandshakeStatus(), 0, 0);
+//            }
+//            recProtIS.setSourceBuffer(src);
+//            // unwrap the record contained in source buffer, pass it
+//            // to appropriate client protocol (alert, handshake, or app)
+//            // and retrieve the type of unwrapped data
+//            int type = recordProtocol.unwrap();
+//            // process the data and return the result
+//            switch (type) {
+//                case ContentType.HANDSHAKE:
+//                case ContentType.CHANGE_CIPHER_SPEC:
+//                    if (handshakeProtocol.getStatus().equals(
+//                            SSLEngineResult.HandshakeStatus.FINISHED)) {
+//                        session = recordProtocol.getSession();
+//                    }
+//                    break;
+//                case ContentType.APPLICATION_DATA:
+//                    break;
+//                case ContentType.ALERT:
+//                    if (alertProtocol.isFatalAlert()) {
+//                        alertProtocol.setProcessed();
+//                        if (session != null) {
+//                            session.invalidate();
+//                        }
+//                        String description = "Fatal alert received "
+//                            + alertProtocol.getAlertDescription();
+//                        shutdown();
+//                        throw new SSLException(description);
+//                    } else {
+//                        if (logger != null) {
+//                            logger.println("Warning allert has been received: "
+//                                + alertProtocol.getAlertDescription());
+//                        }
+//                        switch(alertProtocol.getDescriptionCode()) {
+//                            case AlertProtocol.CLOSE_NOTIFY:
+//                                alertProtocol.setProcessed();
+//                                close_notify_was_received = true;
+//                                if (!close_notify_was_sent) {
+//                                    closeOutbound();
+//                                    closeInbound();
+//                                } else {
+//                                    closeInbound();
+//                                    shutdown();
+//                                }
+//                                break;
+//                            case AlertProtocol.NO_RENEGOTIATION:
+//                                alertProtocol.setProcessed();
+//                                if (session == null) {
+//                                    // message received during the initial 
+//                                    // handshake
+//                                    throw new AlertException(
+//                                        AlertProtocol.HANDSHAKE_FAILURE,
+//                                        new SSLHandshakeException(
+//                                            "Received no_renegotiation "
+//                                            + "during the initial handshake"));
+//                                } else {
+//                                    // just stop the handshake
+//                                    handshakeProtocol.stop();
+//                                }
+//                                break;
+//                            default:
+//                                alertProtocol.setProcessed();
+//                        }
+//                    }
+//                    break;
+//            }
+//            return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(),
+//                    recProtIS.consumed(), 
+//                    // place the app. data (if any) into the dest. buffers 
+//                    // and get the number of produced bytes:
+//                    appData.placeTo(dsts, offset, length));
+//        } catch (BufferUnderflowException e) {
+//            // there was not enought data ource buffer to make complete packet
+//            src.reset();
+//            return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW,
+//                    getHandshakeStatus(), 0, 0);
+//        } catch (AlertException e) {
+//            // fatal alert occured
+//            alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
+//            engine_was_closed = true;
+//            src.reset();
+//            if (session != null) {
+//                session.invalidate();
+//            }
+//            // shutdown work will be made after the alert will be sent
+//            // to another peer (by wrap method)
+//            throw e.getReason();
+//        } catch (SSLException e) {
+//            throw e;
+//        } catch (IOException e) {
+//            alertProtocol.alert(AlertProtocol.FATAL,
+//                    AlertProtocol.INTERNAL_ERROR);
+//            engine_was_closed = true;
+//            // shutdown work will be made after the alert will be sent
+//            // to another peer (by wrap method)
+//            throw new SSLException(e.getMessage());
+//        }
     }
 
     /**
@@ -636,7 +651,7 @@ public class SSLEngineImpl extends SSLEn
         byte[] src = srcs[0].array();
         int src_len = src.length;
         
-        return wrapImpl(SSL, src, src_len, dst.array(), dst.array().length);
+        return wrapImpl(SSLEngineAddress, src, src_len, dst.array(), dst.array().length);
         
         
 //        SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();

Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.c?rev=996891&r1=996890&r2=996891&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.c (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.c Tue Sep 14 13:32:09 2010
@@ -24,16 +24,34 @@
 #include "openssl/ssl.h"
 #include "openssl/err.h"
 
+typedef struct {
+  BIO *bio;
+  BIO *bio_io;
+} _sslengine;
+
 static jobject handshake_need_wrap, handshake_need_unwrap, handshake_finished, handshake_not_handshaking;
 static jobject engine_buffer_overflow, engine_buffer_underflow, engine_closed, engine_ok;
-static int initialised = 0;
 
-void init(JNIEnv *env) {
+jobject getHandshakeStatus(JNIEnv *env, int state) {
+    jclass exception;
+    switch(state) {
+    case SSL_ERROR_NONE:
+      return handshake_not_handshaking;
+    case SSL_ERROR_WANT_READ:
+      return handshake_need_unwrap;
+    case SSL_ERROR_WANT_WRITE:
+      return handshake_need_wrap;
+    default:
+      exception = (*env)->FindClass(env, "javax/net/ssl/SSLHandshakeException");
+      (*env)->ThrowNew(env, exception, ERR_reason_error_string(ERR_get_error()));
+    }
+    return NULL;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl
+  (JNIEnv *env, jclass clazz) {
     jclass class;
     jfieldID fieldID;
-    if (initialised == 1) {
-      return;
-    }
     // initialise handshake status enum
     class = (*env)->FindClass(env, "javax/net/ssl/SSLEngineResult$HandshakeStatus");
     fieldID = (*env)->GetStaticFieldID(env, class, "NEED_WRAP", "Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
@@ -55,128 +73,146 @@ void init(JNIEnv *env) {
     engine_closed = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
     fieldID = (*env)->GetStaticFieldID(env, class, "OK", "Ljavax/net/ssl/SSLEngineResult$Status;");
     engine_ok = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
-    
-    initialised = 1;
-}
-
-jobject getHandshakeStatus(JNIEnv *env, int state) {
-    jclass exception;
-    switch(state) {
-    case SSL_ERROR_NONE:
-      return handshake_not_handshaking;
-    case SSL_ERROR_WANT_READ:
-      return handshake_need_unwrap;
-    case SSL_ERROR_WANT_WRITE:
-      return handshake_need_wrap;
-    default:
-      exception = (*env)->FindClass(env, "javax/net/ssl/SSLHandshakeException");
-      (*env)->ThrowNew(env, exception, ERR_reason_error_string(ERR_get_error()));
-    }
-    return NULL;
 }
 
-JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl
+JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initSSL
   (JNIEnv *env, jclass clazz, jlong context) {
-    init(env);
-    return addr2jlong(SSL_new(jlong2addr(SSL_CTX, context)));
+    SSL *ssl;
+    ssl = SSL_new(jlong2addr(SSL_CTX, context));
+    return addr2jlong(ssl);
 }
 
-JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl
+JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initSSLEngine
   (JNIEnv *env, jclass clazz, jlong jssl) {
+    _sslengine *sslengine;
     SSL *ssl = jlong2addr(SSL, jssl);
-    BIO *server, *server_out;
-    int ret;
-    size_t bufsiz = 256;
-
+    BIO *bio, *bio_in, *bio_out;
+    sslengine = malloc(sizeof(_sslengine));
+    bio = BIO_new(BIO_f_ssl());
+    BIO_set_ssl(bio, ssl, BIO_NOCLOSE);
     // create a bio pair
-    BIO_new_bio_pair(&server, bufsiz, &server_out, bufsiz);
-    
-    SSL_set_bio(ssl, server, server);
+    BIO_new_bio_pair(&bio_in, 0, &bio_out, 0);
+    BIO_get_ssl(bio, &ssl);
+    SSL_set_bio(ssl, bio_in, bio_in);
+    sslengine->bio = bio;
+    sslengine->bio_io = bio_out;
+    return addr2jlong(sslengine);
+}
 
-    // Put our SSL into connect state
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl
+  (JNIEnv *env, jclass clazz, jlong jsslengine) {
+    _sslengine *sslengine = jlong2addr(_sslengine, jsslengine);
+    SSL *ssl = NULL;
+    BIO *bio = sslengine->bio;
+    BIO *server_io = sslengine->bio_io;
+    int ret;
+    
+    BIO_get_ssl(bio, &ssl);
+    // Put our SSL into accept state
     SSL_set_accept_state(ssl);
-
     // Start the client handshake
     ret = SSL_do_handshake(ssl);
-
-    return getHandshakeStatus(env, SSL_get_error(ssl, ret));
+    
+    fprintf(stderr, "Server bio pending: %d\n", BIO_ctrl_pending(bio));
+    fprintf(stderr, "Server bio can write: %d\n", BIO_ctrl_get_write_guarantee(bio));
+    fprintf(stderr, "Server bio read request: %d\n", BIO_ctrl_get_read_request(bio));
+    fprintf(stderr, "Server IO pending: %d\n", BIO_ctrl_pending(server_io));
+    fprintf(stderr, "Server IO can write: %d\n", BIO_ctrl_get_write_guarantee(server_io));
+    fprintf(stderr, "Server IO read request: %d\n", BIO_ctrl_get_read_request(server_io));
+    return handshake_need_unwrap;
+    //return getHandshakeStatus(env, SSL_get_error(ssl, ret));
 }
 
 JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_connectImpl
-  (JNIEnv *env, jclass clazz, jlong jssl) {
-    SSL *ssl = jlong2addr(SSL, jssl);
-    BIO *client, *client_out;
+  (JNIEnv *env, jclass clazz, jlong jsslengine) {
+    _sslengine *sslengine = jlong2addr(_sslengine, jsslengine);
+    SSL *ssl = NULL;
+    BIO *bio = sslengine->bio;
+    BIO *client_io = sslengine->bio_io;
     int ret;
     
-    size_t bufsize = 256;  // need to fix
-
-    // create a bio pair
-    BIO_new_bio_pair(&client, bufsize, &client_out, bufsize);
-    
-    SSL_set_bio(ssl, client, client);
-
+    BIO_get_ssl(bio, &ssl);
     // Put our SSL into connect state
     SSL_set_connect_state(ssl);
 
     // Start the client handshake
+    fprintf(stderr, "before handshake: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    fprintf(stderr, "Client bio pending: %d\n", BIO_ctrl_pending(bio));
+    fprintf(stderr, "Client bio can write: %d\n", BIO_ctrl_get_write_guarantee(bio));
+    fprintf(stderr, "Client bio read request: %d\n", BIO_ctrl_get_read_request(bio));
+    fprintf(stderr, "Client IO pending: %d\n", BIO_ctrl_pending(client_io));
+    fprintf(stderr, "Client IO can write: %d\n", BIO_ctrl_get_write_guarantee(client_io));
+    fprintf(stderr, "Client IO read request: %d\n", BIO_ctrl_get_read_request(client_io));
     ret = SSL_do_handshake(ssl);
-
-    return getHandshakeStatus(env, SSL_get_error(ssl, ret));
+    fprintf(stderr, "after handshake: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    fprintf(stderr, "Client bio pending: %d\n", BIO_ctrl_pending(bio));
+    fprintf(stderr, "Client bio can write: %d\n", BIO_ctrl_get_write_guarantee(bio));
+    fprintf(stderr, "Client bio read request: %d\n", BIO_ctrl_get_read_request(bio));
+    fprintf(stderr, "Client IO pending: %d\n", BIO_ctrl_pending(client_io));
+    fprintf(stderr, "Client IO can write: %d\n", BIO_ctrl_get_write_guarantee(client_io));
+    fprintf(stderr, "Client IO read request: %d\n", BIO_ctrl_get_read_request(client_io));
+    return handshake_need_wrap;
+    //return getHandshakeStatus(env, SSL_get_error(ssl, ret));
 }
 
 JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_wrapImpl
-  (JNIEnv *env, jclass clazz, jlong jssl, jbyteArray src, int src_len, 
+  (JNIEnv *env, jclass clazz, jlong jsslengine, jbyteArray src, int src_len, 
   jbyteArray dst, int dst_len) {
-    SSL *ssl = jlong2addr(SSL, jssl);
-    int write_result, read_result;
-    jobject handshake_state, engine_state, result;
+    _sslengine *sslengine = jlong2addr(_sslengine, jsslengine);
+    BIO *bio = sslengine->bio;
+    BIO *bio_io = sslengine->bio_io;
+    SSL *ssl = NULL;
+    int write_result = 0, read_result = 0;
+    jobject handshake_state = NULL, engine_state = NULL, result = NULL;
     jclass result_class;
     jmethodID result_constructor;
+    jbyte *buffer;
+
+    BIO_get_ssl(bio, &ssl);
 
+    fprintf(stderr, ">wrap 1: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    
     // write input data
-    jbyte *buffer = (jbyte*) malloc(src_len * sizeof(jbyte*)); 
+    buffer = (jbyte*) malloc(src_len * sizeof(jbyte*));
     (*env)->GetByteArrayRegion(env, src, 0, src_len, buffer);
-
-    write_result = SSL_write(ssl, (const void *)buffer, (int)src_len);
-    fprintf(stderr, "SSL_write, result:%d \n", write_result);
+    write_result = BIO_write(bio, (const void *)buffer, (int)src_len);
+    fprintf(stderr, ">wrap BIO_write, result:%d \n", write_result);
     if (write_result > 0) {
-        // must not be handshaking as we've written bytes
+        // wrote some data so must not be handshaking
         handshake_state = handshake_not_handshaking;
         if (write_result < src_len) {
             engine_state = engine_buffer_overflow;
         } else {
             engine_state = engine_ok;
         }
-    } if (write_result == 0) {
-        handshake_state = handshake_not_handshaking;
-        engine_state = engine_closed;
     } else {
-        handshake_state = getHandshakeStatus(env, SSL_get_error(ssl, write_result));
-        if ((*env)->ExceptionCheck(env)) {
-            return NULL;
-        }
-        engine_state = engine_ok; // is this correct?
         write_result = 0;
+        handshake_state = handshake_need_unwrap;
+        engine_state = engine_ok;
     }
     free(buffer);
     
+    fprintf(stderr, ">wrap 2: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
     
     // read output data
     buffer = (jbyte*) malloc(dst_len * sizeof(jbyte*));
-
-    read_result = SSL_read(ssl, (void *)buffer, (int)dst_len);
+    read_result = BIO_read(bio_io, buffer, dst_len);
+    
+    fprintf(stderr, ">wrap read result: %d\n", read_result);
+    fprintf(stderr, ">wrap 3: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    fprintf(stderr, ">wrap bio pending: %d\n", BIO_ctrl_pending(bio));
+    fprintf(stderr, ">wrap bio can write: %d\n", BIO_ctrl_get_write_guarantee(bio));
+    fprintf(stderr, ">wrap bio read request: %d\n", BIO_ctrl_get_read_request(bio));
+    fprintf(stderr, ">wrap IO pending: %d\n", BIO_ctrl_pending(bio_io));
+    fprintf(stderr, ">wrap IO can write: %d\n", BIO_ctrl_get_write_guarantee(bio_io));
+    fprintf(stderr, ">wrap IO read request: %d\n", BIO_ctrl_get_read_request(bio_io));
+    
     if (read_result > 0) {
       (*env)->SetByteArrayRegion(env, dst, 0, read_result, buffer);
     }
-    if (read_result == -1) {
-        // The socket has been closed
-        jclass exception = (*env)->FindClass(env, "java/net/SocketException");
-        (*env)->ThrowNew(env, exception, "Connection was reset");
-        return NULL;
-    }
     if (read_result < 0) {
-      fprintf(stderr, "Read returned:%d \n", read_result);
-      read_result = 0;
+        // change state?
+        read_result = 0;
     }
     free(buffer);
     
@@ -188,3 +224,75 @@ JNIEXPORT jobject JNICALL Java_org_apach
         engine_state, handshake_state, write_result, read_result);
     return result;
 }
+
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_unwrapImpl
+  (JNIEnv *env, jclass clazz, jlong jsslengine, jbyteArray src, int src_len, 
+  jbyteArray dst, int dst_len) {
+      _sslengine *sslengine = jlong2addr(_sslengine, jsslengine);
+    BIO *bio = sslengine->bio;
+    BIO *bio_io = sslengine->bio_io;
+    SSL *ssl = NULL;
+    int write_result = 0, read_result = 0;
+    jobject handshake_state = NULL, engine_state = NULL, result = NULL;
+    jclass result_class;
+    jmethodID result_constructor;
+    jbyte *buffer;
+
+    BIO_get_ssl(bio, &ssl);
+
+    fprintf(stderr, ">unwrap 1: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    
+    // write input data
+    buffer = (jbyte*) malloc(src_len * sizeof(jbyte*));
+    (*env)->GetByteArrayRegion(env, src, 0, src_len, buffer);
+    write_result = BIO_write(bio_io, (const void *)buffer, (int)src_len);
+    fprintf(stderr, ">unwrap BIO_write, result:%d \n", write_result);
+    if (write_result < 0) {
+        // change state?
+        write_result = 0;
+    }
+    
+    free(buffer);
+    
+    fprintf(stderr, ">unwrap 2: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    
+    // read output data
+    buffer = (jbyte*) malloc(dst_len * sizeof(jbyte*));
+    read_result = BIO_read(bio, buffer, dst_len);
+    
+    if (read_result > 0) {
+        // wrote some data so must not be handshaking
+        handshake_state = handshake_not_handshaking;
+        if (read_result < src_len) {
+            engine_state = engine_buffer_underflow;
+        } else {
+            engine_state = engine_ok;
+        }
+    } else {
+        read_result = 0;
+        handshake_state = handshake_need_wrap;
+        engine_state = engine_ok;
+    }
+    
+    fprintf(stderr, ">unwrap read result: %d\n", read_result);
+    fprintf(stderr, ">unwrap 3: SSL in init? %d : %s\n", SSL_in_init(ssl), SSL_state_string_long(ssl));
+    fprintf(stderr, ">unwrap bio pending: %d\n", BIO_ctrl_pending(bio));
+    fprintf(stderr, ">unwrap bio can write: %d\n", BIO_ctrl_get_write_guarantee(bio));
+    fprintf(stderr, ">unwrap bio read request: %d\n", BIO_ctrl_get_read_request(bio));
+    fprintf(stderr, ">unwrap IO pending: %d\n", BIO_ctrl_pending(bio_io));
+    fprintf(stderr, ">unwrap IO can write: %d\n", BIO_ctrl_get_write_guarantee(bio_io));
+    fprintf(stderr, ">unwrap IO read request: %d\n", BIO_ctrl_get_read_request(bio_io));
+    
+    if (read_result > 0) {
+      (*env)->SetByteArrayRegion(env, dst, 0, read_result, buffer);
+    }
+    free(buffer);
+    
+    // construct return object
+    result_class = (*env)->FindClass(env, "javax/net/ssl/SSLEngineResult");
+    result_constructor = (*env)->GetMethodID(env, result_class, "<init>", 
+        "(Ljavax/net/ssl/SSLEngineResult$Status;Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;II)V");
+    result = (*env)->NewObject(env, result_class, result_constructor,
+        engine_state, handshake_state, write_result, read_result);
+    return result;  
+}

Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.h?rev=996891&r1=996890&r2=996891&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.h (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/shared/sslEngine.h Tue Sep 14 13:32:09 2010
@@ -23,7 +23,9 @@
 extern "C" {
 #endif
 
-JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl
+JNIEXPORT void JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl
+  (JNIEnv *, jclass);
+JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_sslEngineImpl
   (JNIEnv *, jclass, jlong);
 JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl
   (JNIEnv *, jclass, jlong);
@@ -31,6 +33,8 @@ JNIEXPORT jobject JNICALL Java_org_apach
   (JNIEnv *, jclass, jlong);
 JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_wrapImpl
   (JNIEnv *, jclass, jlong, jbyteArray, int, jbyteArray, int);
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_unwrapImpl
+  (JNIEnv *, jclass, jlong, jbyteArray, int, jbyteArray, int);
 #ifdef __cplusplus
 }
 #endif

Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/exports.txt
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/exports.txt?rev=996891&r1=996890&r2=996891&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/exports.txt (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/exports.txt Tue Sep 14 13:32:09 2010
@@ -14,6 +14,9 @@ Java_org_apache_harmony_xnet_provider_js
 Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_readAppDataImpl
 Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_closeImpl
 Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl
+Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initSSL
+Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initSSLEngine
 Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl
 Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_connectImpl
 Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_wrapImpl
+Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_unwrapImpl

Added: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/libhyjsse.exp
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/libhyjsse.exp?rev=996891&view=auto
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/libhyjsse.exp (added)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/native/jsse/unix/libhyjsse.exp Tue Sep 14 13:32:09 2010
@@ -0,0 +1,26 @@
+HYJSSE_0.1 {
+  global :
+    Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_initialiseDefaults;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_initialiseContext;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_setEnabledProtocolsImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_setClientAuthImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_setEnabledCipherSuitesImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSessionImpl_initialiseSession;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSessionImpl_getCipherNameImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSessionImpl_getCreationTimeImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSessionImpl_getPeerCertificatesImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_initImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_sslAcceptImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_sslConnectImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_writeAppDataImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_readAppDataImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLSocketImpl_closeImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initSSL;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initSSLEngine;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_connectImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_wrapImpl;
+    Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_unwrapImpl;
+  local : *;
+};