mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
SMACK-376 Allow supplying a custom SSLContext for encrypted connections.
The provided TrustManager / SSLContext implementation is very flexible, but it does not allow to query the user about accepting possibly invalid SSL certificates. By supplying a custom SSLContext with a TrustManager implementing such a query mechanism it is possible to implement this behaviour. The patch adds ConnectionConfiguration.customSSLContext with appropriate getter/setter methods and uses the custom context in XMPPConnection. Signed-Off-By: Georg Lukas <georg@op-co.de> git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@13520 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
c57843eeee
commit
da1987a98b
2 changed files with 28 additions and 5 deletions
|
@ -24,6 +24,7 @@ import org.jivesoftware.smack.proxy.ProxyInfo;
|
||||||
import org.jivesoftware.smack.util.DNSUtil;
|
import org.jivesoftware.smack.util.DNSUtil;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.security.auth.callback.CallbackHandler;
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ public class ConnectionConfiguration implements Cloneable {
|
||||||
private boolean selfSignedCertificateEnabled = false;
|
private boolean selfSignedCertificateEnabled = false;
|
||||||
private boolean expiredCertificatesCheckEnabled = false;
|
private boolean expiredCertificatesCheckEnabled = false;
|
||||||
private boolean notMatchingDomainCheckEnabled = false;
|
private boolean notMatchingDomainCheckEnabled = false;
|
||||||
|
private SSLContext customSSLContext;
|
||||||
|
|
||||||
private boolean compressionEnabled = false;
|
private boolean compressionEnabled = false;
|
||||||
|
|
||||||
|
@ -486,6 +488,25 @@ public class ConnectionConfiguration implements Cloneable {
|
||||||
this.notMatchingDomainCheckEnabled = notMatchingDomainCheckEnabled;
|
this.notMatchingDomainCheckEnabled = notMatchingDomainCheckEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the custom SSLContext for SSL sockets. This is null by default.
|
||||||
|
*
|
||||||
|
* @return the SSLContext previously set with setCustomSSLContext() or null.
|
||||||
|
*/
|
||||||
|
public SSLContext getCustomSSLContext() {
|
||||||
|
return this.customSSLContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a custom SSLContext for creating SSL sockets. A custom Context causes all other
|
||||||
|
* SSL/TLS realted settings to be ignored.
|
||||||
|
*
|
||||||
|
* @param context the custom SSLContext for new sockets; null to reset default behavior.
|
||||||
|
*/
|
||||||
|
public void setCustomSSLContext(SSLContext context) {
|
||||||
|
this.customSSLContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the connection is going to use stream compression. Stream compression
|
* Returns true if the connection is going to use stream compression. Stream compression
|
||||||
* will be requested after TLS was established (if TLS was enabled) and only if the server
|
* will be requested after TLS was established (if TLS was enabled) and only if the server
|
||||||
|
|
|
@ -763,14 +763,14 @@ public class XMPPConnection extends Connection {
|
||||||
* @throws Exception if an exception occurs.
|
* @throws Exception if an exception occurs.
|
||||||
*/
|
*/
|
||||||
void proceedTLSReceived() throws Exception {
|
void proceedTLSReceived() throws Exception {
|
||||||
SSLContext context = SSLContext.getInstance("TLS");
|
SSLContext context = this.config.getCustomSSLContext();
|
||||||
KeyStore ks = null;
|
KeyStore ks = null;
|
||||||
KeyManager[] kms = null;
|
KeyManager[] kms = null;
|
||||||
PasswordCallback pcb = null;
|
PasswordCallback pcb = null;
|
||||||
|
|
||||||
if(config.getCallbackHandler() == null) {
|
if(config.getCallbackHandler() == null) {
|
||||||
ks = null;
|
ks = null;
|
||||||
} else {
|
} else if (context == null) {
|
||||||
//System.out.println("Keystore type: "+configuration.getKeystoreType());
|
//System.out.println("Keystore type: "+configuration.getKeystoreType());
|
||||||
if(config.getKeystoreType().equals("NONE")) {
|
if(config.getKeystoreType().equals("NONE")) {
|
||||||
ks = null;
|
ks = null;
|
||||||
|
@ -826,9 +826,11 @@ public class XMPPConnection extends Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify certificate presented by the server
|
// Verify certificate presented by the server
|
||||||
context.init(kms,
|
if (context == null) {
|
||||||
new javax.net.ssl.TrustManager[]{new ServerTrustManager(getServiceName(), config)},
|
context = SSLContext.getInstance("TLS");
|
||||||
new java.security.SecureRandom());
|
context.init(kms, new javax.net.ssl.TrustManager[] { new ServerTrustManager(getServiceName(), config) },
|
||||||
|
new java.security.SecureRandom());
|
||||||
|
}
|
||||||
Socket plain = socket;
|
Socket plain = socket;
|
||||||
// Secure the plain connection
|
// Secure the plain connection
|
||||||
socket = context.getSocketFactory().createSocket(plain,
|
socket = context.getSocketFactory().createSocket(plain,
|
||||||
|
|
Loading…
Reference in a new issue