You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ad...@apache.org on 2010/01/09 15:26:31 UTC
svn commit: r897460 [2/2] - in /mina/sandbox/adc/ahc:
api/src/main/java/org/apache/ahc/api/
api/src/main/java/org/apache/ahc/api/listeners/
mina2/src/main/java/org/apache/ahc/mina2/
mina3/src/main/java/org/apache/ahc/mina3/ mina3/src/main/java/org/apac...
Added: mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/FinishedChannelState.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/FinishedChannelState.java?rev=897460&view=auto
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/FinishedChannelState.java (added)
+++ mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/FinishedChannelState.java Sat Jan 9 14:26:30 2010
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.mina.ssl;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.core.BaseChannelState;
+import org.apache.mina.core.IoBuffer;
+import org.apache.mina.core.IoProperty;
+import org.apache.mina.core.IoPropertyScope;
+import org.apache.mina.core.StateMachineChannel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public class FinishedChannelState extends BaseChannelState
+{
+ private final static Logger LOGGER = LoggerFactory.getLogger(FinishedChannelState.class);
+ private ByteBuffer byteBuffer;
+ private SSLEngine engine;
+
+ @IoProperty(name = "byteBuffer", scope = IoPropertyScope.SESSION)
+ public void setByteBuffer(ByteBuffer byteBuffer)
+ {
+ this.byteBuffer = byteBuffer;
+ }
+
+ @IoProperty(name = "engine", scope = IoPropertyScope.SESSION)
+ public void setEngine(SSLEngine engine)
+ {
+ this.engine = engine;
+ }
+
+ @Override
+ public Object send(StateMachineChannel stateMachine, Object message) throws Exception
+ {
+ IoBuffer ioBuffer = (IoBuffer) message;
+
+ engine.wrap(ioBuffer.getMessages(), byteBuffer);
+
+ return byteBuffer;
+ }
+
+ @Override
+ public Object receive(StateMachineChannel stateMachine, Object message) throws Exception
+ {
+ IoBuffer ioBuffer = (IoBuffer) message;
+
+ SSLEngineResult result = engine.unwrap(ioBuffer.getMessages()[0], byteBuffer);
+
+ if (result.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW)
+ {
+ return byteBuffer;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
Added: mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/HandshakeChannelState.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/HandshakeChannelState.java?rev=897460&view=auto
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/HandshakeChannelState.java (added)
+++ mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/HandshakeChannelState.java Sat Jan 9 14:26:30 2010
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.mina.ssl;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.core.BaseChannelState;
+import org.apache.mina.core.IoBuffer;
+import org.apache.mina.core.IoByteBufferFactory;
+import org.apache.mina.core.IoProperty;
+import org.apache.mina.core.IoPropertyScope;
+import org.apache.mina.core.StateMachineChannel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public class HandshakeChannelState extends BaseChannelState<SslStates>
+{
+ private final static Logger LOGGER = LoggerFactory.getLogger(HandshakeChannelState.class);
+ private IoByteBufferFactory factory;
+ private SSLEngine engine;
+
+ @IoProperty(name = "factory", scope = IoPropertyScope.GLOBAL)
+ public void setFactory(IoByteBufferFactory factory)
+ {
+ this.factory = factory;
+ }
+
+ @IoProperty(name = "engine", scope = IoPropertyScope.SESSION)
+ public void setEngine(SSLEngine engine)
+ {
+ this.engine = engine;
+ }
+
+ @Override
+ public Object send(StateMachineChannel<SslStates> stateMachine, Object message) throws Exception
+ {
+ IoBuffer ioBuffer = (IoBuffer) message;
+
+ ByteBuffer byteBuffer = factory.allocate(engine.getSession().getPacketBufferSize()).get();
+ SSLEngineResult result = engine.wrap(ioBuffer.getMessages(), byteBuffer);
+ if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK)
+ {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null)
+ {
+ LOGGER.trace("delegated task started");
+ runnable.run();
+ LOGGER.trace("delegated task completed");
+ }
+
+ SSLEngineResult.HandshakeStatus status = engine.getHandshakeStatus();
+ if (status == SSLEngineResult.HandshakeStatus.NEED_TASK)
+ {
+ throw new Exception("handshake shouldn't need additional tasks");
+ }
+ LOGGER.trace("handshake status: " + status);
+ }
+ factory.recycle(ioBuffer);
+
+ return byteBuffer;
+ }
+
+ @Override
+ public Object receive(StateMachineChannel<SslStates> stateMachine, Object message) throws Exception
+ {
+ IoBuffer ioBuffer = (IoBuffer) message;
+
+ ByteBuffer byteBuffer = factory.allocate(engine.getSession().getPacketBufferSize()).get();
+ SSLEngineResult result = engine.unwrap(ioBuffer.getMessages()[0], byteBuffer);
+ if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK)
+ {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null)
+ {
+ LOGGER.trace("delegated task started");
+ runnable.run();
+ LOGGER.trace("delegated task completed");
+ }
+
+ SSLEngineResult.HandshakeStatus status = engine.getHandshakeStatus();
+ if (status == SSLEngineResult.HandshakeStatus.NEED_TASK)
+ {
+ throw new Exception("handshake shouldn't need additional tasks");
+ }
+
+ LOGGER.trace("handshake status: " + status);
+ }
+ else if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP)
+ {
+ stateMachine.send(send(stateMachine, IoBuffer.EMPTY));
+ }
+ else if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED)
+ {
+ stateMachine.setState(SslStates.FINISHED);
+ }
+ factory.recycle(ioBuffer);
+
+ return byteBuffer;
+ }
+}
Copied: mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslChannel.java (from r892489, mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/core/SslChannel.java)
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslChannel.java?p2=mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslChannel.java&p1=mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/core/SslChannel.java&r1=892489&r2=897460&rev=897460&view=diff
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/core/SslChannel.java (original)
+++ mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslChannel.java Sat Jan 9 14:26:30 2010
@@ -16,41 +16,96 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.mina.core;
+package org.apache.mina.ssl;
-import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+
+import org.apache.mina.core.IoBuffer;
+import org.apache.mina.core.IoByteBufferFactory;
+import org.apache.mina.core.IoChannelState;
+import org.apache.mina.core.IoDown;
+import org.apache.mina.core.IoProperty;
+import org.apache.mina.core.IoPropertyScope;
+import org.apache.mina.core.StateMachineChannel;
/**
* @version $Revision: $ $Date: $
*/
-public class SslChannel extends AbstractIoChannel implements IoDown, IoUp
+public class SslChannel extends StateMachineChannel<SslStates>
{
- private final SSLContext context;
+ private SslConfig sslConfig;
+ private IoByteBufferFactory factory;
+ private ByteBuffer byteBuffer;
+ private SSLEngine engine;
- public SslChannel(SSLContext context)
+ public SslChannel()
{
- if (context == null) throw new IllegalArgumentException("SSL context cannot be null");
- this.context = context;
+ getStates().put(SslStates.HANDSHAKE, Collections.<IoChannelState>singletonList(new HandshakeChannelState()));
+ getStates().put(SslStates.FINISHED, Collections.<IoChannelState>singletonList(new FinishedChannelState()));
+ getStates().put(SslStates.CLOSING, Collections.<IoChannelState>singletonList(new ClosingChannelState()));
+ getStates().put(SslStates.CLOSED, Collections.<IoChannelState>singletonList(new ClosedChannelState()));
}
+ @IoProperty(name = "sslConfig", scope = IoPropertyScope.GLOBAL)
+ public void setSslConfig(SslConfig sslConfig)
+ {
+ this.sslConfig = sslConfig;
+ }
+
+ @IoProperty(name = "factory", scope = IoPropertyScope.GLOBAL)
+ public void setFactory(IoByteBufferFactory factory)
+ {
+ this.factory = factory;
+ }
+
+ @Override
public void init() throws Exception
{
- //Todo change body of implemented methods use File | Settings | File Templates.
+ sslConfig.getSslContext().init(sslConfig.getKeyManagers(), sslConfig.getTrustManagers(), sslConfig.getSecureRandom());
+
+ engine = sslConfig.getSslContext().createSSLEngine();
+
+ engine.setUseClientMode(sslConfig.isClientMode());
+ if (sslConfig.getSslProtocols() != null) engine.setEnabledProtocols(sslConfig.getSslProtocols());
+ if (sslConfig.getEnabledCipherSuites() != null) engine.setEnabledCipherSuites(sslConfig.getEnabledCipherSuites());
+
+ engine.beginHandshake();
+
+ byteBuffer = factory.allocate(engine.getSession().getPacketBufferSize()).get();
+
+ setState(SslStates.HANDSHAKE);
+
+ if (!sslConfig.isLazyHandshake())
+ {
+ HandshakeChannelState state = (HandshakeChannelState) getStates().get(SslStates.HANDSHAKE).get(0);
+ state.setByteBuffer(byteBuffer);
+ state.setEngine(engine);
+
+ IoBuffer message = (IoBuffer) state.send(this, IoBuffer.EMPTY);
+
+ for (IoDown down : getChildren()) down.send(message);
+ }
}
+ @Override
public void destroy() throws Exception
{
- //Todo change body of implemented methods use File | Settings | File Templates.
+ engine.closeInbound();
+ engine.closeOutbound();
}
- public void send(IoSession session, Object message) throws Exception
+ @IoProperty(name = "byteBuffer", scope = IoPropertyScope.SESSION)
+ public ByteBuffer getByteBuffer()
{
- //Todo change body of implemented methods use File | Settings | File Templates.
+ return byteBuffer;
}
- public void receive(IoSession session, Object message) throws Exception
+ @IoProperty(name = "engine", scope = IoPropertyScope.SESSION)
+ public SSLEngine getEngine()
{
- //Todo change body of implemented methods use File | Settings | File Templates.
+ return engine;
}
}
Added: mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslConfig.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslConfig.java?rev=897460&view=auto
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslConfig.java (added)
+++ mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslConfig.java Sat Jan 9 14:26:30 2010
@@ -0,0 +1,126 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.mina.ssl;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import java.security.SecureRandom;
+
+import org.apache.mina.core.IoConfig;
+
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public class SslConfig implements IoConfig
+{
+ private boolean lazyHandshake;
+ private boolean clientMode;
+ private SSLContext sslContext;
+ private String[] sslProtocols;
+ private KeyManager[] keyManagers;
+ private TrustManager[] trustManagers;
+ private SecureRandom secureRandom;
+ private String[] enabledCipherSuites;
+
+ public boolean isLazyHandshake()
+ {
+ return lazyHandshake;
+ }
+
+ public void setLazyHandshake(boolean lazyHandshake)
+ {
+ this.lazyHandshake = lazyHandshake;
+ }
+
+ public boolean isClientMode()
+ {
+ return clientMode;
+ }
+
+ public void setClientMode(boolean clientMode)
+ {
+ this.clientMode = clientMode;
+ }
+
+ public SSLContext getSslContext()
+ {
+ return sslContext;
+ }
+
+ public void setSslContext(SSLContext sslContext)
+ {
+ this.sslContext = sslContext;
+ }
+
+ public String[] getSslProtocols()
+ {
+ return sslProtocols;
+ }
+
+ public void setSslProtocols(String[] sslProtocols)
+ {
+ this.sslProtocols = new String[sslProtocols.length];
+ System.arraycopy(sslProtocols, 0, this.sslProtocols, 0, sslProtocols.length);
+ }
+
+ public KeyManager[] getKeyManagers()
+ {
+ return keyManagers;
+ }
+
+ public void setKeyManagers(KeyManager[] keyManagers)
+ {
+ this.keyManagers = new KeyManager[keyManagers.length];
+ System.arraycopy(keyManagers, 0, this.keyManagers, 0, keyManagers.length);
+ }
+
+ public TrustManager[] getTrustManagers()
+ {
+ return trustManagers;
+ }
+
+ public void setTrustManagers(TrustManager[] trustManagers)
+ {
+ this.trustManagers = new TrustManager[trustManagers.length];
+ System.arraycopy(trustManagers, 0, this.trustManagers, 0, trustManagers.length);
+ }
+
+ public SecureRandom getSecureRandom()
+ {
+ return secureRandom;
+ }
+
+ public void setSecureRandom(SecureRandom secureRandom)
+ {
+ this.secureRandom = secureRandom;
+ }
+
+ public String[] getEnabledCipherSuites()
+ {
+ return enabledCipherSuites;
+ }
+
+ public void setEnabledCipherSuites(String[] enabledCipherSuites)
+ {
+ this.enabledCipherSuites = new String[enabledCipherSuites.length];
+ System.arraycopy(enabledCipherSuites, 0, this.enabledCipherSuites, 0, enabledCipherSuites.length);
+ }
+}
Added: mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslStates.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslStates.java?rev=897460&view=auto
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslStates.java (added)
+++ mina/sandbox/adc/ahc/mina3/src/main/java/org/apache/mina/ssl/SslStates.java Sat Jan 9 14:26:30 2010
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.mina.ssl;
+
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public enum SslStates
+{
+ HANDSHAKE,
+ FINISHED,
+ CLOSING,
+ CLOSED;
+}
Added: mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/BenchMark.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/BenchMark.java?rev=897460&view=auto
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/BenchMark.java (added)
+++ mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/BenchMark.java Sat Jan 9 14:26:30 2010
@@ -0,0 +1,183 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.ahc;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLSession;
+import java.nio.ByteBuffer;
+
+import org.apache.ahc.mina3.EquipmentStack;
+import org.junit.Test;
+
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public class BenchMark
+{
+ @Test
+ public void test()
+ {
+ EquipmentStack stack = new EquipmentStack();
+
+ for (int i = 0; i < 1000; i++) stack.equipWith("" + i, new Object());
+
+ long start = System.currentTimeMillis();
+ final int COUNT = 100000;
+ for (int i = 0; i < COUNT; i++)
+ {
+ stack.push();
+ stack.pop();
+ }
+ long end = System.currentTimeMillis();
+ System.err.println("Time " + (double)(end - start) / 1000d + "s " + (double)(end - start) / (double)COUNT * 1000d + "us");
+ }
+
+ @Test
+ public void testSsl() throws Exception
+ {
+ SSLEngine clientEngine = generateEngine(true);
+ SSLEngine serverEngine = generateEngine(false);
+
+ ByteBuffer in = ByteBuffer.wrap(new byte[]{(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe});
+ in.flip();
+ ByteBuffer out = ByteBuffer.allocate(1024);
+
+ SSLSession session = clientEngine.getSession();
+
+ ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
+ ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
+ ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
+ ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
+
+ doHandshake(clientEngine, serverEngine, in, peerNetData);
+// SSLEngineResult result = engine.wrap(in, out);
+ }
+
+ void doHandshake(SSLEngine fromEngine, SSLEngine toEngine, ByteBuffer myAppData, ByteBuffer peerNetData) throws Exception
+ {
+ int appBufferSize = fromEngine.getSession().getApplicationBufferSize();
+ ByteBuffer myNetData = ByteBuffer.allocate(appBufferSize);
+ ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);
+
+ // Begin handshake
+ fromEngine.beginHandshake();
+ SSLEngineResult.HandshakeStatus hs = fromEngine.getHandshakeStatus();
+
+ // Process handshaking message
+ while ((hs = fromEngine.getHandshakeStatus()) != SSLEngineResult.HandshakeStatus.FINISHED &&
+ (hs = fromEngine.getHandshakeStatus()) != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
+ {
+
+ switch (hs)
+ {
+
+ case NEED_UNWRAP:
+ // Receive handshaking data from peer
+// if (socketChannel.read(peerNetData) < 0)
+// {
+// // Handle closed channel
+// }
+
+ // Process incoming handshaking data
+ peerNetData.flip();
+ SSLEngineResult res = fromEngine.unwrap(peerNetData, peerAppData);
+ peerNetData.compact();
+ hs = res.getHandshakeStatus();
+
+
+ // Check status
+ switch (res.getStatus())
+ {
+ case OK:
+ // if( hs == SSLEngineResult.HandshakeStatus.FINISHED ){
+ // break myio;
+ // }
+ break;
+ case BUFFER_OVERFLOW:
+ System.out.println("---------overflow-------");
+ break;
+ case BUFFER_UNDERFLOW:
+ System.out.println("---------underflow-------");
+ break;
+
+ // Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED
+ //...
+ }
+ break;
+
+ case NEED_WRAP:
+ // Empty the local network packet buffer.
+ myNetData.clear();
+
+ // Generate handshaking data
+ res = fromEngine.wrap(myAppData, myNetData);
+ hs = res.getHandshakeStatus();
+ //HandshakeStatus hs2 = engine.getHandshakeStatus();
+ // Check status
+ switch (res.getStatus())
+ {
+ case OK:
+ // if( hs == SSLEngineResult.HandshakeStatus.FINISHED ){
+ // break myio;
+ // }
+ myNetData.flip();
+
+ // Send the handshaking data to peer
+ while (!myNetData.hasRemaining())
+ {
+// if (socketChannel.write(myNetData) < 0)
+// {
+// // Handle closed channel
+// }
+ }
+
+ break;
+
+ // Handle other status: BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED
+ //...
+ }
+ break;
+
+ case NEED_TASK:
+ new Thread(fromEngine.getDelegatedTask()).start();
+ // Handle blocking tasks
+ break;
+
+ // Handle other status: // FINISHED or NOT_HANDSHAKING
+ //...
+ }
+ }
+
+ // Processes after handshaking
+ //...
+ }
+
+ SSLEngine generateEngine(boolean isClient) throws Exception
+ {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, null, null);
+ SSLEngine engine = context.createSSLEngine();
+ engine.setUseClientMode(isClient);
+
+ return engine;
+ }
+}
Added: mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/SSLEngineSimpleDemo.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/SSLEngineSimpleDemo.java?rev=897460&view=auto
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/SSLEngineSimpleDemo.java (added)
+++ mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/SSLEngineSimpleDemo.java Sat Jan 9 14:26:30 2010
@@ -0,0 +1,400 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.ahc;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.FileInputStream;
+import java.nio.ByteBuffer;
+import java.security.KeyStore;
+
+
+/**
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ * <p/>
+ * The demo creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two ByteBuffers: think of them
+ * as directly connected pipes.
+ * <p/>
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ * <p/>
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ * <p/>
+ * client server message
+ * ====== ====== =======
+ * wrap() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * unwrap() ... ServerHello/Certificate
+ * wrap() ... ClientKeyExchange
+ * wrap() ... ChangeCipherSpec
+ * wrap() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * unwrap() ... ChangeCipherSpec
+ * unwrap() ... Finished
+ *
+ * @version $Revision: $ $Date: $
+ */
+public class SSLEngineSimpleDemo
+{
+ /*
+ * Enables logging of the SSLEngine operations.
+ */
+ private static boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static boolean debug = false;
+
+ private SSLContext sslc;
+
+ private SSLEngine clientEngine; // client Engine
+ private ByteBuffer clientOut; // write side of clientEngine
+ private ByteBuffer clientIn; // read side of clientEngine
+
+ private SSLEngine serverEngine; // server Engine
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ /*
+ * For data transport, this example uses local ByteBuffers. This
+ * isn't really useful, but the purpose of this example is to show
+ * SSLEngine concepts, not how to do network transport.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores.
+ */
+ private static String keyStoreFile = "testkeys";
+ private static String trustStoreFile = "testkeys";
+ private static String passwd = "passphrase";
+
+ /*
+ * Main entry point for this demo.
+ */
+
+ public static void main(String args[]) throws Exception
+ {
+ if (debug)
+ {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ SSLEngineSimpleDemo demo = new SSLEngineSimpleDemo();
+ demo.runDemo();
+
+ System.out.println("Demo Completed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for this demo.
+ */
+
+ public SSLEngineSimpleDemo() throws Exception
+ {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyStoreFile), passphrase);
+ ts.load(new FileInputStream(trustStoreFile), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+ }
+
+ /*
+ * Run the demo.
+ *
+ * Sit in a tight loop, both engines calling wrap/unwrap regardless
+ * of whether data is available or not. We do this until both engines
+ * report back they are closed.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+
+ private void runDemo() throws Exception
+ {
+ boolean dataDone = false;
+
+ createSSLEngines();
+ createBuffers();
+
+ SSLEngineResult clientResult; // results from client's last operation
+ SSLEngineResult serverResult; // results from server's last operation
+
+ /*
+ * Examining the SSLEngineResults could be much more involved,
+ * and may alter the overall flow of the application.
+ *
+ * For example, if we received a BUFFER_OVERFLOW when trying
+ * to write to the output pipe, we could reallocate a larger
+ * pipe, but instead we wait for the peer to drain it.
+ */
+ while (!isEngineClosed(clientEngine) ||
+ !isEngineClosed(serverEngine))
+ {
+
+ log("================");
+
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+
+ cTOs.flip();
+ sTOc.flip();
+
+ log("----");
+
+ clientResult = clientEngine.unwrap(sTOc, clientIn);
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+
+ cTOs.compact();
+ sTOc.compact();
+
+ /*
+ * After we've transfered all application data between the client
+ * and server, we close the clientEngine's outbound stream.
+ * This generates a close_notify handshake message, which the
+ * server engine receives and responds by closing itself.
+ *
+ * In normal operation, each SSLEngine should call
+ * closeOutbound(). To protect against truncation attacks,
+ * SSLEngine.closeInbound() should be called whenever it has
+ * determined that no more input data will ever be
+ * available (say a closed input stream).
+ */
+ if (!dataDone && (clientOut.limit() == serverIn.position()) &&
+ (serverOut.limit() == clientIn.position()))
+ {
+
+ /*
+ * A sanity check to ensure we got what was sent.
+ */
+ checkTransfer(serverOut, clientIn);
+ checkTransfer(clientOut, serverIn);
+
+ log("\tClosing clientEngine's *OUTBOUND*...");
+ clientEngine.closeOutbound();
+ // serverEngine.closeOutbound();
+ dataDone = true;
+ }
+ }
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this demo.
+ */
+
+ private void createSSLEngines() throws Exception
+ {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake. Also, require SSL client authentication.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ serverEngine.setNeedClientAuth(true);
+
+ /*
+ * Similar to above, but using client mode instead.
+ */
+ clientEngine = sslc.createSSLEngine("client", 80);
+ clientEngine.setUseClientMode(true);
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+
+ private void createBuffers()
+ {
+ /*
+ * We'll assume the buffer sizes are the same
+ * between client and server.
+ */
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception
+ {
+
+ if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK)
+ {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null)
+ {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ SSLEngineResult.HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK)
+ {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine)
+ {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Simple check to make sure everything came across as expected.
+ */
+
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception
+ {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b))
+ {
+ throw new Exception("Data didn't transfer cleanly");
+ }
+ else
+ {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result)
+ {
+ if (!logging)
+ {
+ return;
+ }
+ if (resultOnce)
+ {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n" +
+ "\t\"getStatus() / getHandshakeStatus()\" +\n" +
+ "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ SSLEngineResult.HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str +
+ result.getStatus() + "/" + hsStatus + ", " +
+ result.bytesConsumed() + "/" + result.bytesProduced() +
+ " bytes");
+ if (hsStatus == SSLEngineResult.HandshakeStatus.FINISHED)
+ {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str)
+ {
+ if (logging)
+ {
+ System.out.println(str);
+ }
+ }
+}
\ No newline at end of file
Modified: mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/api/ClientTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/api/ClientTest.java?rev=897460&r1=897459&r2=897460&view=diff
==============================================================================
--- mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/api/ClientTest.java (original)
+++ mina/sandbox/adc/ahc/mina3/src/test/java/org/apache/ahc/api/ClientTest.java Sat Jan 9 14:26:30 2010
@@ -38,6 +38,8 @@
import com.acme.ahc.listeners.AcmeSslBenchmarkListener;
import com.acme.ahc.listeners.AcmeSslCertificatManager;
import org.apache.ahc.api.listeners.MimeContentListener;
+import org.apache.ahc.mina3.AsyncHttpClient;
+import org.apache.ahc.mina3.AsyncHttpRequest;
import org.junit.Test;
@@ -49,7 +51,7 @@
@Test
void testBatch() throws Exception
{
- HttpClient client = new AcmeHttpClient();
+ HttpClient client = new AsyncHttpClient();
client.equipWith(new AcmeSslCertificatManager());
client.equipWith("CLIENT_ID", "92341");
@@ -83,7 +85,7 @@
@Test
void testSend() throws Exception
{
- HttpClient client = new AcmeHttpClient();
+ HttpClient client = new AsyncHttpClient();
HttpResponse response = client.get("http://rest.acme.com/rest/student/41134?token=dFWEGV8ss63dmcs0245c")
.register(new FutureListener<HttpResponse>()
@@ -104,9 +106,9 @@
@Test
void testSendMultipleAttachments() throws Exception
{
- HttpClient client = new AcmeHttpClient();
+ HttpClient client = new AsyncHttpClient();
- HttpRequest request = new AcmeHttpRequest();
+ HttpRequest request = new AsyncHttpRequest();
request.setUrl(new URL("http://rest.acme.com/rest/student/41134?token=dFWEGV8ss63dmcs0245"))
.addMimeContent(generateXml())
@@ -118,9 +120,9 @@
@Test
void testReceiveMultipleAttachments() throws Exception
{
- HttpClient client = new AcmeHttpClient();
+ HttpClient client = new AsyncHttpClient();
- HttpRequest request = new AcmeHttpRequest();
+ HttpRequest request = new AsyncHttpRequest();
request.setUrl(new URL("http://rest.acme.com/rest/student/41134?token=dFWEGV8ss63dmcs0245"))
.addMimeContentListener(new MimeContentListener()