Skip to content

Commit

Permalink
try to do smt SSLContext.session= is set and also try answering ses…
Browse files Browse the repository at this point in the history
…sion_reused?

... this might resolve issues such as net/http using session= to force session re-use
kares committed Mar 30, 2016
1 parent 916ef9b commit f12aab2
Showing 3 changed files with 49 additions and 9 deletions.
6 changes: 4 additions & 2 deletions src/main/java/org/jruby/ext/openssl/SSLContext.java
Original file line number Diff line number Diff line change
@@ -662,10 +662,12 @@ private static SSLEngine dummySSLEngine(final String protocol) throws GeneralSec
}

// should keep SSLContext as a member for introducin SSLSession. later...
SSLEngine createSSLEngine(String peerHost, int peerPort) throws NoSuchAlgorithmException, KeyManagementException {
final SSLEngine createSSLEngine(String peerHost, int peerPort)
throws NoSuchAlgorithmException, KeyManagementException {
final SSLEngine engine;
// an empty peerHost implies no SNI (RFC 3546) support requested
if (peerHost == null || peerHost.length() == 0) {
if ( peerHost == null || peerHost.length() == 0 ) {
// no hints for an internal session reuse strategy
engine = internalContext.getSSLContext().createSSLEngine();
}
// SNI is attempted for valid peerHost hostname on Java >= 7
3 changes: 2 additions & 1 deletion src/main/java/org/jruby/ext/openssl/SSLSession.java
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@
import static org.jruby.ext.openssl.OpenSSL._OpenSSLError;
import static org.jruby.ext.openssl.OpenSSL.warn;
import static org.jruby.ext.openssl.SSL._SSL;
import static org.jruby.ext.openssl.OpenSSL.warn;

/**
* OpenSSL::SSL::Session
@@ -88,7 +89,7 @@ public IRubyObject initialize(final ThreadContext context, final IRubyObject arg
}

SSLSession initializeImpl(final ThreadContext context, final SSLSocket socket) {
sslSession = socket.getSession();
sslSession = socket.sslSession();
return this;
}

49 changes: 43 additions & 6 deletions src/main/java/org/jruby/ext/openssl/SSLSocket.java
Original file line number Diff line number Diff line change
@@ -1009,21 +1009,45 @@ public IRubyObject pending() {
return getRuntime().getNil();
}

private boolean reusableSSLEngine() {
if ( engine != null ) {
final String peerHost = engine.getPeerHost();
if ( peerHost != null && peerHost.length() > 0 ) {
// NOT getSSLContext().createSSLEngine() - no hints for session reuse
return true;
}
}
return false;
}

@JRubyMethod(name = "session_reused?")
public IRubyObject session_reused_p() {
warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session_reused? is not supported");
return getRuntime().getNil(); // throw new UnsupportedOperationException();
if ( reusableSSLEngine() ) {
if ( ! engine.getEnableSessionCreation() ) {
// if session creation is disabled we can be sure its to be re-used
return getRuntime().getTrue();
}
//return getRuntime().getFalse(); // NOTE: likely incorrect (we can not decide)
}
//warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session_reused? is not supported");
return getRuntime().getNil(); // can not decide - probably not
}

final javax.net.ssl.SSLSession getSession() {
// JSSE: SSL Sessions can be reused only if connecting to the same host at the same port

final javax.net.ssl.SSLSession sslSession() {
return engine == null ? null : engine.getSession();
}

private transient SSLSession session;

@JRubyMethod(name = "session")
public IRubyObject session(final ThreadContext context) {
if ( getSession() == null ) return context.nil;
if ( sslSession() == null ) return context.nil;
return getSession(context);
}

private SSLSession getSession(final ThreadContext context) {
if ( session == null ) {
return session = new SSLSession(context.runtime).initializeImpl(context, this);
}
@@ -1032,8 +1056,21 @@ public IRubyObject session(final ThreadContext context) {

@JRubyMethod(name = "session=")
public IRubyObject set_session(IRubyObject session) {
warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session= is not supported");
return getRuntime().getNil(); // throw new UnsupportedOperationException();
final ThreadContext context = getRuntime().getCurrentContext();
// NOTE: we can not fully support this without the SSL provider internals
// but we can assume setting a session= is meant as a forced session re-use
if ( reusableSSLEngine() ) {
engine.setEnableSessionCreation(false);
if ( session instanceof SSLSession ) {
final SSLSession theSession = (SSLSession) session;
if ( ! theSession.equals( getSession(context) ) ) {
getSession(context).set_timeout(context, theSession.timeout(context));
}
}
return getSession(context);
}
warn(context, "WARNING: SSLSocket#session= has not effect");
return context.nil;
}

@JRubyMethod

0 comments on commit f12aab2

Please sign in to comment.