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/10 18:01:18 UTC
svn commit: r995839 - in
/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src:
main/java/javax/net/ssl/ main/java/org/apache/harmony/xnet/provider/jsse/
main/native/jsse/shared/ main/native/jsse/unix/
test/api/java/org/apache/harmony/xnet/tes...
Author: odeakin
Date: Fri Sep 10 16:01:18 2010
New Revision: 995839
URL: http://svn.apache.org/viewvc?rev=995839&view=rev
Log:
Apply x-net-4.patch for HARMONY-6627 ([classlib][x-net] Creating a JSSE provider based on OpenSSL) with some very minor modifications (details in the JIRA).
Modified:
harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/javax/net/ssl/SSLEngineResult.java
harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
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
harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/test/api/java/org/apache/harmony/xnet/tests/javax/net/ssl/SSLEngineTest.java
Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/javax/net/ssl/SSLEngineResult.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/javax/net/ssl/SSLEngineResult.java?rev=995839&r1=995838&r2=995839&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/javax/net/ssl/SSLEngineResult.java (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/javax/net/ssl/SSLEngineResult.java Fri Sep 10 16:01:18 2010
@@ -26,7 +26,7 @@ public class SSLEngineResult {
/**
* The {@code enum} describing the state of the current handshake.
*/
- public enum HandshakeStatus {
+ public static enum HandshakeStatus {
/**
* No handshake in progress.
*/
Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.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/JSSEProvider.java?rev=995839&r1=995838&r2=995839&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java Fri Sep 10 16:01:18 2010
@@ -108,6 +108,9 @@ public final class JSSEProvider extends
public Void run() {
put("SSLContext.TLS", SSLContextImpl.class.getName());
put("Alg.Alias.SSLContext.TLSv1", "TLS");
+ put("SSLContext.SSL", SSLContextImpl.class.getName());
+ put("Alg.Alias.SSLContext.SSLv3", "SSL");
+ put("Alg.Alias.SSLContext.SSLv2", "SSL");
put("KeyManagerFactory.X509", KeyManagerFactoryImpl.class.getName());
put("TrustManagerFactory.X509", TrustManagerFactoryImpl.class.getName());
return null;
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=995839&r1=995838&r2=995839&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 Fri Sep 10 16:01:18 2010
@@ -21,10 +21,15 @@ import org.apache.harmony.xnet.provider.
import org.apache.harmony.xnet.provider.jsse.SSLSessionImpl;
import org.apache.harmony.xnet.provider.jsse.SSLEngineDataStream;
+import java.io.FileDescriptor;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLEngineResult;
@@ -85,9 +90,11 @@ public class SSLEngineImpl extends SSLEn
// Pointer to the OpenSSL SSL struct used for this engine
private long SSL;
-
+
+ private SSLEngineResult.HandshakeStatus handshakeStatus;
+
private native long initImpl(long context);
-
+
/**
* Ctor
* @param sslParameters: SSLParameters
@@ -110,6 +117,11 @@ public class SSLEngineImpl extends SSLEn
SSL = initImpl(sslParameters.getSSLContextAddress());
}
+ 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.
* @throws SSLException
@@ -124,20 +136,29 @@ public class SSLEngineImpl extends SSLEn
if (!peer_mode_was_set) {
throw new IllegalStateException("Client/Server mode was not set");
}
+ // TODO: need to repeat connect/accept if status was waiting on wrap/unwrap previously?
if (!handshake_started) {
handshake_started = true;
- if (getUseClientMode()) {
- //handshakeProtocol = new ClientHandshakeImpl(this);
+
+ if (sslParameters.getUseClientMode()) {
+ if (logger != null) {
+ logger.println("SSLEngineImpl: CLIENT connecting");
+ }
+
+ handshakeStatus = connectImpl(SSL);
} else {
- //handshakeProtocol = new ServerHandshakeImpl(this);
+ if (logger != null) {
+ logger.println("SSLEngineImpl: SERVER accepting connection");
+ }
+ handshakeStatus = acceptImpl(SSL);
}
- appData = new SSLEngineAppData();
- alertProtocol = new AlertProtocol();
- recProtIS = new SSLBufferedInput();
- recordProtocol = new SSLRecordProtocol(handshakeProtocol,
- alertProtocol, recProtIS, appData);
+// appData = new SSLEngineAppData();
+// alertProtocol = new AlertProtocol();
+// recProtIS = new SSLBufferedInput();
+// recordProtocol = new SSLRecordProtocol(handshakeProtocol,
+// alertProtocol, recProtIS, appData);
}
- handshakeProtocol.start();
+// handshakeProtocol.start();
}
/**
@@ -206,7 +227,8 @@ public class SSLEngineImpl extends SSLEn
*/
@Override
public Runnable getDelegatedTask() {
- return handshakeProtocol.getTask();
+ return null;
+ //return handshakeProtocol.getTask();
}
/**
@@ -370,17 +392,18 @@ public class SSLEngineImpl extends SSLEn
// initial handshake has not been started yet
return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
}
- if (alertProtocol.hasAlert()) {
- // need to send an alert
- return SSLEngineResult.HandshakeStatus.NEED_WRAP;
- }
- if (close_notify_was_sent && !close_notify_was_received) {
- // waiting for "close_notify" response
- return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
- }
- return handshakeProtocol.getStatus();
+ return handshakeStatus;
+// if (alertProtocol.hasAlert()) {
+// // need to send an alert
+// return SSLEngineResult.HandshakeStatus.NEED_WRAP;
+// }
+// if (close_notify_was_sent && !close_notify_was_received) {
+// // waiting for "close_notify" response
+// return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
+// }
+// return handshakeProtocol.getStatus();
}
-
+
/**
* This method works according to the specification of implemented class.
* @see javax.net.ssl.SSLEngine#getSession() method
@@ -608,148 +631,155 @@ public class SSLEngineImpl extends SSLEn
if (!handshake_started) {
beginHandshake();
}
-
- SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
- // If it is an 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_UNWRAP) ||
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_TASK))) {
- return new SSLEngineResult(
- getEngineStatus(), handshakeStatus, 0, 0);
- }
-
- int capacity = dst.remaining();
- int produced = 0;
-
- if (alertProtocol.hasAlert()) {
- // we have an alert to be sent
- if (capacity < recordProtocol.getRecordSize(2)) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
- byte[] alert_data = alertProtocol.wrap();
- // place the alert record into destination
- dst.put(alert_data);
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- if (session != null) {
- session.invalidate();
- }
- // fatal alert has been sent, so shut down the engine
- shutdown();
- return new SSLEngineResult(
- SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
- 0, alert_data.length);
- } else {
- alertProtocol.setProcessed();
- // check if the works on this engine have been done
- if (close_notify_was_sent && close_notify_was_received) {
- shutdown();
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
- 0, alert_data.length);
- }
- return new SSLEngineResult(
- getEngineStatus(),
- getHandshakeStatus(),
- 0, alert_data.length);
- }
- }
-
- if (capacity < recordProtocol.getMinRecordSize()) {
- if (logger != null) {
- logger.println("Capacity of the destination("
- +capacity+") < MIN_PACKET_SIZE("
- +recordProtocol.getMinRecordSize()+")");
- }
- return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
-
- try {
- if (!handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
- // so we wraps application data
- dataStream.setSourceBuffers(srcs, offset, len);
- if ((capacity < SSLRecordProtocol.MAX_SSL_PACKET_SIZE) &&
- (capacity < recordProtocol.getRecordSize(
- dataStream.available()))) {
- if (logger != null) {
- logger.println("The destination buffer("
- +capacity+") can not take the resulting packet("
- + recordProtocol.getRecordSize(
- dataStream.available())+")");
- }
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
- if (remaining_wrapped_data == null) {
- remaining_wrapped_data =
- recordProtocol.wrap(ContentType.APPLICATION_DATA,
- dataStream);
- }
- if (capacity < remaining_wrapped_data.length) {
- // It should newer happen because we checked the destination
- // buffer size, but there is a possibility
- // (if dest buffer was filled outside)
- // so we just remember the data into remaining_wrapped_data
- // and will enclose it during the the next call
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, dataStream.consumed(), 0);
- } else {
- dst.put(remaining_wrapped_data);
- produced = remaining_wrapped_data.length;
- remaining_wrapped_data = null;
- return new SSLEngineResult(getEngineStatus(),
- handshakeStatus, dataStream.consumed(), produced);
- }
- } else {
- if (remaining_hsh_data == null) {
- remaining_hsh_data = handshakeProtocol.wrap();
- }
- if (capacity < remaining_hsh_data.length) {
- // It should newer happen because we checked the destination
- // buffer size, but there is a possibility
- // (if dest buffer was filled outside)
- // so we just remember the data into remaining_hsh_data
- // and will enclose it during the the next call
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- } else {
- dst.put(remaining_hsh_data);
- produced = remaining_hsh_data.length;
- remaining_hsh_data = null;
-
- handshakeStatus = handshakeProtocol.getStatus();
- if (handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- session = recordProtocol.getSession();
- }
- }
- return new SSLEngineResult(
- getEngineStatus(), getHandshakeStatus(), 0, produced);
- }
- } catch (AlertException e) {
- // fatal alert occured
- alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
- engine_was_closed = true;
- 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();
- }
+
+ // only use the first buffer at the moment
+ byte[] src = srcs[0].array();
+ int src_len = src.length;
+
+ return wrapImpl(SSL, src, src_len, dst.array(), dst.array().length);
+
+
+// SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
+// // If it is an 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_UNWRAP) ||
+// handshakeStatus.equals(
+// SSLEngineResult.HandshakeStatus.NEED_TASK))) {
+// return new SSLEngineResult(
+// getEngineStatus(), handshakeStatus, 0, 0);
+// }
+//
+// int capacity = dst.remaining();
+// int produced = 0;
+//
+// if (alertProtocol.hasAlert()) {
+// // we have an alert to be sent
+// if (capacity < recordProtocol.getRecordSize(2)) {
+// return new SSLEngineResult(
+// SSLEngineResult.Status.BUFFER_OVERFLOW,
+// handshakeStatus, 0, 0);
+// }
+// byte[] alert_data = alertProtocol.wrap();
+// // place the alert record into destination
+// dst.put(alert_data);
+// if (alertProtocol.isFatalAlert()) {
+// alertProtocol.setProcessed();
+// if (session != null) {
+// session.invalidate();
+// }
+// // fatal alert has been sent, so shut down the engine
+// shutdown();
+// return new SSLEngineResult(
+// SSLEngineResult.Status.CLOSED,
+// SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
+// 0, alert_data.length);
+// } else {
+// alertProtocol.setProcessed();
+// // check if the works on this engine have been done
+// if (close_notify_was_sent && close_notify_was_received) {
+// shutdown();
+// return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
+// SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
+// 0, alert_data.length);
+// }
+// return new SSLEngineResult(
+// getEngineStatus(),
+// getHandshakeStatus(),
+// 0, alert_data.length);
+// }
+// }
+//
+// if (capacity < recordProtocol.getMinRecordSize()) {
+// if (logger != null) {
+// logger.println("Capacity of the destination("
+// +capacity+") < MIN_PACKET_SIZE("
+// +recordProtocol.getMinRecordSize()+")");
+// }
+// return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW,
+// handshakeStatus, 0, 0);
+// }
+//
+// try {
+// if (!handshakeStatus.equals(
+// SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
+// // so we wraps application data
+// dataStream.setSourceBuffers(srcs, offset, len);
+// if ((capacity < SSLRecordProtocol.MAX_SSL_PACKET_SIZE) &&
+// (capacity < recordProtocol.getRecordSize(
+// dataStream.available()))) {
+// if (logger != null) {
+// logger.println("The destination buffer("
+// +capacity+") can not take the resulting packet("
+// + recordProtocol.getRecordSize(
+// dataStream.available())+")");
+// }
+// return new SSLEngineResult(
+// SSLEngineResult.Status.BUFFER_OVERFLOW,
+// handshakeStatus, 0, 0);
+// }
+// if (remaining_wrapped_data == null) {
+// remaining_wrapped_data =
+// recordProtocol.wrap(ContentType.APPLICATION_DATA,
+// dataStream);
+// }
+// if (capacity < remaining_wrapped_data.length) {
+// // It should newer happen because we checked the destination
+// // buffer size, but there is a possibility
+// // (if dest buffer was filled outside)
+// // so we just remember the data into remaining_wrapped_data
+// // and will enclose it during the the next call
+// return new SSLEngineResult(
+// SSLEngineResult.Status.BUFFER_OVERFLOW,
+// handshakeStatus, dataStream.consumed(), 0);
+// } else {
+// dst.put(remaining_wrapped_data);
+// produced = remaining_wrapped_data.length;
+// remaining_wrapped_data = null;
+// return new SSLEngineResult(getEngineStatus(),
+// handshakeStatus, dataStream.consumed(), produced);
+// }
+// } else {
+// if (remaining_hsh_data == null) {
+// remaining_hsh_data = handshakeProtocol.wrap();
+// }
+// if (capacity < remaining_hsh_data.length) {
+// // It should newer happen because we checked the destination
+// // buffer size, but there is a possibility
+// // (if dest buffer was filled outside)
+// // so we just remember the data into remaining_hsh_data
+// // and will enclose it during the the next call
+// return new SSLEngineResult(
+// SSLEngineResult.Status.BUFFER_OVERFLOW,
+// handshakeStatus, 0, 0);
+// } else {
+// dst.put(remaining_hsh_data);
+// produced = remaining_hsh_data.length;
+// remaining_hsh_data = null;
+//
+// handshakeStatus = handshakeProtocol.getStatus();
+// if (handshakeStatus.equals(
+// SSLEngineResult.HandshakeStatus.FINISHED)) {
+// session = recordProtocol.getSession();
+// }
+// }
+// return new SSLEngineResult(
+// getEngineStatus(), getHandshakeStatus(), 0, produced);
+// }
+// } catch (AlertException e) {
+// // fatal alert occured
+// alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
+// engine_was_closed = true;
+// 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();
+// }
}
-
+
// Shutdownes the engine and makes all cleanup work.
private void shutdown() {
engine_was_closed = true;
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=995839&r1=995838&r2=995839&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 Fri Sep 10 16:01:18 2010
@@ -24,9 +24,167 @@
#include "openssl/ssl.h"
#include "openssl/err.h"
+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) {
+ 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;");
+ handshake_need_wrap = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
+ fieldID = (*env)->GetStaticFieldID(env, class, "NEED_UNWRAP", "Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
+ handshake_need_unwrap = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
+ fieldID = (*env)->GetStaticFieldID(env, class, "FINISHED", "Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
+ handshake_finished = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
+ fieldID = (*env)->GetStaticFieldID(env, class, "NOT_HANDSHAKING", "Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
+ handshake_not_handshaking = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
+
+ // initialise engine status enum
+ class = (*env)->FindClass(env, "javax/net/ssl/SSLEngineResult$Status");
+ fieldID = (*env)->GetStaticFieldID(env, class, "BUFFER_OVERFLOW", "Ljavax/net/ssl/SSLEngineResult$Status;");
+ engine_buffer_overflow = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
+ fieldID = (*env)->GetStaticFieldID(env, class, "BUFFER_UNDERFLOW", "Ljavax/net/ssl/SSLEngineResult$Status;");
+ engine_buffer_underflow = (*env)->NewGlobalRef(env, (*env)->GetStaticObjectField(env, class, fieldID));
+ fieldID = (*env)->GetStaticFieldID(env, class, "CLOSED", "Ljavax/net/ssl/SSLEngineResult$Status;");
+ 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
(JNIEnv *env, jclass clazz, jlong context) {
+ init(env);
return addr2jlong(SSL_new(jlong2addr(SSL_CTX, context)));
}
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl
+ (JNIEnv *env, jclass clazz, jlong jssl) {
+ SSL *ssl = jlong2addr(SSL, jssl);
+ BIO *server, *server_out;
+ int ret;
+ size_t bufsiz = 256;
+
+ // create a bio pair
+ BIO_new_bio_pair(&server, bufsiz, &server_out, bufsiz);
+
+ SSL_set_bio(ssl, server, server);
+
+ // Put our SSL into connect state
+ SSL_set_accept_state(ssl);
+
+ // Start the client handshake
+ ret = SSL_do_handshake(ssl);
+
+ 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;
+ 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);
+
+ // Put our SSL into connect state
+ SSL_set_connect_state(ssl);
+
+ // Start the client handshake
+ ret = SSL_do_handshake(ssl);
+
+ 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,
+ jbyteArray dst, int dst_len) {
+ SSL *ssl = jlong2addr(SSL, jssl);
+ int write_result, read_result;
+ jobject handshake_state, engine_state, result;
+ jclass result_class;
+ jmethodID result_constructor;
+
+ // write input data
+ 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);
+ if (write_result > 0) {
+ // must not be handshaking as we've written bytes
+ 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;
+ }
+ free(buffer);
+
+
+ // read output data
+ buffer = (jbyte*) malloc(dst_len * sizeof(jbyte*));
+
+ read_result = SSL_read(ssl, (void *)buffer, (int)dst_len);
+ 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;
+ }
+ 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=995839&r1=995838&r2=995839&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 Fri Sep 10 16:01:18 2010
@@ -25,7 +25,12 @@ extern "C" {
JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_initImpl
(JNIEnv *, jclass, jlong);
-
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_acceptImpl
+ (JNIEnv *, jclass, jlong);
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_connectImpl
+ (JNIEnv *, jclass, jlong);
+JNIEXPORT jobject JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_wrapImpl
+ (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=995839&r1=995838&r2=995839&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 Fri Sep 10 16:01:18 2010
@@ -14,3 +14,6 @@ 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_acceptImpl
+Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_connectImpl
+Java_org_apache_harmony_xnet_provider_jsse_SSLEngineImpl_wrapImpl
Modified: harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/test/api/java/org/apache/harmony/xnet/tests/javax/net/ssl/SSLEngineTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/test/api/java/org/apache/harmony/xnet/tests/javax/net/ssl/SSLEngineTest.java?rev=995839&r1=995838&r2=995839&view=diff
==============================================================================
--- harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/test/api/java/org/apache/harmony/xnet/tests/javax/net/ssl/SSLEngineTest.java (original)
+++ harmony/enhanced/java/branches/omd/classlib/modules/x-net/src/test/api/java/org/apache/harmony/xnet/tests/javax/net/ssl/SSLEngineTest.java Fri Sep 10 16:01:18 2010
@@ -18,14 +18,15 @@
package org.apache.harmony.xnet.tests.javax.net.ssl;
import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLEngineResult;
+import org.apache.harmony.xnet.provider.jsse.JSSETestData;
+
import junit.framework.TestCase;
/**
@@ -344,6 +345,94 @@ public class SSLEngineTest extends TestC
assertEquals(1, res.bytesConsumed());
assertEquals(2, res.bytesProduced());
}
+
+ /**
+ * Test for <code>beginHandshake()</code> method
+ *
+ * Test establishing a handshake between client and server and then sending
+ * some data between them.
+ */
+ public void testHandshake() throws Exception {
+ SSLContext context = JSSETestData.getContext();
+ SSLEngine client = context.createSSLEngine();
+ client.setUseClientMode(true);
+ client.beginHandshake();
+ assertEquals(HandshakeStatus.NEED_WRAP, client.getHandshakeStatus());
+ SSLEngine server = context.createSSLEngine();
+ server.setUseClientMode(false);
+ server.beginHandshake();
+ assertEquals(HandshakeStatus.NEED_UNWRAP, server.getHandshakeStatus());
+
+ // application data
+ String clientData = "hello server";
+ String serverData = "hello client";
+
+ // create buffers
+ // output buffers contain the application data to write
+ ByteBuffer clientOutBuffer = ByteBuffer.wrap(clientData.getBytes());
+ ByteBuffer serverOutBuffer = ByteBuffer.wrap(serverData.getBytes());
+ // input buffers contain the responses to read
+ ByteBuffer clientInBuffer = ByteBuffer.allocate(client.getSession()
+ .getApplicationBufferSize());
+ ByteBuffer serverInBuffer = ByteBuffer.allocate(server.getSession()
+ .getApplicationBufferSize());
+ // transport buffers represent the network connection
+ ByteBuffer clientTransport = ByteBuffer.allocate(client.getSession()
+ .getPacketBufferSize());
+ ByteBuffer serverTransport = ByteBuffer.allocate(server.getSession()
+ .getPacketBufferSize());
+
+ SSLEngineResult result;
+ // loop trying to establish handshake between server and client
+ // break out when the application data has been written
+ while (true) {
+ // first try writing from the server/client to the transport
+ result = server.wrap(serverOutBuffer, serverTransport);
+ if (server.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable task = server.getDelegatedTask();
+ task.run();
+ }
+ result = client.wrap(clientOutBuffer, clientTransport);
+ if (client.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable task = client.getDelegatedTask();
+ task.run();
+ }
+
+ // then read from the transport to the server/client
+ serverTransport.flip();
+ clientTransport.flip();
+ result = server.unwrap(clientTransport, serverInBuffer);
+ if (server.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable task = server.getDelegatedTask();
+ task.run();
+ }
+ result = client.unwrap(serverTransport, clientInBuffer);
+ if (client.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable task = client.getDelegatedTask();
+ task.run();
+ }
+
+ // clear the buffers
+ serverTransport.clear();
+ clientTransport.clear();
+
+ // if all application data bas been written, break out
+ if (clientOutBuffer.remaining() == 0
+ && serverOutBuffer.remaining() == 0) {
+ break;
+ }
+ }
+ // check that the handshake status is correct
+ assertEquals(HandshakeStatus.NOT_HANDSHAKING, client
+ .getHandshakeStatus());
+ assertEquals(HandshakeStatus.NOT_HANDSHAKING, server
+ .getHandshakeStatus());
+ // check the data in the client and server buffers
+ assertEquals(clientData, new String(serverInBuffer.array(), 0,
+ clientData.length()));
+ assertEquals(serverData, new String(clientInBuffer.array(), 0,
+ serverData.length()));
+ }
}
/*