Search code examples
androidejabberdsmack

SMACK 4.2.4 connection with ejabberd through TLS


I have been working with ejabberd and smack 4.2.4. It was fine until I implemented TLS certificate from LetsEncrypt. Now it gives SSL handshake error.

Same secure connection works for iOS and other clients if I enable TLS in connection configuration.

I searched but could find any idea how to fix this. Please help for Android connection.

Thanks,


Solution

  • I spent time and finally got this solution working for me.

    configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
    SSLContext sslContext = getSSLContext(context);
    configBuilder.setCustomSSLContext(sslContext);
    
    
    public SSLContext getSSLContext(Context context ) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
            CertificateFactory cf = null;
    
            try {
                cf = CertificateFactory.getInstance("X.509");
            } catch (CertificateException e) {
                Log.e(TAG, e.getMessage());
            }
    
            InputStream in = context.getResources().openRawResource(R.raw.chain); // R.raw.chain is CA Root Certificate added in RAW resources folder
    
            InputStream caInput = new BufferedInputStream(in);
            Certificate ca = null;
            try {
                ca = cf.generateCertificate(caInput);
                Log.d(TAG, "ca=" + ((X509Certificate) ca).getSubjectDN());
            }
            catch (Exception e){
                Log.e(TAG, e.getMessage());
            }
            finally {
                caInput.close();
            }
    
            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);
    
            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
    
            // Create an SSLContext that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            return sslContext;
    
        }