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