1ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra/*
2ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * Copyright (C) 2012 The Android Open Source Project
3ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra *
4ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * Licensed under the Apache License, Version 2.0 (the "License");
5ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * you may not use this file except in compliance with the License.
6ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * You may obtain a copy of the License at
7ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra *
8ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra *      http://www.apache.org/licenses/LICENSE-2.0
9ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra *
10ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * Unless required by applicable law or agreed to in writing, software
11ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * distributed under the License is distributed on an "AS IS" BASIS,
12ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * See the License for the specific language governing permissions and
14ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * limitations under the License.
15ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra */
16ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
17ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condrapackage android.net.http;
18ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
1912e752225aa96888358294be0d725d499a1c9f03Kenny Rootimport com.android.org.conscrypt.TrustManagerImpl;
208071124375e336b98de45b44b9884c92cdfd9bd8Andy Stadler
21ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condraimport java.security.cert.CertificateException;
22ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condraimport java.security.cert.X509Certificate;
23ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condraimport java.util.List;
24ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
25ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condraimport javax.net.ssl.X509TrustManager;
26ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
27ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra/**
28ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra * X509TrustManager wrapper exposing Android-added features.
29da776c872e8880b48dfac4a9e9a2d90e398e4608Kenny Root * <p>
30da776c872e8880b48dfac4a9e9a2d90e398e4608Kenny Root * The checkServerTrusted method allows callers to perform additional
31da776c872e8880b48dfac4a9e9a2d90e398e4608Kenny Root * verification of certificate chains after they have been successfully verified
32da776c872e8880b48dfac4a9e9a2d90e398e4608Kenny Root * by the platform.
33da776c872e8880b48dfac4a9e9a2d90e398e4608Kenny Root * </p>
34ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra */
35ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condrapublic class X509TrustManagerExtensions {
36ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
370ea4e7b581f97b13d4f63f54609736a1ad5a858aNarayan Kamath    final TrustManagerImpl mDelegate;
38ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
39ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra    /**
40ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * Constructs a new X509TrustManagerExtensions wrapper.
41ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     *
42ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * @param tm A {@link X509TrustManager} as returned by TrustManagerFactory.getInstance();
43ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * @throws IllegalArgumentException If tm is an unsupported TrustManager type.
44ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     */
45ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra    public X509TrustManagerExtensions(X509TrustManager tm) throws IllegalArgumentException {
46cb4c5819758a7e2951bd4818383f7c5e10a5f016Geremy Condra        if (tm instanceof TrustManagerImpl) {
47ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra            mDelegate = (TrustManagerImpl) tm;
48ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra        } else {
490ea4e7b581f97b13d4f63f54609736a1ad5a858aNarayan Kamath            mDelegate = null;
50ff9ca781d0db5f81c3e703641fc7b9a34936a328Brian Carlstrom            throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() +
51ff9ca781d0db5f81c3e703641fc7b9a34936a328Brian Carlstrom                    " which is not a supported type of X509TrustManager");
52ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra        }
53ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra    }
54ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra
55ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra    /**
56ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * Verifies the given certificate chain.
57ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     *
58ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * <p>See {@link X509TrustManager#checkServerTrusted(X509Certificate[], String)} for a
59ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * description of the chain and authType parameters. The final parameter, host, should be the
60ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * hostname of the server.</p>
61ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     *
62ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * @throws CertificateException if the chain does not verify correctly.
63ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     * @return the properly ordered chain used for verification as a list of X509Certificates.
64ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra     */
65ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra    public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
66ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra                                                    String host) throws CertificateException {
67e2dd396cef8c3b1c22b799ac931e207fdc729154Brian Carlstrom        return mDelegate.checkServerTrusted(chain, authType, host);
68ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra    }
69d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh
70d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh    /**
71d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     * Checks whether a CA certificate is added by an user.
72d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     *
73d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     * <p>Since {@link X509TrustManager#checkServerTrusted} allows its parameter {@code chain} to
74d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     * chain up to user-added CA certificates, this method can be used to perform additional
75d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     * policies for user-added CA certificates.
76d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     *
77d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     * @return {@code true} to indicate that the certificate was added by the user, {@code false}
78d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     * otherwise.
79d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh     */
80d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh    public boolean isUserAddedCertificate(X509Certificate cert) {
81d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh        return mDelegate.isUserAddedCertificate(cert);
82d96371521299627c8be59e0d9d5b42a61d0720beWilliam Luh    }
83ed41a4e2d81fceafbddb1e9a4ca327535bb739efGeremy Condra}
84