1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.javax.net.ssl;
18
19import java.io.PrintStream;
20import java.net.Socket;
21import javax.net.ssl.SSLEngine;
22import javax.net.ssl.TrustManager;
23import javax.net.ssl.X509ExtendedTrustManager;
24import javax.net.ssl.X509TrustManager;
25import java.security.cert.CertificateException;
26import java.security.cert.X509Certificate;
27import libcore.java.io.NullPrintStream;
28import libcore.java.security.StandardNames;
29
30/**
31 * TestTrustManager is a simple proxy class that wraps an existing
32 * X509ExtendedTrustManager to provide debug logging and recording of
33 * values.
34 */
35public final class TestTrustManager extends X509ExtendedTrustManager {
36
37    private static final boolean LOG = false;
38    private static final PrintStream out = LOG ? System.out : new NullPrintStream();
39
40    private final X509TrustManager trustManager;
41    private final X509ExtendedTrustManager extendedTrustManager;
42
43    public static TrustManager[] wrap(TrustManager[] trustManagers) {
44        TrustManager[] result = trustManagers.clone();
45        for (int i = 0; i < result.length; i++) {
46            result[i] = wrap(result[i]);
47        }
48        return result;
49    }
50
51    public static TrustManager wrap(TrustManager trustManager) {
52        if (trustManager instanceof X509ExtendedTrustManager) {
53            return new TestTrustManager((X509ExtendedTrustManager) trustManager);
54        } else if (trustManager instanceof X509TrustManager) {
55            return new TestTrustManager((X509TrustManager) trustManager);
56        }
57        return trustManager;
58    }
59
60    public TestTrustManager(X509ExtendedTrustManager trustManager) {
61        out.println("TestTrustManager.<init> extendedTrustManager=" + trustManager);
62        this.extendedTrustManager = trustManager;
63        this.trustManager = trustManager;
64    }
65
66    public TestTrustManager(X509TrustManager trustManager) {
67        out.println("TestTrustManager.<init> trustManager=" + trustManager);
68        this.extendedTrustManager = null;
69        this.trustManager = trustManager;
70    }
71
72    public void checkClientTrusted(X509Certificate[] chain, String authType)
73            throws CertificateException {
74        out.print("TestTrustManager.checkClientTrusted "
75                  + "chain=" + chain.length + " "
76                  + "authType=" + authType + " ");
77        try {
78            assertClientAuthType(authType);
79            trustManager.checkClientTrusted(chain, authType);
80            out.println("OK");
81        } catch (CertificateException e) {
82            e.printStackTrace(out);
83            throw e;
84        }
85    }
86
87    @Override
88    public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
89            throws CertificateException {
90        if (extendedTrustManager == null) {
91            out.print("(fallback to X509TrustManager) ");
92            checkClientTrusted(chain, authType);
93            return;
94        }
95        out.print("TestTrustManager.checkClientTrusted "
96                + "chain=" + chain.length + " "
97                + "authType=" + authType + " "
98                + "socket=" + socket + " ");
99        try {
100            assertClientAuthType(authType);
101            extendedTrustManager.checkClientTrusted(chain, authType, socket);
102            out.println("OK");
103        } catch (CertificateException e) {
104            e.printStackTrace(out);
105            throw e;
106        }
107    }
108
109    @Override
110    public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
111            throws CertificateException {
112        if (extendedTrustManager == null) {
113            out.print("(fallback to X509TrustManager) ");
114            checkClientTrusted(chain, authType);
115            return;
116        }
117        out.print("TestTrustManager.checkClientTrusted "
118                + "chain=" + chain.length + " "
119                + "authType=" + authType + " "
120                + "engine=" + engine + " ");
121        try {
122            assertClientAuthType(authType);
123            extendedTrustManager.checkClientTrusted(chain, authType, engine);
124            out.println("OK");
125        } catch (CertificateException e) {
126            e.printStackTrace(out);
127            throw e;
128        }
129    }
130
131    private void assertClientAuthType(String authType) {
132        if (!StandardNames.CLIENT_AUTH_TYPES.contains(authType)) {
133            throw new AssertionError("Unexpected client auth type " + authType);
134        }
135    }
136
137    public void checkServerTrusted(X509Certificate[] chain, String authType)
138            throws CertificateException {
139        out.print("TestTrustManager.checkServerTrusted "
140                  + "chain=" + chain.length + " "
141                  + "authType=" + authType + " ");
142        try {
143            assertServerAuthType(authType);
144            trustManager.checkServerTrusted(chain, authType);
145            out.println("OK");
146        } catch (CertificateException e) {
147            e.printStackTrace(out);
148            throw e;
149        }
150    }
151
152    @Override
153    public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
154            throws CertificateException {
155        if (extendedTrustManager == null) {
156            out.print("(fallback to X509TrustManager) ");
157            checkServerTrusted(chain, authType);
158            return;
159        }
160        out.print("TestTrustManager.checkServerTrusted "
161                + "chain=" + chain.length + " "
162                + "authType=" + authType + " "
163                + "socket=" + socket.toString() + " ");
164        try {
165            assertServerAuthType(authType);
166            extendedTrustManager.checkServerTrusted(chain, authType, socket);
167            out.println("OK");
168        } catch (CertificateException e) {
169            e.printStackTrace(out);
170            throw e;
171        }
172    }
173
174    @Override
175    public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
176            throws CertificateException {
177        if (extendedTrustManager == null) {
178            out.print("(fallback to X509TrustManager) ");
179            checkServerTrusted(chain, authType);
180            return;
181        }
182        out.print("TestTrustManager.checkServerTrusted "
183                + "chain=" + chain.length + " "
184                + "authType=" + authType + " "
185                + "engine=" + engine.toString() + " ");
186        try {
187            assertServerAuthType(authType);
188            extendedTrustManager.checkServerTrusted(chain, authType, engine);
189            out.println("OK");
190        } catch (CertificateException e) {
191            e.printStackTrace(out);
192            throw e;
193        }
194    }
195
196    private void assertServerAuthType(String authType) {
197        if (!StandardNames.SERVER_AUTH_TYPES.contains(authType)) {
198            throw new AssertionError("Unexpected server auth type " + authType);
199        }
200    }
201
202    /**
203     * Returns the list of certificate issuer authorities which are trusted for
204     * authentication of peers.
205     *
206     * @return the list of certificate issuer authorities which are trusted for
207     *         authentication of peers.
208     */
209    public X509Certificate[] getAcceptedIssuers() {
210        X509Certificate[] result = trustManager.getAcceptedIssuers();
211        out.print("TestTrustManager.getAcceptedIssuers result=" + result.length);
212        return result;
213    }
214}
215
216