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.Principal; 22 import java.security.PrivateKey; 23 import java.security.cert.X509Certificate; 24 import javax.net.ssl.KeyManager; 25 import javax.net.ssl.SSLEngine; 26 import javax.net.ssl.X509ExtendedKeyManager; 27 import libcore.java.io.NullPrintStream; 28 import libcore.java.security.StandardNames; 29 30 /** 31 * TestKeyManager is a simple proxy class that wraps an existing 32 * X509ExtendedKeyManager to provide debug logging and recording of 33 * values. 34 */ 35 public final class TestKeyManager extends X509ExtendedKeyManager { 36 private static final boolean LOG = false; 37 private static final PrintStream out = LOG ? System.out : new NullPrintStream(); 38 39 private final X509ExtendedKeyManager keyManager; 40 41 public static KeyManager[] wrap(KeyManager[] keyManagers) { 42 KeyManager[] result = keyManagers.clone(); 43 for (int i = 0; i < result.length; i++) { 44 result[i] = wrap(result[i]); 45 } 46 return result; 47 } 48 49 public static KeyManager wrap(KeyManager keyManager) { 50 if (!(keyManager instanceof X509ExtendedKeyManager)) { 51 return keyManager; 52 } 53 return new TestKeyManager((X509ExtendedKeyManager) keyManager); 54 } 55 56 public TestKeyManager(X509ExtendedKeyManager keyManager) { 57 out.println("TestKeyManager.<init> keyManager=" + keyManager); 58 this.keyManager = keyManager; 59 } 60 61 @Override 62 public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) { 63 out.print("TestKeyManager.chooseClientAlias"); 64 out.print(" | keyTypes: "); 65 for (String keyType : keyTypes) { 66 out.print(keyType); 67 out.print(' '); 68 } 69 dumpIssuers(issuers); 70 dumpSocket(socket); 71 assertKeyTypes(keyTypes); 72 return dumpAlias(keyManager.chooseClientAlias(keyTypes, issuers, socket)); 73 } 74 75 private void assertKeyTypes(String[] keyTypes) { 76 for (String keyType : keyTypes) { 77 assertKeyType(keyType); 78 } 79 } 80 81 private void assertKeyType(String keyType) { 82 if (!StandardNames.KEY_TYPES.contains(keyType)) { 83 throw new AssertionError("Unexpected key type " + keyType); 84 } 85 } 86 87 @Override 88 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { 89 out.print("TestKeyManager.chooseServerAlias"); 90 out.print(" | keyType: "); 91 out.print(keyType); 92 out.print(' '); 93 dumpIssuers(issuers); 94 dumpSocket(socket); 95 assertKeyType(keyType); 96 return dumpAlias(keyManager.chooseServerAlias(keyType, issuers, socket)); 97 } 98 99 private void dumpSocket(Socket socket) { 100 out.print(" | socket: "); 101 out.print(String.valueOf(socket)); 102 } 103 104 private void dumpIssuers(Principal[] issuers) { 105 out.print(" | issuers: "); 106 if (issuers == null) { 107 out.print("null"); 108 return; 109 } 110 for (Principal issuer : issuers) { 111 out.print(issuer); 112 out.print(' '); 113 } 114 } 115 116 private String dumpAlias(String alias) { 117 out.print(" => "); 118 out.println(alias); 119 return alias; 120 } 121 122 @Override 123 public X509Certificate[] getCertificateChain(String alias) { 124 out.print("TestKeyManager.getCertificateChain"); 125 out.print(" | alias: "); 126 out.print(alias); 127 return dumpCerts(keyManager.getCertificateChain(alias)); 128 } 129 130 private X509Certificate[] dumpCerts(X509Certificate[] certs) { 131 out.print(" => "); 132 for (X509Certificate cert : certs) { 133 out.print(cert.getSubjectDN()); 134 out.print(' '); 135 } 136 out.println(); 137 return certs; 138 } 139 140 @Override 141 public String[] getClientAliases(String keyType, Principal[] issuers) { 142 out.print("TestKeyManager.getClientAliases"); 143 out.print(" | keyType: "); 144 out.print(keyType); 145 dumpIssuers(issuers); 146 assertKeyType(keyType); 147 return dumpAliases(keyManager.getClientAliases(keyType, issuers)); 148 } 149 150 @Override 151 public String[] getServerAliases(String keyType, Principal[] issuers) { 152 out.print("TestKeyManager.getServerAliases"); 153 out.print(" | keyType: "); 154 out.print(keyType); 155 dumpIssuers(issuers); 156 assertKeyType(keyType); 157 return dumpAliases(keyManager.getServerAliases(keyType, issuers)); 158 } 159 160 private String[] dumpAliases(String[] aliases) { 161 out.print(" => "); 162 for (String alias : aliases) { 163 out.print(alias); 164 out.print(' '); 165 } 166 out.println(); 167 return aliases; 168 } 169 170 @Override 171 public PrivateKey getPrivateKey(String alias) { 172 out.print("TestKeyManager.getPrivateKey"); 173 out.print(" | alias: "); 174 out.print(alias); 175 PrivateKey pk = keyManager.getPrivateKey(alias); 176 out.print(" => "); 177 out.println(String.valueOf(pk)); 178 return pk; 179 } 180 181 @Override 182 public String chooseEngineClientAlias(String[] keyTypes, Principal[] issuers, SSLEngine e) { 183 out.print("TestKeyManager.chooseEngineClientAlias"); 184 out.print(" | keyTypes: "); 185 for (String keyType : keyTypes) { 186 out.print(keyType); 187 out.print(' '); 188 } 189 dumpIssuers(issuers); 190 dumpEngine(e); 191 assertKeyTypes(keyTypes); 192 return dumpAlias(keyManager.chooseEngineClientAlias(keyTypes, issuers, e)); 193 } 194 195 @Override 196 public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine e) { 197 out.print("TestKeyManager.chooseEngineServerAlias"); 198 out.print(" | keyType: "); 199 out.print(keyType); 200 out.print(' '); 201 dumpIssuers(issuers); 202 dumpEngine(e); 203 assertKeyType(keyType); 204 return dumpAlias(keyManager.chooseEngineServerAlias(keyType, issuers, e)); 205 } 206 207 private void dumpEngine(SSLEngine engine) { 208 out.print(" | engine: "); 209 out.print(String.valueOf(engine)); 210 } 211 } 212