use of org.jivesoftware.smack.internal.SmackTlsContext in project Smack by igniterealtime.
the class ConnectionConfiguration method getSmackTlsContext.
private static SmackTlsContext getSmackTlsContext(DnssecMode dnssecMode, SslContextFactory sslContextFactory, X509TrustManager trustManager, KeyManager[] keyManagers, SecureRandom secureRandom, String keystoreType, String keystorePath, CallbackHandler callbackHandler, String pkcs11Library) throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, NoSuchProviderException, UnrecoverableKeyException, KeyManagementException, UnsupportedCallbackException, NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final SSLContext context;
if (sslContextFactory != null) {
context = sslContextFactory.createSslContext();
} else {
// If the user didn't specify a SslContextFactory, use the default one
context = SSLContext.getInstance("TLS");
}
// setPKCS11Library() in the builder, and all related fields and the parameters of this function.
if (keyManagers == null) {
keyManagers = Builder.getKeyManagersFrom(keystoreType, keystorePath, callbackHandler, pkcs11Library);
}
SmackDaneVerifier daneVerifier = null;
if (dnssecMode == DnssecMode.needsDnssecAndDane) {
SmackDaneProvider daneProvider = DNSUtil.getDaneProvider();
if (daneProvider == null) {
throw new UnsupportedOperationException("DANE enabled but no SmackDaneProvider configured");
}
daneVerifier = daneProvider.newInstance();
if (daneVerifier == null) {
throw new IllegalStateException("DANE requested but DANE provider did not return a DANE verifier");
}
// User requested DANE verification.
daneVerifier.init(context, keyManagers, trustManager, secureRandom);
} else {
final TrustManager[] trustManagers;
if (trustManager != null) {
trustManagers = new TrustManager[] { trustManager };
} else {
// Ensure trustManagers is null in case there was no explicit trust manager provided, so that the
// default one is used.
trustManagers = null;
}
context.init(keyManagers, trustManagers, secureRandom);
}
return new SmackTlsContext(context, daneVerifier);
}
use of org.jivesoftware.smack.internal.SmackTlsContext in project Smack by igniterealtime.
the class XMPPTCPConnection method proceedTLSReceived.
/**
* The server has indicated that TLS negotiation can start. We now need to secure the
* existing plain connection and perform a handshake. This method won't return until the
* connection has finished the handshake or an error occurred while securing the connection.
* @throws IOException if an I/O error occurred.
* @throws SecurityNotPossibleException if TLS is not possible.
* @throws CertificateException if there is an issue with the certificate.
*/
@SuppressWarnings("LiteralClassName")
private void proceedTLSReceived() throws IOException, SecurityNotPossibleException, CertificateException {
SmackTlsContext smackTlsContext = getSmackTlsContext();
Socket plain = socket;
int port = plain.getPort();
String xmppServiceDomainString = config.getXMPPServiceDomain().toString();
SSLSocketFactory sslSocketFactory = smackTlsContext.sslContext.getSocketFactory();
// Secure the plain connection
socket = sslSocketFactory.createSocket(plain, xmppServiceDomainString, port, true);
final SSLSocket sslSocket = (SSLSocket) socket;
// Immediately set the enabled SSL protocols and ciphers. See SMACK-712 why this is
// important (at least on certain platforms) and it seems to be a good idea anyways to
// prevent an accidental implicit handshake.
TLSUtils.setEnabledProtocolsAndCiphers(sslSocket, config.getEnabledSSLProtocols(), config.getEnabledSSLCiphers());
// Initialize the reader and writer with the new secured version
initReaderAndWriter();
// Proceed to do the handshake
sslSocket.startHandshake();
if (smackTlsContext.daneVerifier != null) {
smackTlsContext.daneVerifier.finish(sslSocket.getSession());
}
final HostnameVerifier verifier = getConfiguration().getHostnameVerifier();
if (verifier == null) {
throw new IllegalStateException("No HostnameVerifier set. Use connectionConfiguration.setHostnameVerifier() to configure.");
}
final String verifierHostname;
{
DnsName xmppServiceDomainDnsName = getConfiguration().getXmppServiceDomainAsDnsNameIfPossible();
// See also: https://bugzilla.mozilla.org/show_bug.cgi?id=280839#c1
if (xmppServiceDomainDnsName != null) {
verifierHostname = xmppServiceDomainDnsName.ace;
} else {
LOGGER.log(Level.WARNING, "XMPP service domain name '" + getXMPPServiceDomain() + "' can not be represented as DNS name. TLS X.509 certificate validiation may fail.");
verifierHostname = getXMPPServiceDomain().toString();
}
}
final boolean verificationSuccessful;
// Verify the TLS session.
verificationSuccessful = verifier.verify(verifierHostname, sslSocket.getSession());
if (!verificationSuccessful) {
throw new CertificateException("Hostname verification of certificate failed. Certificate does not authenticate " + getXMPPServiceDomain());
}
// Set that TLS was successful
secureSocket = sslSocket;
}
Aggregations