private List<X509Certificate> checkTrusted(X509Certificate[] certs, byte[] ocspData,
            byte[] tlsSctData, String authType, String host, boolean clientAuth)
            throws CertificateException {
        if (certs == null || certs.length == 0 || authType == null || authType.isEmpty()) {
            throw new IllegalArgumentException("null or zero-length parameter");
        }
        if (err != null) {
            throw new CertificateException(err);
        }
        Set<X509Certificate> used = new HashSet<>();
        List<X509Certificate> untrustedChain = new ArrayList<>();
        List<TrustAnchor> trustedChain = new ArrayList<>();
        // Initialize the chain to contain the leaf certificate. This potentially could be a trust
        // anchor. If the leaf is a trust anchor we still continue with path building to build the
        // complete trusted chain for additional validation such as certificate pinning.
        X509Certificate leaf = certs[0];
        TrustAnchor leafAsAnchor = findTrustAnchorBySubjectAndPublicKey(leaf);
        if (leafAsAnchor != null) {
            trustedChain.add(leafAsAnchor);
            used.add(leafAsAnchor.getTrustedCert());
        } else {
            untrustedChain.add(leaf);
        }
        used.add(leaf);
        return checkTrustedRecursive(certs, ocspData, tlsSctData, host, clientAuth,
                untrustedChain, trustedChain, used);
    }
Validates whether a server is trusted. If session is given and non-null
it also checks if chain is pinned appropriately for that peer host. If
null, it does not check for pinned certs. The return value is a list of
the certificates used for making the trust decision.
common/src/main/java/org/conscrypt/TrustManagerImpl.java