Search in sources :

Example 1 with SmackTlsContext

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);
}
Also used : SmackDaneVerifier(org.jivesoftware.smack.util.dns.SmackDaneVerifier) SmackTlsContext(org.jivesoftware.smack.internal.SmackTlsContext) SmackDaneProvider(org.jivesoftware.smack.util.dns.SmackDaneProvider) SSLContext(javax.net.ssl.SSLContext) TrustManager(javax.net.ssl.TrustManager) X509TrustManager(javax.net.ssl.X509TrustManager)

Example 2 with SmackTlsContext

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;
}
Also used : DnsName(org.minidns.dnsname.DnsName) SmackTlsContext(org.jivesoftware.smack.internal.SmackTlsContext) SSLSocket(javax.net.ssl.SSLSocket) CertificateException(java.security.cert.CertificateException) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) SSLSocket(javax.net.ssl.SSLSocket) Socket(java.net.Socket) Rfc6120TcpRemoteConnectionEndpoint(org.jivesoftware.smack.tcp.rce.Rfc6120TcpRemoteConnectionEndpoint) HostnameVerifier(javax.net.ssl.HostnameVerifier)

Aggregations

SmackTlsContext (org.jivesoftware.smack.internal.SmackTlsContext)2 Socket (java.net.Socket)1 CertificateException (java.security.cert.CertificateException)1 HostnameVerifier (javax.net.ssl.HostnameVerifier)1 SSLContext (javax.net.ssl.SSLContext)1 SSLSocket (javax.net.ssl.SSLSocket)1 SSLSocketFactory (javax.net.ssl.SSLSocketFactory)1 TrustManager (javax.net.ssl.TrustManager)1 X509TrustManager (javax.net.ssl.X509TrustManager)1 Rfc6120TcpRemoteConnectionEndpoint (org.jivesoftware.smack.tcp.rce.Rfc6120TcpRemoteConnectionEndpoint)1 SmackDaneProvider (org.jivesoftware.smack.util.dns.SmackDaneProvider)1 SmackDaneVerifier (org.jivesoftware.smack.util.dns.SmackDaneVerifier)1 DnsName (org.minidns.dnsname.DnsName)1