Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51839cc5 authored by cketti's avatar cketti
Browse files

Change TrustManager to return list of "accepted issuers"

parent 0f1bc05e
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
package com.fsck.k9.mail.helpers;


import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;


public class KeyStoreProvider {
    private static final String KEYSTORE_PASSWORD = "password";
    private static final String KEYSTORE_RESOURCE = "/keystore.jks";
    private static final String SERVER_CERTIFICATE_ALIAS = "mockimapserver";


    private final KeyStore keyStore;


    public static KeyStoreProvider getInstance() {
        KeyStore keyStore = loadKeyStore();
        return new KeyStoreProvider(keyStore);
    }

    private static KeyStore loadKeyStore() {
        try {
            KeyStore keyStore = KeyStore.getInstance("JKS");

            InputStream keyStoreInputStream = KeyStoreProvider.class.getResourceAsStream(KEYSTORE_RESOURCE);
            try {
                keyStore.load(keyStoreInputStream, KEYSTORE_PASSWORD.toCharArray());
            } finally {
                keyStoreInputStream.close();
            }

            return keyStore;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private KeyStoreProvider(KeyStore keyStore) {
        this.keyStore = keyStore;
    }

    public KeyStore getKeyStore() {
        return keyStore;
    }

    public char[] getPassword() {
        return KEYSTORE_PASSWORD.toCharArray();
    }

    public X509Certificate getServerCertificate() {
        try {
            KeyStore keyStore = loadKeyStore();
            return (X509Certificate) keyStore.getCertificate(SERVER_CERTIFICATE_ALIAS);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        }
    }
}
+14 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import java.io.IOException;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
@@ -14,11 +15,23 @@ import javax.net.ssl.TrustManager;


public class TestTrustedSocketFactory implements TrustedSocketFactory {
    private final X509Certificate serverCertificate;


    public static TestTrustedSocketFactory newInstance() {
        X509Certificate serverCertificate = KeyStoreProvider.getInstance().getServerCertificate();
        return new TestTrustedSocketFactory(serverCertificate);
    }

    private TestTrustedSocketFactory(X509Certificate serverCertificate) {
        this.serverCertificate = serverCertificate;
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, String clientCertificateAlias)
            throws NoSuchAlgorithmException, KeyManagementException, MessagingException, IOException {

        TrustManager[] trustManagers = new TrustManager[] { new VeryTrustingTrustManager() };
        TrustManager[] trustManagers = new TrustManager[] { new VeryTrustingTrustManager(serverCertificate) };

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagers, null);
+8 −1
Original line number Diff line number Diff line
@@ -10,6 +10,13 @@ import javax.net.ssl.X509TrustManager;

@SuppressLint("TrustAllX509TrustManager")
class VeryTrustingTrustManager implements X509TrustManager {
    private final X509Certificate serverCertificate;


    public VeryTrustingTrustManager(X509Certificate serverCertificate) {
        this.serverCertificate = serverCertificate;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        // Accept all certificates
@@ -22,7 +29,7 @@ class VeryTrustingTrustManager implements X509TrustManager {

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
        return new X509Certificate[] { serverCertificate };
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ public class ImapConnectionTest {
    public void setUp() throws Exception {
        connectivityManager = mock(ConnectivityManager.class);
        oAuth2TokenProvider = createOAuth2TokenProvider();
        socketFactory = new TestTrustedSocketFactory();
        socketFactory = TestTrustedSocketFactory.newInstance();

        settings = new SimpleImapSettings();
        settings.setUsername(USERNAME);
+12 −23
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import java.util.zip.InflaterInputStream;

import android.annotation.SuppressLint;

import com.fsck.k9.mail.helpers.KeyStoreProvider;
import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZOutputStream;
import javax.net.ssl.KeyManagerFactory;
@@ -37,15 +38,13 @@ import org.apache.commons.io.IOUtils;

@SuppressLint("NewApi")
public class MockImapServer {
    private static final String KEYSTORE_PASSWORD = "password";
    private static final String KEYSTORE_RESOURCE = "/keystore.jks";

    private static final byte[] CRLF = { '\r', '\n' };


    private final Deque<ImapInteraction> interactions = new ConcurrentLinkedDeque<>();
    private final CountDownLatch waitForConnectionClosed = new CountDownLatch(1);
    private final CountDownLatch waitForAllExpectedCommands = new CountDownLatch(1);
    private final KeyStoreProvider keyStoreProvider;
    private final Logger logger;

    private MockServerThread mockServerThread;
@@ -54,10 +53,11 @@ public class MockImapServer {


    public MockImapServer() {
        this(new DefaultLogger());
        this(KeyStoreProvider.getInstance(), new DefaultLogger());
    }

    public MockImapServer(Logger logger) {
    public MockImapServer(KeyStoreProvider keyStoreProvider, Logger logger) {
        this.keyStoreProvider = keyStoreProvider;
        this.logger = logger;
    }

@@ -96,7 +96,7 @@ public class MockImapServer {
        port = serverSocket.getLocalPort();

        mockServerThread = new MockServerThread(serverSocket, interactions, waitForConnectionClosed,
                waitForAllExpectedCommands, logger);
                waitForAllExpectedCommands, logger, keyStoreProvider);
        mockServerThread.start();
    }

@@ -236,6 +236,7 @@ public class MockImapServer {
        private final CountDownLatch waitForConnectionClosed;
        private final CountDownLatch waitForAllExpectedCommands;
        private final Logger logger;
        private final KeyStoreProvider keyStoreProvider;

        private volatile boolean shouldStop = false;
        private volatile Socket clientSocket;
@@ -246,13 +247,15 @@ public class MockImapServer {


        public MockServerThread(ServerSocket serverSocket, Deque<ImapInteraction> interactions,
                CountDownLatch waitForConnectionClosed, CountDownLatch waitForAllExpectedCommands, Logger logger) {
                CountDownLatch waitForConnectionClosed, CountDownLatch waitForAllExpectedCommands, Logger logger,
                KeyStoreProvider keyStoreProvider) {
            super("MockImapServer");
            this.serverSocket = serverSocket;
            this.interactions = interactions;
            this.waitForConnectionClosed = waitForConnectionClosed;
            this.waitForAllExpectedCommands = waitForAllExpectedCommands;
            this.logger = logger;
            this.keyStoreProvider = keyStoreProvider;
        }

        @Override
@@ -356,11 +359,11 @@ public class MockImapServer {
        private void upgradeToTls(Socket socket) throws KeyStoreException, IOException, NoSuchAlgorithmException,
                CertificateException, UnrecoverableKeyException, KeyManagementException {

            KeyStore keyStore = loadKeyStore();
            KeyStore keyStore = keyStoreProvider.getKeyStore();

            String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(defaultAlgorithm);
            keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
            keyManagerFactory.init(keyStore, keyStoreProvider.getPassword());

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
@@ -375,20 +378,6 @@ public class MockImapServer {
            output = Okio.buffer(Okio.sink(sslSocket.getOutputStream()));
        }

        private KeyStore loadKeyStore() throws KeyStoreException, IOException, NoSuchAlgorithmException,
                CertificateException {
            KeyStore keyStore = KeyStore.getInstance("JKS");

            InputStream keyStoreInputStream = getClass().getResourceAsStream(KEYSTORE_RESOURCE);
            try {
                keyStore.load(keyStoreInputStream, KEYSTORE_PASSWORD.toCharArray());
            } finally {
                keyStoreInputStream.close();
            }

            return keyStore;
        }

        private void readAdditionalCommands() throws IOException {
            String command = input.readUtf8Line();
            if (command == null) {
Loading