/*
 * Copyright 2016 OpenMarket Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.matrix.androidsdk.ssl;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.net.ssl.X509TrustManager;

/**
 * Implements a TrustManager that checks Certificates against an explicit list of known
 * fingerprints.
 */
public class PinnedTrustManager implements X509TrustManager {
    private final List<Fingerprint> mFingerprints;
    private final X509TrustManager mDefaultTrustManager;

    /**
     * @param fingerprints        An array of SHA256 cert fingerprints
     * @param defaultTrustManager Optional trust manager to fall back on if cert does not match
     *                            any of the fingerprints. Can be null.
     */
    public PinnedTrustManager(List<Fingerprint> fingerprints, X509TrustManager defaultTrustManager) {
        mFingerprints = fingerprints;
        mDefaultTrustManager = defaultTrustManager;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String s) throws CertificateException {
        try {
            if (mDefaultTrustManager != null) {
                mDefaultTrustManager.checkClientTrusted(
                        chain, s
                );
                return;
            }
        } catch (CertificateException e) {
            // If there is an exception we fall back to checking fingerprints
            if (mFingerprints == null || mFingerprints.size() == 0) {
                throw new UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.getCause());
            }
        }
        checkTrusted("client", chain);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String s) throws CertificateException {
        try {
            if (mDefaultTrustManager != null) {
                mDefaultTrustManager.checkServerTrusted(
                        chain, s
                );
                return;
            }
        } catch (CertificateException e) {
            // If there is an exception we fall back to checking fingerprints
            if (mFingerprints == null || mFingerprints.size() == 0) {
                throw new UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.getCause());
            }
        }
        checkTrusted("server", chain);
    }

    private void checkTrusted(String type, X509Certificate[] chain) throws CertificateException {
        X509Certificate cert = chain[0];

        boolean found = false;
        if (mFingerprints != null) {
            for (Fingerprint allowedFingerprint : mFingerprints) {
                if (allowedFingerprint != null && allowedFingerprint.matchesCert(cert)) {
                    found = true;
                    break;
                }
            }
        }

        if (!found) {
            throw new UnrecognizedCertificateException(cert, Fingerprint.newSha256Fingerprint(cert), null);
        }
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

@@ -29,19 +29,52 @@
 ket Ltd%0A
+ * Copyright 2018 New Vector Ltd%0A
  *%0A
-
  * Licen
@@ -776,16 +776,50 @@
 .List;%0A%0A
+import javax.annotation.Nullable;%0A
 import j
@@ -1072,24 +1072,38 @@
 ngerprints;%0A
+    @Nullable%0A
     private 
@@ -1464,16 +1464,26 @@
 rprints,
+ @Nullable
  X509Tru
@@ -2819,35 +2819,33 @@
 ingerprints.
-size() == 0
+isEmpty()
 ) %7B%0A        

Add @Nullable annotation