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 17 package org.conscrypt.javax.net.ssl; 18 19 import java.io.PrintStream; 20 import java.net.Socket; 21 import java.security.cert.CertificateException; 22 import java.security.cert.X509Certificate; 23 import javax.net.ssl.SSLEngine; 24 import javax.net.ssl.TrustManager; 25 import javax.net.ssl.X509ExtendedTrustManager; 26 import javax.net.ssl.X509TrustManager; 27 import libcore.java.io.NullPrintStream; 28 import 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 */ 35 public abstract class TestTrustManager { 36 private static final boolean LOG = false; 37 private static final PrintStream out = LOG ? System.out : new NullPrintStream(); 38 private static final Class<?> EXTENDED_TRUST_MANAGER_CLASS = getExtendedTrustManagerClass(); 39 40 public static TrustManager[] wrap(TrustManager[] trustManagers) { 41 TrustManager[] result = trustManagers.clone(); 42 for (int i = 0; i < result.length; i++) { 43 result[i] = wrap(result[i]); 44 } 45 return result; 46 } 47 48 public static TrustManager wrap(TrustManager trustManager) { 49 if (EXTENDED_TRUST_MANAGER_CLASS != null && EXTENDED_TRUST_MANAGER_CLASS.isInstance(trustManager)) { 50 return new ExtendedWrapper((X509ExtendedTrustManager) trustManager); 51 } else if (trustManager instanceof X509TrustManager) { 52 return new Wrapper((X509TrustManager) trustManager); 53 } 54 return trustManager; 55 } 56 57 private static Class<?> getExtendedTrustManagerClass() { 58 try { 59 return Class.forName("javax.net.ssl.X509ExtendedTrustManager"); 60 } catch (ClassNotFoundException e) { 61 return null; 62 } 63 } 64 65 private static void assertClientAuthType(String authType) { 66 if (!StandardNames.CLIENT_AUTH_TYPES.contains(authType)) { 67 throw new AssertionError("Unexpected client auth type " + authType); 68 } 69 } 70 71 private static void assertServerAuthType(String authType) { 72 if (!StandardNames.SERVER_AUTH_TYPES.contains(authType)) { 73 throw new AssertionError("Unexpected server auth type " + authType); 74 } 75 } 76 77 private static final class Wrapper implements X509TrustManager { 78 private final X509TrustManager trustManager; 79 80 private Wrapper(X509TrustManager trustManager) { 81 out.println("TestTrustManager.<init> trustManager=" + trustManager); 82 this.trustManager = trustManager; 83 } 84 85 @Override 86 public void checkClientTrusted(X509Certificate[] chain, String authType) 87 throws CertificateException { 88 out.print("TestTrustManager.checkClientTrusted " 89 + "chain=" + chain.length + " " 90 + "authType=" + authType + " "); 91 try { 92 assertClientAuthType(authType); 93 trustManager.checkClientTrusted(chain, authType); 94 out.println("OK"); 95 } catch (CertificateException e) { 96 e.printStackTrace(out); 97 throw e; 98 } 99 } 100 101 102 103 @Override 104 public void checkServerTrusted(X509Certificate[] chain, String authType) 105 throws CertificateException { 106 out.print("TestTrustManager.checkServerTrusted " 107 + "chain=" + chain.length + " " 108 + "authType=" + authType + " "); 109 try { 110 assertServerAuthType(authType); 111 trustManager.checkServerTrusted(chain, authType); 112 out.println("OK"); 113 } catch (CertificateException e) { 114 e.printStackTrace(out); 115 throw e; 116 } 117 } 118 119 /** 120 * Returns the list of certificate issuer authorities which are trusted for 121 * authentication of peers. 122 * 123 * @return the list of certificate issuer authorities which are trusted for 124 * authentication of peers. 125 */ 126 @Override 127 public X509Certificate[] getAcceptedIssuers() { 128 X509Certificate[] result = trustManager.getAcceptedIssuers(); 129 out.print("TestTrustManager.getAcceptedIssuers result=" + result.length); 130 return result; 131 } 132 } 133 134 private static final class ExtendedWrapper extends X509ExtendedTrustManager { 135 private final X509ExtendedTrustManager extendedTrustManager; 136 private final X509TrustManager trustManager; 137 138 ExtendedWrapper(X509ExtendedTrustManager trustManager) { 139 out.println("TestTrustManager.<init> extendedTrustManager=" + trustManager); 140 this.extendedTrustManager = trustManager; 141 this.trustManager = trustManager; 142 } 143 144 @Override 145 public void checkClientTrusted(X509Certificate[] chain, String authType) 146 throws CertificateException { 147 out.print("TestTrustManager.checkClientTrusted " 148 + "chain=" + chain.length + " " 149 + "authType=" + authType + " "); 150 try { 151 assertClientAuthType(authType); 152 trustManager.checkClientTrusted(chain, authType); 153 out.println("OK"); 154 } catch (CertificateException e) { 155 e.printStackTrace(out); 156 throw e; 157 } 158 } 159 160 161 162 @Override 163 public void checkServerTrusted(X509Certificate[] chain, String authType) 164 throws CertificateException { 165 out.print("TestTrustManager.checkServerTrusted " 166 + "chain=" + chain.length + " " 167 + "authType=" + authType + " "); 168 try { 169 assertServerAuthType(authType); 170 trustManager.checkServerTrusted(chain, authType); 171 out.println("OK"); 172 } catch (CertificateException e) { 173 e.printStackTrace(out); 174 throw e; 175 } 176 } 177 178 @Override 179 public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) 180 throws CertificateException { 181 if (extendedTrustManager == null) { 182 out.print("(fallback to X509TrustManager) "); 183 checkClientTrusted(chain, authType); 184 return; 185 } 186 out.print("TestTrustManager.checkClientTrusted " 187 + "chain=" + chain.length + " " 188 + "authType=" + authType + " " 189 + "socket=" + socket + " "); 190 try { 191 assertClientAuthType(authType); 192 extendedTrustManager.checkClientTrusted(chain, authType, socket); 193 out.println("OK"); 194 } catch (CertificateException e) { 195 e.printStackTrace(out); 196 throw e; 197 } 198 } 199 200 @Override 201 public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) 202 throws CertificateException { 203 if (extendedTrustManager == null) { 204 out.print("(fallback to X509TrustManager) "); 205 checkClientTrusted(chain, authType); 206 return; 207 } 208 out.print("TestTrustManager.checkClientTrusted " 209 + "chain=" + chain.length + " " 210 + "authType=" + authType + " " 211 + "engine=" + engine + " "); 212 try { 213 assertClientAuthType(authType); 214 extendedTrustManager.checkClientTrusted(chain, authType, engine); 215 out.println("OK"); 216 } catch (CertificateException e) { 217 e.printStackTrace(out); 218 throw e; 219 } 220 } 221 222 @Override 223 public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) 224 throws CertificateException { 225 if (extendedTrustManager == null) { 226 out.print("(fallback to X509TrustManager) "); 227 checkServerTrusted(chain, authType); 228 return; 229 } 230 out.print("TestTrustManager.checkServerTrusted " 231 + "chain=" + chain.length + " " 232 + "authType=" + authType + " " 233 + "socket=" + socket.toString() + " "); 234 try { 235 assertServerAuthType(authType); 236 extendedTrustManager.checkServerTrusted(chain, authType, socket); 237 out.println("OK"); 238 } catch (CertificateException e) { 239 e.printStackTrace(out); 240 throw e; 241 } 242 } 243 244 @Override 245 public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) 246 throws CertificateException { 247 if (extendedTrustManager == null) { 248 out.print("(fallback to X509TrustManager) "); 249 checkServerTrusted(chain, authType); 250 return; 251 } 252 out.print("TestTrustManager.checkServerTrusted " 253 + "chain=" + chain.length + " " 254 + "authType=" + authType + " " 255 + "engine=" + engine.toString() + " "); 256 try { 257 assertServerAuthType(authType); 258 extendedTrustManager.checkServerTrusted(chain, authType, engine); 259 out.println("OK"); 260 } catch (CertificateException e) { 261 e.printStackTrace(out); 262 throw e; 263 } 264 } 265 266 /** 267 * Returns the list of certificate issuer authorities which are trusted for 268 * authentication of peers. 269 * 270 * @return the list of certificate issuer authorities which are trusted for 271 * authentication of peers. 272 */ 273 @Override 274 public X509Certificate[] getAcceptedIssuers() { 275 X509Certificate[] result = trustManager.getAcceptedIssuers(); 276 out.print("TestTrustManager.getAcceptedIssuers result=" + result.length); 277 return result; 278 } 279 } 280 } 281