Skip to content

Instantly share code, notes, and snippets.

@bambuchaAdm
Last active February 27, 2019 08:54
Show Gist options
  • Save bambuchaAdm/11b65ef7d6a787bcb3312a1d59b5cafd to your computer and use it in GitHub Desktop.
Save bambuchaAdm/11b65ef7d6a787bcb3312a1d59b5cafd to your computer and use it in GitHub Desktop.
Note about SSLEngine
package example
import java.net.InetSocketAddress
import java.nio.ByteBuffer
import java.nio.channels.SocketChannel
import java.nio.charset.Charset
import java.util
import com.mongodb.ServerAddress
import com.mongodb.connection.{AsyncCompletionHandler, SocketSettings, SslSettings, Stream, StreamFactory, StreamFactoryFactory}
import javax.net.ssl.SSLEngineResult.HandshakeStatus
import javax.net.ssl.SSLEngineResult.Status
import javax.net.ssl.{SSLContext, SSLEngine, SSLEngineResult}
import org.bson.ByteBuf
import scala.annotation.tailrec
import scala.collection.JavaConverters._
class TunneledStremaFactoryFactory extends StreamFactoryFactory {
override def create(socketSettings: SocketSettings, sslSettings: SslSettings): StreamFactory = ???
}
class TunneledStreamFactory(sslContext: SSLContext) extends StreamFactory {
override def create(serverAddress: ServerAddress): Stream = {
val engine = sslContext.createSSLEngine()
engine.setUseClientMode(true)
new TunneledStream(serverAddress.getSocketAddress, engine)
}
}
class TunneledStream(address: InetSocketAddress, sslEngine: SSLEngine) extends Stream {
def proxyHandshake = {
ByteBuffer.wrap(
"""CONNECT example.host.com:22 HTTP/1.1
|Proxy-Authorization: Basic encoded-credentials
""".stripMargin.getBytes(Charset.forName("utf8"))
)
}
val channel: SocketChannel = SocketChannel.open()
val fromChannel: ByteBuffer = {
ByteBuffer.allocate(sslEngine.getSession.getApplicationBufferSize + 50)
}
val toChannel: ByteBuffer = {
ByteBuffer.allocate(sslEngine.getSession.getPacketBufferSize + 50)
}
val outgress: ByteBuffer = {
ByteBuffer.allocate(sslEngine.getSession.getApplicationBufferSize + 50)
}
val ingress: ByteBuffer = {
ByteBuffer.allocate(sslEngine.getSession.getPacketBufferSize + 50)
}
@tailrec
private def executeDelegatedTask(engine: SSLEngine): Unit = {
val task = engine.getDelegatedTask
if(task != null){
task.run()
executeDelegatedTask(engine)
}
}
private def unwrap()= {
val read = channel.read(fromChannel)
fromChannel.flip()
sslEngine.unwrap(ingress, toChannel).getStatus match {
case Status.BUFFER_OVERFLOW =>
case Status.BUFFER_UNDERFLOW =>
case Status.CLOSED =>
case Status.OK => // OK
}
}
private def handshake(): Unit ={
sslEngine.beginHandshake()
sslEngine.getHandshakeStatus match {
case HandshakeStatus.FINISHED => // OK
case HandshakeStatus.NEED_TASK => executeDelegatedTask(sslEngine)
case HandshakeStatus.NEED_UNWRAP | HandshakeStatus.NEED_UNWRAP_AGAIN =>
case HandshakeStatus.NEED_WRAP =>
}
}
override def open(): Unit = {
channel.connect(address)
channel.write(proxyHandshake)
channel.read(outgress)
// here assertion
executeDelegatedTask(sslEngine)
}
override def openAsync(handler: AsyncCompletionHandler[Void]): Unit = ???
override def write(buffers: util.List[ByteBuf]): Unit = {
val array = buffers.toArray(Array.ofDim(buffers.))
buffers.asScala.foreach { buffer =>
sslEngine.wrap()
}
}
override def read(numBytes: Int): ByteBuf = ???
override def writeAsync(buffers: util.List[ByteBuf], handler: AsyncCompletionHandler[Void]): Unit = ???
override def readAsync(numBytes: Int, handler: AsyncCompletionHandler[ByteBuf]): Unit = ???
override def getAddress: ServerAddress = ???
override def close(): Unit = ???
override def isClosed: Boolean = ???
override def getBuffer(size: Int): ByteBuf = ???
}
class Main extends App {
}
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment